[Commits] 37345bd: MDEV-7529 GIS: ST_Relate returns unexpected results for POINT relations.

holyfoot at askmonty.org holyfoot at askmonty.org
Sun Mar 15 20:23:52 EET 2015


revision-id: 37345bd9dde7fb948c439e73fbec5a88385162b2
parent(s): ca3041883725393baa6c645050ef926d782eb3a8
committer: Alexey Botchkov
branch nick: 10.1
timestamp: 2015-03-15 22:20:38 +0400
message:

MDEV-7529 GIS: ST_Relate returns unexpected results for POINT relations.
Problem was that we considered the point itself as the 'border' object. Instead
of that the 'border' of a POINT is an empty set, and the point is the 'interior'.
Another error fixed by the way - not all operations of the resulting function were properly
allocated.

---
 mysql-test/r/gis.result | 22 ++++++++++++++++++++--
 mysql-test/t/gis.test   |  9 +++++++++
 sql/gcalc_tools.cc      |  4 ++--
 sql/item_geofunc.cc     | 12 +++++++-----
 4 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index c3d9fa3..32799f1 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -404,7 +404,7 @@ Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t,
 Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r
 FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second;
 first	second	w	c	o	e	d	t	i	r
-120	120	1	1	0	1	0	1	1	0
+120	120	1	1	0	1	0	0	1	0
 120	121	0	0	1	0	0	0	1	0
 120	122	NULL	NULL	NULL	NULL	NULL	NULL	NULL	NULL
 120	123	NULL	NULL	NULL	NULL	NULL	NULL	NULL	NULL
@@ -1779,4 +1779,22 @@ ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,-10 -10, 0 -10, 0 0)'))
 #
 SELECT ST_GEOMETRYTYPE(ST_PointOnSurface(ST_PolyFromText('POLYGON((-70.916 42.1002,-70.9468 42.0946,-70.9754 42.0875,-70.9749 42.0879,-70.9759 42.0897,-70.916 42.1002))')));
 ST_GEOMETRYTYPE(ST_PointOnSurface(ST_PolyFromText('POLYGON((-70.916 42.1002,-70.9468 42.0946,-70.9754 42.0875,-70.9749 42.0879,-70.9759 42.0897,-70.916 42.1002))')))
-POINT
+NULL
+#
+# MDEV-7529 GIS: ST_Relate returns unexpected results for POINT relations
+#
+select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'),'T*F**FFF*') AS equals;
+equals
+1
+select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'),'T*****FF*') AS contains;
+contains
+1
+select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'),'T*F**F***') AS within;
+within
+1
+select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(1 1)'),'FF*FF****') as disjoint;
+disjoint
+1
+select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'),'FF*FF****') as disjoint;
+disjoint
+0
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index 9c84848..125bd31 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -1497,3 +1497,12 @@ select ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,-10 -10, 0 -10, 0 0)
 --echo #
 SELECT ST_GEOMETRYTYPE(ST_PointOnSurface(ST_PolyFromText('POLYGON((-70.916 42.1002,-70.9468 42.0946,-70.9754 42.0875,-70.9749 42.0879,-70.9759 42.0897,-70.916 42.1002))')));
 
+--echo #
+--echo # MDEV-7529 GIS: ST_Relate returns unexpected results for POINT relations
+--echo #
+select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'),'T*F**FFF*') AS equals;
+select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'),'T*****FF*') AS contains;
+select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'),'T*F**F***') AS within;
+select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(1 1)'),'FF*FF****') as disjoint;
+select ST_Relate(ST_PointFromText('POINT(0 0)'),ST_PointFromText('POINT(0 0)'),'FF*FF****') as disjoint;
+
diff --git a/sql/gcalc_tools.cc b/sql/gcalc_tools.cc
index 8644374..2d770fd 100644
--- a/sql/gcalc_tools.cc
+++ b/sql/gcalc_tools.cc
@@ -300,10 +300,10 @@ int Gcalc_function::check_function(Gcalc_scan_iterator &scan_it)
       gcalc_shape_info si= events->get_shape();
       if (events->event == scev_thread ||
           events->event == scev_end ||
-          events->event == scev_single_point ||
           (get_shape_kind(si) == Gcalc_function::shape_polygon))
         set_b_state(si);
-      else if (get_shape_kind(si) == Gcalc_function::shape_line)
+      else if (events->event == scev_single_point ||
+               get_shape_kind(si) == Gcalc_function::shape_line)
         set_i_state(si);
     }
 
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index 753bae8..9fc8e9d 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -1081,9 +1081,9 @@ static Gcalc_function::op_type op_matrix(int n)
   switch (n)
   {
     case 0:
-      return Gcalc_function::op_border;
-    case 1:
       return Gcalc_function::op_internals;
+    case 1:
+      return Gcalc_function::op_border;
     case 2:
       return (Gcalc_function::op_type)
         ((int) Gcalc_function::op_not | (int) Gcalc_function::op_union);
@@ -1103,6 +1103,8 @@ static int setup_relate_func(Geometry *g1, Geometry *g2,
   int last_shape_pos;
 
   last_shape_pos= func->get_next_expression_pos();
+  if (func->reserve_op_buffer(1))
+    return 1;
   func->add_operation(Gcalc_function::op_intersection, 0);
   for (int nc=0; nc<9; nc++)
   {
@@ -1120,11 +1122,11 @@ static int setup_relate_func(Geometry *g1, Geometry *g2,
         cur_op|= Gcalc_function::v_find_t;
         break;
       case 'F':
-        cur_op|= Gcalc_function::v_find_f;
+        cur_op|= (Gcalc_function::op_not | Gcalc_function::v_find_t);
         break;
     };
     ++n_operands;
-    if (func->reserve_op_buffer(1))
+    if (func->reserve_op_buffer(3))
       return 1;
     func->add_operation(cur_op, 2);
 
@@ -2346,7 +2348,7 @@ String *Item_func_pointonsurface::val_str(String *str)
     }
     x0= scan_it.get_sp_x(pprev);
     px= scan_it.get_sp_x(pit.point());
-    if (fabs(px - x0) > GIS_ZERO)
+    if (px - x0 > GIS_ZERO)
     {
       if (scan_it.get_h() > GIS_ZERO)
       {


More information about the commits mailing list