summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Botchkov <holyfoot@askmonty.org>2015-03-15 22:20:38 +0400
committerAlexey Botchkov <holyfoot@askmonty.org>2015-03-15 22:20:38 +0400
commit37345bd9dde7fb948c439e73fbec5a88385162b2 (patch)
tree3170bbf05310ce08238dd63e53ea3edec511e58b
parentca3041883725393baa6c645050ef926d782eb3a8 (diff)
downloadmariadb-git-37345bd9dde7fb948c439e73fbec5a88385162b2.tar.gz
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.
-rw-r--r--mysql-test/r/gis.result22
-rw-r--r--mysql-test/t/gis.test9
-rw-r--r--sql/gcalc_tools.cc4
-rw-r--r--sql/item_geofunc.cc12
4 files changed, 38 insertions, 9 deletions
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index c3d9fa39270..32799f15de2 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 9c84848b979..125bd310844 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 864437401b7..2d770fd45d6 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 753bae89ca4..9fc8e9d09e0 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)
{