diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2015-03-15 22:20:38 +0400 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2015-03-15 22:20:38 +0400 |
commit | 37345bd9dde7fb948c439e73fbec5a88385162b2 (patch) | |
tree | 3170bbf05310ce08238dd63e53ea3edec511e58b | |
parent | ca3041883725393baa6c645050ef926d782eb3a8 (diff) | |
download | mariadb-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.result | 22 | ||||
-rw-r--r-- | mysql-test/t/gis.test | 9 | ||||
-rw-r--r-- | sql/gcalc_tools.cc | 4 | ||||
-rw-r--r-- | 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 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) { |