Skip to content
  • Alexander Barkov's avatar
    de2c71cd
    Bug#13833019 ASSERTION `T1->RESULT_RANGE' FAILED IN GCALC_OPERATION_R · de2c71cd
    Alexander Barkov authored
    Bug#13832749 HANDLE_FATAL_SIGNAL IN GCALC_FUNCTION::COUNT_INTERNAL
    
    1. ST_Buffer() did not work well due to a few bugs in the
      buffer transporter implementation.
    
    a. The sequence of:
    
      func.get_next_operation_pos();
      ...
      func.add_operands_to_op(union_pos, trn.m_nshapes);
    
      did not work in case of collection geometries
      (MultiPoint, MultiLineString, MultiPolygon, GeometryCollection),
      which already create a union of m_nshapes items themself.
      In this case the caller should have generated a union1 operation
      instead of unionN operation, i.e. the above add_operands_to_op()
      call should have passed 1 instead of trn.m_nshapes,
      to get this function execution plan:
    
        union1(unionN(shape1,shape2,...,shapeN))
    
      instead of bad:
    
        unionN(unionN(shape1,shape2,..,shapeN))
    
      The fix moves the code generating the upper-most union command
      *inside* store_shape() for all geometry types.
    
    b. The next problem after moving union generating inside store_shapes()
       was that the Item_func_buffer::Transporter::m_nshapes member was
       erroneously shared by both collection itself and its items, e.g.:
    
      - lines of multilinestring and the multiline itself
      - items of a geometry collection and the collection itself
    
      The fix removes the m_nshapes member from Item_func_buffer::Transporter
      and passes the current shape transformation status as a parameter
      to all tranformation methods line stat_xxx/complete_xxx/add_point, etc.
    
      This simplifies simultanious access to the transformation statistics
      of the collection itself and of the current item.
      A new class Gcalc_shape_status was introduces to store transformation status.
      Before a collection processing code enters an item, a new transformation
      status variable is created on stack and passed to the item processing
      routine.
    
    c. ST_Buffer did not include the very last edge of a polygon with 4+ points
    due to the bug in the point comparison code in
    Item_func_buffer::Transporter::complete:
    
    - if (x2 != x00 && y2 != y00)
    + if (x2 != x00 || y2 != y00)
    
    
    2. Area() of a geometry collection consisting of polygons mistakenly
      returned NULL, because Gis_geometry_collection::area was not implemented.
      Area() of Points and LineStrings also returned NULL. Fixing to return 0.
    
    
    3. Negative buffer values worked wrong:
    
    - ST_Buffer(GeomFromText('POINT(0 0)',-1));
    
      Returned similar value to 
    
      ST_Buffer(GeomFromText('POINT(0 0)',1));
    
    - ST_Buffer(GeomFromText('LineString(0 0)'),-1)
    
      returned similar value to
    
      ST_Buffer(GeomFromText('LineString(0 0)'),1)
    
    Fixing negative buffers to return empty sets for Points and LineStrings,
    according to the OCG specifications.
    
    4. Zero buffer made server crash:
    
      ST_Buffer(<polygon>, 0)
    
      because of division-by-zero-alike problem.
      Changing zero buffer to return the original geometry itself,
      instead of going through the zero-unsafe buffer generating code.
    
    5. Adding GIS debug output functionality, to print debug information
    into server log and into client side warnings. The latter is very useful
    for mtr purposes. GIS debug output is available only in debug builds
    and does not exist in production builds.
    
    6. Adding ST_GIS_DEBUG() function to turn client-side GIS debug warnings on/off:
    
    SELECT ST_GIS_DEBUG(1); -- turn debug output on
    SELECT ST_GIS_DEBUG(0); -- turn debug output off
    
    Client side debug warnings are off by default.
    
    
    Per file comments:
    
    added:
      @ mysql-test/include/gis_debug.inc
        - Adding a shared file to test various GIS functions
    
      @ mysql-test/r/gis-debug.result
      @ mysql-test/t/gis-debug.test
        - Adding a debug test with client-side GIS debug warnings.
    
    modified:
      @ mysql-test/r/gis-precise.result
      @ mysql-test/t/gis-precise.test
        - Including gis_debug.inc,
          to make sure the results are correct in non-debugs.
    
      @ sql/gcalc_slicescan.h.diff
        - Introducing a new class Gcalc_shape_status and passing
          a parameter of Gcalc_shape_status type into transformation methods.
        - Adding prototypes for collection_add_item() and complete_collection()
          transformation methods. Previously these methods did not exist
          because Item_func_buffer::val_str() tried to process the upper-most
          union itself (incorrectly).
    
        - Adding skip_xxx() methods, to exclude certain geometries during
          transformation. For example, negative buffer does not need Points
          and LineStrings.
    
      @ sql/gcalc_tools.cc.diff
        - Adding debug routines
        - Adding Gcalc_shape_status parameter into the transformation methods
        - Adding the default implementation of start_collection(),
          collection_add_item() and complete_collection() routines.
    
      @ sql/gcalc_tools.h.diff
        - Adding prototype for the debug routine
        - Adding an Gcalc_shape_status parameter to transformation routines
    
      @ sql/item_create.cc.diff
        - Adding a code to create ST_GIS_DEBUG() SQL function in debug builds
    
      @ sql/item_geofunc.cc.diff
    
        - Adding Gcalc_shape_status parameter into the transformation methods
        - Adding a new code to catch zero distance
        - Adding a new code to catch empty buffer set after transformation
        - Removing the top-level union generating code
        - Adding Item_func_gis_debug::val_int() implementation
        - Adding calls for debug_print_function_buffer() near all store_shapes()
          calls.
    
      @ sql/item_geofunc.h.diff
        - Removing the m_nshapes member
        - Adding Gcalc_shape_status parameter to the transformation methods
        - Adding prototype for Item_func_gis_debug,
          the item behind the new ST_GIS_DEBUG() SQL function.
    
      @ sql/spatial.cc.diff
        - Implementing Geometry::collection_store_shapes() and
          Geometry::collection_area() methods, which are shared between
          collection geometry types:
          GeometryCollection, MultiPoint, MultiLineString,MultiPolygon
        - Adding Gcalc_shape_status parameter to the transformation methods
        - Implementing the missing Gis_geometry_collection::area().
    
      @ sql/spatial.h.diff
        - Adding prototypes for collection_store_shapes() and collection_area().
        - Adding prototype for the missing Gis_geometry_collection::area().
        - Adding the default implementation for area(), for the geometry
          types who have empty area.
        - Adding Gcalc_shape_status parameter to the transformation methods
      @ sql/sql_class.cc.diff
        - Adding gis_debug initialization into THD constructor
    
      @ sql/sql_class.h.diff
        - Introducing gis_debug member and related methods.
    de2c71cd
    Bug#13833019 ASSERTION `T1->RESULT_RANGE' FAILED IN GCALC_OPERATION_R
    Alexander Barkov authored
    Bug#13832749 HANDLE_FATAL_SIGNAL IN GCALC_FUNCTION::COUNT_INTERNAL
    
    1. ST_Buffer() did not work well due to a few bugs in the
      buffer transporter implementation.
    
    a. The sequence of:
    
      func.get_next_operation_pos();
      ...
      func.add_operands_to_op(union_pos, trn.m_nshapes);
    
      did not work in case of collection geometries
      (MultiPoint, MultiLineString, MultiPolygon, GeometryCollection),
      which already create a union of m_nshapes items themself.
      In this case the caller should have generated a union1 operation
      instead of unionN operation, i.e. the above add_operands_to_op()
      call should have passed 1 instead of trn.m_nshapes,
      to get this function execution plan:
    
        union1(unionN(shape1,shape2,...,shapeN))
    
      instead of bad:
    
        unionN(unionN(shape1,shape2,..,shapeN))
    
      The fix moves the code generating the upper-most union command
      *inside* store_shape() for all geometry types.
    
    b. The next problem after moving union generating inside store_shapes()
       was that the Item_func_buffer::Transporter::m_nshapes member was
       erroneously shared by both collection itself and its items, e.g.:
    
      - lines of multilinestring and the multiline itself
      - items of a geometry collection and the collection itself
    
      The fix removes the m_nshapes member from Item_func_buffer::Transporter
      and passes the current shape transformation status as a parameter
      to all tranformation methods line stat_xxx/complete_xxx/add_point, etc.
    
      This simplifies simultanious access to the transformation statistics
      of the collection itself and of the current item.
      A new class Gcalc_shape_status was introduces to store transformation status.
      Before a collection processing code enters an item, a new transformation
      status variable is created on stack and passed to the item processing
      routine.
    
    c. ST_Buffer did not include the very last edge of a polygon with 4+ points
    due to the bug in the point comparison code in
    Item_func_buffer::Transporter::complete:
    
    - if (x2 != x00 && y2 != y00)
    + if (x2 != x00 || y2 != y00)
    
    
    2. Area() of a geometry collection consisting of polygons mistakenly
      returned NULL, because Gis_geometry_collection::area was not implemented.
      Area() of Points and LineStrings also returned NULL. Fixing to return 0.
    
    
    3. Negative buffer values worked wrong:
    
    - ST_Buffer(GeomFromText('POINT(0 0)',-1));
    
      Returned similar value to 
    
      ST_Buffer(GeomFromText('POINT(0 0)',1));
    
    - ST_Buffer(GeomFromText('LineString(0 0)'),-1)
    
      returned similar value to
    
      ST_Buffer(GeomFromText('LineString(0 0)'),1)
    
    Fixing negative buffers to return empty sets for Points and LineStrings,
    according to the OCG specifications.
    
    4. Zero buffer made server crash:
    
      ST_Buffer(<polygon>, 0)
    
      because of division-by-zero-alike problem.
      Changing zero buffer to return the original geometry itself,
      instead of going through the zero-unsafe buffer generating code.
    
    5. Adding GIS debug output functionality, to print debug information
    into server log and into client side warnings. The latter is very useful
    for mtr purposes. GIS debug output is available only in debug builds
    and does not exist in production builds.
    
    6. Adding ST_GIS_DEBUG() function to turn client-side GIS debug warnings on/off:
    
    SELECT ST_GIS_DEBUG(1); -- turn debug output on
    SELECT ST_GIS_DEBUG(0); -- turn debug output off
    
    Client side debug warnings are off by default.
    
    
    Per file comments:
    
    added:
      @ mysql-test/include/gis_debug.inc
        - Adding a shared file to test various GIS functions
    
      @ mysql-test/r/gis-debug.result
      @ mysql-test/t/gis-debug.test
        - Adding a debug test with client-side GIS debug warnings.
    
    modified:
      @ mysql-test/r/gis-precise.result
      @ mysql-test/t/gis-precise.test
        - Including gis_debug.inc,
          to make sure the results are correct in non-debugs.
    
      @ sql/gcalc_slicescan.h.diff
        - Introducing a new class Gcalc_shape_status and passing
          a parameter of Gcalc_shape_status type into transformation methods.
        - Adding prototypes for collection_add_item() and complete_collection()
          transformation methods. Previously these methods did not exist
          because Item_func_buffer::val_str() tried to process the upper-most
          union itself (incorrectly).
    
        - Adding skip_xxx() methods, to exclude certain geometries during
          transformation. For example, negative buffer does not need Points
          and LineStrings.
    
      @ sql/gcalc_tools.cc.diff
        - Adding debug routines
        - Adding Gcalc_shape_status parameter into the transformation methods
        - Adding the default implementation of start_collection(),
          collection_add_item() and complete_collection() routines.
    
      @ sql/gcalc_tools.h.diff
        - Adding prototype for the debug routine
        - Adding an Gcalc_shape_status parameter to transformation routines
    
      @ sql/item_create.cc.diff
        - Adding a code to create ST_GIS_DEBUG() SQL function in debug builds
    
      @ sql/item_geofunc.cc.diff
    
        - Adding Gcalc_shape_status parameter into the transformation methods
        - Adding a new code to catch zero distance
        - Adding a new code to catch empty buffer set after transformation
        - Removing the top-level union generating code
        - Adding Item_func_gis_debug::val_int() implementation
        - Adding calls for debug_print_function_buffer() near all store_shapes()
          calls.
    
      @ sql/item_geofunc.h.diff
        - Removing the m_nshapes member
        - Adding Gcalc_shape_status parameter to the transformation methods
        - Adding prototype for Item_func_gis_debug,
          the item behind the new ST_GIS_DEBUG() SQL function.
    
      @ sql/spatial.cc.diff
        - Implementing Geometry::collection_store_shapes() and
          Geometry::collection_area() methods, which are shared between
          collection geometry types:
          GeometryCollection, MultiPoint, MultiLineString,MultiPolygon
        - Adding Gcalc_shape_status parameter to the transformation methods
        - Implementing the missing Gis_geometry_collection::area().
    
      @ sql/spatial.h.diff
        - Adding prototypes for collection_store_shapes() and collection_area().
        - Adding prototype for the missing Gis_geometry_collection::area().
        - Adding the default implementation for area(), for the geometry
          types who have empty area.
        - Adding Gcalc_shape_status parameter to the transformation methods
      @ sql/sql_class.cc.diff
        - Adding gis_debug initialization into THD constructor
    
      @ sql/sql_class.h.diff
        - Introducing gis_debug member and related methods.
Loading