[Commits] 702fba1: MDEV-7510 GIS: IsRing returns false for a primitive triangle.

holyfoot at askmonty.org holyfoot at askmonty.org
Fri Mar 13 14:12:55 EET 2015


revision-id: 702fba1511c90ea9c72b6c00122e0f31a05237b4
parent(s): 75d65b5f4e5428310e57155903602801d7d86ee2
committer: Alexey Botchkov
branch nick: 10.1
timestamp: 2015-03-13 16:10:31 +0400
message:

MDEV-7510 GIS: IsRing returns false for a primitive triangle.

The problem is in the IsSimple function. If the first and the last points
of a curve coincide it's and exception and the line is still 'simple'.

---
 mysql-test/r/gis.result | 11 ++++++++++-
 mysql-test/t/gis.test   |  6 ++++++
 sql/item_geofunc.cc     | 16 ++++++++++++----
 3 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index 4f65aa2e..f696466 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -1378,7 +1378,7 @@ SELECT IsRing(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary)))
 FROM named_places 
 WHERE name = 'Goose Island';
 IsRing(LineFromWKB(AsBinary(Boundary(boundary)),SRID(boundary)))
-0
+1
 # Conformance Item T21 
 SELECT GLength(centerline) 
 FROM road_segments 
@@ -1765,3 +1765,12 @@ SRID
 0
 0
 drop table t1;
+#
+# MDEV-7510 GIS: IsRing returns false for a primitive triangle.
+#
+select ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,0 0)'));
+ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,0 0)'))
+1
+select ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,-10 -10, 0 -10, 0 0)'));
+ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,-10 -10, 0 -10, 0 0)'))
+0
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index a4e95b7..888ee68 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -1486,3 +1486,9 @@ ALTER TABLE t1 ADD fid INT NOT NULL;
 select SRID from information_schema.geometry_columns where F_TABLE_NAME='t1';
 drop table t1;
 
+--echo #
+--echo # MDEV-7510 GIS: IsRing returns false for a primitive triangle.
+--echo #
+select ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,0 0)'));
+select ST_IsRing(ST_LineFromText('LINESTRING(0 0,0 10,10 10,-10 -10, 0 -10, 0 0)'));
+
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index 7e8edbc..7f63388 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -1867,7 +1867,6 @@ longlong Item_func_issimple::val_int()
   Gcalc_operation_transporter trn(&func, &collector);
   Geometry *g;
   int result= 1;
-  const Gcalc_scan_iterator::event_point *ev;
   MBR mbr;
   const char *c_end;
 
@@ -1892,6 +1891,8 @@ longlong Item_func_issimple::val_int()
 
   while (scan_it.more_points())
   {
+    const Gcalc_scan_iterator::event_point *ev, *next_ev;
+
     if (scan_it.step())
       goto mem_error;
 
@@ -1899,11 +1900,18 @@ longlong Item_func_issimple::val_int()
     if (ev->simple_event())
       continue;
 
-    if ((ev->event == scev_thread || ev->event == scev_single_point) &&
-        !ev->get_next())
+    next_ev= ev->get_next();
+    if ((ev->event & (scev_thread | scev_single_point)) && !next_ev)
+      continue;
+
+    if ((ev->event == scev_two_threads) && !next_ev->get_next())
       continue;
 
-    if (ev->event == scev_two_threads && !ev->get_next()->get_next())
+    /* If the first and last points of a curve coincide - that is     */
+    /* an exception to the rule and the line is considered as simple. */
+    if ((next_ev && !next_ev->get_next()) &&
+        (ev->event & (scev_thread | scev_end)) &&
+        (next_ev->event & (scev_thread | scev_end)))
       continue;
 
     result= 0;


More information about the commits mailing list