Skip to content

Commit b503666

Browse files
StefanoPetrillitorjehanshelljhaugliddahlerlend
authored andcommitted
MDEV-34137: Implement the GIS function ST_Validate
The GIS function ST_Validate takes ad input a geometry and verifies that - is compliant with the Well-Known Binary (WKB) format and Spatial Reference System Identifier (SRID) syntax. - is geometrically valid. If the input is valid return it, else it returns NULL. The use case of this function is to filter out invalid geometry data. Author: StefanoPetrilli <stefanop_1999@hotmail.it> Co-authored-by: Torje Digernes <torje.digernes@oracle.com> Co-authored-by: Hans H Melby <hans.h.melby@oracle.com> Co-authored-by: Jon Olav Hauglid <jon.hauglid@oracle.com> Co-authored-by: Erlend Dahl <erlend.dahl@oracle.com> Co-authored-by: Norvald H. Ryeng <norvald.ryeng@oracle.com> Co-authored-by: David.Zhao <david.zhao@oracle.com> Co-authored-by: Pavan <pavan.naik@oracle.com>
1 parent 869b4c2 commit b503666

File tree

7 files changed

+545
-22
lines changed

7 files changed

+545
-22
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Creating the spatial Geometry object
2+
USE test;
3+
# ST_VALIDATE must return null when its parameter is NULL
4+
SELECT ST_ASTEXT(ST_VALIDATE( NULL ));
5+
ST_ASTEXT(ST_VALIDATE( NULL ))
6+
NULL
7+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT(NULL,0)));
8+
ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT(NULL,0)))
9+
NULL
10+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT(NULL,4053)));
11+
ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT(NULL,4053)))
12+
NULL
13+
# ST_VALIDATE raises an error if the data is malformed
14+
SELECT ST_VALIDATE( x'00000000DEADBEEF');
15+
ERROR 22023: Invalid GIS data provided to function st_validate.
16+
# ST_VALIDATE return the input if it is valid
17+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POINT(15 25)')));
18+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POINT(15 25)')))
19+
POINT(15 25)
20+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOINT(5 0,25 0,15 10,15 25)')));
21+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOINT(5 0,25 0,15 10,15 25)')))
22+
MULTIPOINT(5 0,25 0,15 10,15 25)
23+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('LINESTRING(10 15,20 15)')));
24+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('LINESTRING(10 15,20 15)')))
25+
LINESTRING(10 15,20 15)
26+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTILINESTRING((25 0,0 15,15 30,0 5))')));
27+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTILINESTRING((25 0,0 15,15 30,0 5))')))
28+
MULTILINESTRING((25 0,0 15,15 30,0 5))
29+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POLYGON((5 0,7 10,0 15,10 15,15 25,20 15,30 15,22 10,25 0,15 5,5 0))')));
30+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POLYGON((5 0,7 10,0 15,10 15,15 25,20 15,30 15,22 10,25 0,15 5,5 0))')))
31+
POLYGON((5 0,7 10,0 15,10 15,15 25,20 15,30 15,22 10,25 0,15 5,5 0))
32+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOLYGON(((0 0,0 10,10 10,0 0)),((10 10,10 15,15 15,10 10)))')));
33+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOLYGON(((0 0,0 10,10 10,0 0)),((10 10,10 15,15 15,10 10)))')))
34+
MULTIPOLYGON(((0 0,0 10,10 10,0 0)),((10 10,10 15,15 15,10 10)))
35+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('GEOMETRYCOLLECTION(POINT(10 10),'
36+
'MULTIPOINT(0 0,10 10),'
37+
'LINESTRING(1 1,2 2,3 3),'
38+
'MULTILINESTRING((0 0,0 10,10 10,10 0),(10 10,10 15,15 15,10 10)))')));
39+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('GEOMETRYCOLLECTION(POINT(10 10),'
40+
'MULTIPOINT(0 0,10 10),'
41+
'LINESTRING(1 1,2 2,3 3),'
42+
43+
GEOMETRYCOLLECTION(POINT(10 10),MULTIPOINT(0 0,10 10),LINESTRING(1 1,2 2,3 3),MULTILINESTRING((0 0,0 10,10 10,10 0),(10 10,10 15,15 15,10 10)))
44+
# The only valid empty geometry is the empty geometrycollection
45+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POINT()')));
46+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POINT()')))
47+
NULL
48+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOINT()')));
49+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOINT()')))
50+
NULL
51+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('LINESTRING()')));
52+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('LINESTRING()')))
53+
NULL
54+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTILINESTRING(())')));
55+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTILINESTRING(())')))
56+
NULL
57+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POLYGON(())')));
58+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POLYGON(())')))
59+
NULL
60+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOLYGON((()),(()))')));
61+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOLYGON((()),(()))')))
62+
NULL
63+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('GEOMETRYCOLLECTION()')));
64+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('GEOMETRYCOLLECTION()')))
65+
GEOMETRYCOLLECTION EMPTY
66+
# Invalid geometries return null
67+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('LINESTRING(0 0,-0.00 0,0.0 0)')));
68+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('LINESTRING(0 0,-0.00 0,0.0 0)')))
69+
NULL
70+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTILINESTRING((0 0))')));
71+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTILINESTRING((0 0))')))
72+
NULL
73+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POLYGON((0 0))')));
74+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POLYGON((0 0))')))
75+
NULL
76+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOLYGON(((1 1, 1 1, 1 1, 1 1, 1 1)))')));
77+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOLYGON(((1 1, 1 1, 1 1, 1 1, 1 1)))')))
78+
NULL
79+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('GEOMETRYCOLLECTION(LINESTRING(0 0))')));
80+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('GEOMETRYCOLLECTION(LINESTRING(0 0))')))
81+
NULL
82+
# If a polygon or multipolygon has counterclockwise internal rings, the rings are returned counterclockwise
83+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 2 1, 2 2, 1 2, 1 1))')));
84+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 2 1, 2 2, 1 2, 1 1))')))
85+
POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,1 2,2 2,2 1,1 1))
86+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 2 1, 2 2, 1 2, 1 1)))')));
87+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 2 1, 2 2, 1 2, 1 1)))')))
88+
MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(1 1,1 2,2 2,2 1,1 1)))
89+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('GEOMETRYCOLLECTION(POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 2 1, 2 2, 1 2, 1 1)))')));
90+
ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('GEOMETRYCOLLECTION(POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 2 1, 2 2, 1 2, 1 1)))')))
91+
GEOMETRYCOLLECTION(POLYGON((0 0,10 0,10 10,0 10,0 0),(1 1,1 2,2 2,2 1,1 1)))
92+
# ST_VALIDATE raises an error if longitude is out of range
93+
SELECT ST_VALIDATE(ST_GEOMFROMTEXT('POINT(0 270)', 4326));
94+
ERROR HY000: Longitude 270.000000 is out of range in function st_validate. It must be within (-180.000000, 180.000000].
95+
# ST_VALIDATE raises an error if latitude is out of range
96+
SELECT ST_VALIDATE(ST_GEOMFROMTEXT('POINT(270 0)', 4326));
97+
ERROR HY000: Latitude 270.000000 is out of range in function st_validate. It must be within [-90.000000, 90.000000].
98+
# ST_VALIDATE returns the same geometry as it was given when it is valid
99+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0
100+
0),( 0.25 0.25, 0.25 0.75, 0.75 0.75, 0.75 0.25, 0.25 0.25))'))) AS
101+
valid_polygon;
102+
valid_polygon
103+
POLYGON((0 0,1 0,1 1,0 1,0 0),(0.25 0.25,0.25 0.75,0.75 0.75,0.75 0.25,0.25 0.25))
104+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0
105+
0),( 0.25 0.25, 0.25 0.75, 0.75 0.75, 0.75 0.25, 0.25 0.25))',4053))) AS
106+
valid_polygon;
107+
valid_polygon
108+
POLYGON((0 0,1 0,1 1,0 1,0 0),(0.25 0.25,0.25 0.75,0.75 0.75,0.75 0.25,0.25 0.25))
109+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0
110+
0),( 0.25 0.25, 0.25 0.75, 0.75 0.75, 0.75 0.25, 0.25 0.25))',2000))) AS
111+
valid_polygon;
112+
valid_polygon
113+
POLYGON((0 0,1 0,1 1,0 1,0 0),(0.25 0.25,0.25 0.75,0.75 0.75,0.75 0.25,0.25 0.25))
114+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0
115+
0),( 0.25 0.25, 0.25 0.75, 0.75 0.75, 0.75 0.25, 0.25 0.25))',4326))) AS
116+
valid_polygon;
117+
valid_polygon
118+
POLYGON((0 0,1 0,1 1,0 1,0 0),(0.25 0.25,0.25 0.75,0.75 0.75,0.75 0.25,0.25 0.25))
119+
# ST_VALIDATE returns NULL if the geometry is invalid
120+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0
121+
0),( 0.25 0.25, 1.75 0.25, 0.75 0.75, 0.25 0.75, 0.25 0.25))'))) AS
122+
should_be_null;
123+
should_be_null
124+
NULL
125+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0
126+
0),( 0.25 0.25, 1.75 0.25, 0.75 0.75, 0.25 0.75, 0.25 0.25))',4053))) AS
127+
should_be_null;
128+
should_be_null
129+
NULL
130+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0
131+
0),( 0.25 0.25, 1.75 0.25, 0.75 0.75, 0.25 0.75, 0.25 0.25))',2000))) AS
132+
should_be_null;
133+
should_be_null
134+
NULL
135+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0
136+
0),( 0.25 0.25, 1.75 0.25, 0.75 0.75, 0.25 0.75, 0.25 0.25))',4326))) AS
137+
should_be_null;
138+
should_be_null
139+
NULL
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Copyright (c) 2014, Oracle and/or its affiliates
2+
# Copyright (c) 2024, MariaDB Corporation.
3+
#
4+
# This program is free software; you can redistribute it and/or modify
5+
# it under the terms of the GNU General Public License as published by
6+
# the Free Software Foundation; version 2 of the License.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
# GNU General Public License for more details.
12+
#
13+
# You should have received a copy of the GNU General Public License
14+
# along with this program; if not, write to the Free Software
15+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA
16+
17+
18+
############################################################################################
19+
# Creating the spatial objects #
20+
############################################################################################
21+
22+
--echo # Creating the spatial Geometry object
23+
USE test;
24+
25+
--echo # ST_VALIDATE must return null when its parameter is NULL
26+
SELECT ST_ASTEXT(ST_VALIDATE( NULL ));
27+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT(NULL,0)));
28+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT(NULL,4053)));
29+
30+
--echo # ST_VALIDATE raises an error if the data is malformed
31+
--error ER_GIS_INVALID_DATA
32+
SELECT ST_VALIDATE( x'00000000DEADBEEF');
33+
34+
--echo # ST_VALIDATE return the input if it is valid
35+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POINT(15 25)')));
36+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOINT(5 0,25 0,15 10,15 25)')));
37+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('LINESTRING(10 15,20 15)')));
38+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTILINESTRING((25 0,0 15,15 30,0 5))')));
39+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POLYGON((5 0,7 10,0 15,10 15,15 25,20 15,30 15,22 10,25 0,15 5,5 0))')));
40+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOLYGON(((0 0,0 10,10 10,0 0)),((10 10,10 15,15 15,10 10)))')));
41+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('GEOMETRYCOLLECTION(POINT(10 10),'
42+
'MULTIPOINT(0 0,10 10),'
43+
'LINESTRING(1 1,2 2,3 3),'
44+
'MULTILINESTRING((0 0,0 10,10 10,10 0),(10 10,10 15,15 15,10 10)))')));
45+
46+
--echo # The only valid empty geometry is the empty geometrycollection
47+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POINT()')));
48+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOINT()')));
49+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('LINESTRING()')));
50+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTILINESTRING(())')));
51+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POLYGON(())')));
52+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOLYGON((()),(()))')));
53+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('GEOMETRYCOLLECTION()')));
54+
55+
--echo # Invalid geometries return null
56+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('LINESTRING(0 0,-0.00 0,0.0 0)')));
57+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTILINESTRING((0 0))')));
58+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POLYGON((0 0))')));
59+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOLYGON(((1 1, 1 1, 1 1, 1 1, 1 1)))')));
60+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('GEOMETRYCOLLECTION(LINESTRING(0 0))')));
61+
62+
--echo # If a polygon or multipolygon has counterclockwise internal rings, the rings are returned counterclockwise
63+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 2 1, 2 2, 1 2, 1 1))')));
64+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 2 1, 2 2, 1 2, 1 1)))')));
65+
SELECT ST_ASTEXT(ST_VALIDATE(ST_GEOMFROMTEXT('GEOMETRYCOLLECTION(POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 2 1, 2 2, 1 2, 1 1)))')));
66+
67+
--echo # ST_VALIDATE raises an error if longitude is out of range
68+
--error ER_LONGITUDE_OUT_OF_RANGE
69+
SELECT ST_VALIDATE(ST_GEOMFROMTEXT('POINT(0 270)', 4326));
70+
71+
--echo # ST_VALIDATE raises an error if latitude is out of range
72+
--error ER_LATITUDE_OUT_OF_RANGE
73+
SELECT ST_VALIDATE(ST_GEOMFROMTEXT('POINT(270 0)', 4326));
74+
75+
--echo # ST_VALIDATE returns the same geometry as it was given when it is valid
76+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0
77+
0),( 0.25 0.25, 0.25 0.75, 0.75 0.75, 0.75 0.25, 0.25 0.25))'))) AS
78+
valid_polygon;
79+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0
80+
0),( 0.25 0.25, 0.25 0.75, 0.75 0.75, 0.75 0.25, 0.25 0.25))',4053))) AS
81+
valid_polygon;
82+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0
83+
0),( 0.25 0.25, 0.25 0.75, 0.75 0.75, 0.75 0.25, 0.25 0.25))',2000))) AS
84+
valid_polygon;
85+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0
86+
0),( 0.25 0.25, 0.25 0.75, 0.75 0.75, 0.75 0.25, 0.25 0.25))',4326))) AS
87+
valid_polygon;
88+
89+
--echo # ST_VALIDATE returns NULL if the geometry is invalid
90+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0
91+
0),( 0.25 0.25, 1.75 0.25, 0.75 0.75, 0.25 0.75, 0.25 0.25))'))) AS
92+
should_be_null;
93+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0
94+
0),( 0.25 0.25, 1.75 0.25, 0.75 0.75, 0.25 0.75, 0.25 0.25))',4053))) AS
95+
should_be_null;
96+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0
97+
0),( 0.25 0.25, 1.75 0.25, 0.75 0.75, 0.25 0.75, 0.25 0.25))',2000))) AS
98+
should_be_null;
99+
SELECT ST_ASTEXT(ST_VALIDATE( ST_GEOMFROMTEXT('POLYGON((0 0, 1 0, 1 1, 0 1, 0
100+
0),( 0.25 0.25, 1.75 0.25, 0.75 0.75, 0.25 0.75, 0.25 0.25))',4326))) AS
101+
should_be_null;

sql/item_geofunc.cc

Lines changed: 76 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2082,6 +2082,7 @@ String *Item_func_buffer::val_str(String *str_value)
20822082
DBUG_RETURN(str_result);
20832083
}
20842084

2085+
20852086
longlong Item_func_isvalid::val_int()
20862087
{
20872088
String *wkb= args[0]->val_str(&tmp);
@@ -2106,6 +2107,73 @@ longlong Item_func_isvalid::val_int()
21062107
return (longlong) valid;
21072108
}
21082109

2110+
2111+
String *Item_func_validate::val_str(String *str_value)
2112+
{
2113+
DBUG_ENTER("Item_func_buffer::val_str");
2114+
DBUG_ASSERT(fixed());
2115+
String *wkb= args[0]->val_str(&tmp);
2116+
Geometry_buffer buffer;
2117+
Geometry *geometry;
2118+
int valid= 1;
2119+
str_value= NULL;
2120+
null_value= 1;
2121+
2122+
if(args[0]->null_value)
2123+
DBUG_RETURN(str_value);
2124+
2125+
if (!(geometry= Geometry::construct(&buffer, wkb->ptr(), wkb->length())))
2126+
{
2127+
my_error(ER_GIS_INVALID_DATA, MYF(0), func_name());
2128+
DBUG_RETURN(str_value);
2129+
}
2130+
2131+
if (geometry->get_class_info()->m_type_id == Geometry::wkb_point)
2132+
{
2133+
double x, y;
2134+
if(((Gis_point *) geometry)->get_xy(&x, &y))
2135+
DBUG_RETURN(str_value);
2136+
2137+
if (x > MAX_LONGITUDE || x <= MIN_LONGITUDE)
2138+
{
2139+
my_error(ER_LATITUDE_OUT_OF_RANGE, MYF(0), x, "st_validate");
2140+
DBUG_RETURN(str_value);
2141+
}
2142+
else if(y > MAX_LATITUDE || y < MIN_LATITUDE) {
2143+
my_error(ER_LONGITUDE_OUT_OF_RANGE, MYF(0), y,"st_validate");
2144+
DBUG_RETURN(str_value);
2145+
}
2146+
2147+
null_value= 0;
2148+
str_value= wkb;
2149+
DBUG_RETURN(str_value);
2150+
}
2151+
2152+
if (geometry->is_valid(&valid))
2153+
DBUG_RETURN(str_value);
2154+
2155+
if (!valid)
2156+
DBUG_RETURN(str_value);
2157+
2158+
if (geometry->get_class_info()->m_type_id == Geometry::wkb_polygon ||
2159+
geometry->get_class_info()->m_type_id == Geometry::wkb_multipolygon ||
2160+
geometry->get_class_info()->m_type_id ==
2161+
Geometry::wkb_geometrycollection)
2162+
{
2163+
String clockwise_wkb;
2164+
if(geometry->make_clockwise(&clockwise_wkb))
2165+
DBUG_RETURN(str_value);
2166+
2167+
wkb->length(4); // keep the SRID
2168+
wkb->append(clockwise_wkb.ptr(), clockwise_wkb.length());
2169+
}
2170+
2171+
null_value= 0;
2172+
str_value= wkb;
2173+
DBUG_RETURN(str_value);
2174+
}
2175+
2176+
21092177
bool Item_func_isempty::val_bool()
21102178
{
21112179
DBUG_ASSERT(fixed());
@@ -4299,37 +4367,21 @@ class Create_func_isvalid : public Create_func_arg1
42994367
virtual ~Create_func_isvalid() = default;
43004368
};
43014369

4302-
class Create_func_isvalid : public Create_func_arg1
4370+
class Create_func_validate : public Create_func_arg1
43034371
{
43044372
public:
43054373
Item *create_1_arg(THD *thd, Item *arg1) override
43064374
{
4307-
return new (thd->mem_root) Item_func_isvalid(thd, arg1);
4375+
return new (thd->mem_root) Item_func_validate(thd, arg1);
43084376
}
43094377

4310-
static Create_func_isvalid s_singleton;
4378+
static Create_func_validate s_singleton;
43114379

43124380
protected:
4313-
Create_func_isvalid() = default;
4314-
virtual ~Create_func_isvalid() = default;
4381+
Create_func_validate() = default;
4382+
virtual ~Create_func_validate() = default;
43154383
};
43164384

4317-
class Create_func_isvalid : public Create_func_arg1
4318-
{
4319-
public:
4320-
Item *create_1_arg(THD *thd, Item *arg1) override
4321-
{
4322-
return new (thd->mem_root) Item_func_isvalid(thd, arg1);
4323-
}
4324-
4325-
static Create_func_isvalid s_singleton;
4326-
4327-
protected:
4328-
Create_func_isvalid() = default;
4329-
virtual ~Create_func_isvalid() = default;
4330-
};
4331-
4332-
43334385
class Create_func_issimple : public Create_func_arg1
43344386
{
43354387
public:
@@ -4632,6 +4684,7 @@ Create_func_intersects Create_func_intersects::s_singleton;
46324684
Create_func_isclosed Create_func_isclosed::s_singleton;
46334685
Create_func_isempty Create_func_isempty::s_singleton;
46344686
Create_func_isvalid Create_func_isvalid::s_singleton;
4687+
Create_func_validate Create_func_validate::s_singleton;
46354688
Create_func_isring Create_func_isring::s_singleton;
46364689
Create_func_issimple Create_func_issimple::s_singleton;
46374690
Create_func_simplify Create_func_simplify::s_singleton;
@@ -4703,6 +4756,7 @@ static Native_func_registry func_array_geom[] =
47034756
{ { STRING_WITH_LEN("ISCLOSED") }, GEOM_BUILDER(Create_func_isclosed)},
47044757
{ { STRING_WITH_LEN("ISEMPTY") }, GEOM_BUILDER(Create_func_isempty)},
47054758
{ { STRING_WITH_LEN("ISVALID") }, GEOM_BUILDER(Create_func_isvalid)},
4759+
{ { STRING_WITH_LEN("VALIDATE") }, GEOM_BUILDER(Create_func_validate)},
47064760
{ { STRING_WITH_LEN("ISRING") }, GEOM_BUILDER(Create_func_isring)},
47074761
{ { STRING_WITH_LEN("ISSIMPLE") }, GEOM_BUILDER(Create_func_issimple)},
47084762
{ { STRING_WITH_LEN("SIMPLIFY") }, GEOM_BUILDER(Create_func_simplify)},
@@ -4787,6 +4841,7 @@ static Native_func_registry func_array_geom[] =
47874841
{ { STRING_WITH_LEN("ST_ISCLOSED") }, GEOM_BUILDER(Create_func_isclosed)},
47884842
{ { STRING_WITH_LEN("ST_ISEMPTY") }, GEOM_BUILDER(Create_func_isempty)},
47894843
{ { STRING_WITH_LEN("ST_ISVALID") }, GEOM_BUILDER(Create_func_isvalid)},
4844+
{ { STRING_WITH_LEN("ST_VALIDATE") }, GEOM_BUILDER(Create_func_validate)},
47904845
{ { STRING_WITH_LEN("ST_ISRING") }, GEOM_BUILDER(Create_func_isring)},
47914846
{ { STRING_WITH_LEN("ST_ISSIMPLE") }, GEOM_BUILDER(Create_func_issimple)},
47924847
{ { STRING_WITH_LEN("ST_SIMPLIFY") }, GEOM_BUILDER(Create_func_simplify)},

0 commit comments

Comments
 (0)