Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 122 additions & 1 deletion mysql-test/main/gis-json.result
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ Warning 4076 Incorrect GeoJSON format - empty 'coordinates' array.
SELECT ST_GEOMFROMGEOJSON("{ \"type\": \"Feature\", \"geometry\": [10, 20] }") as exp;
exp
NULL
Warnings:
Warning 4048 Incorrect GeoJSON format specified for st_geomfromgeojson function.
SELECT ST_ASTEXT (ST_GEOMFROMGEOJSON ('{ "type": "GEOMETRYCOLLECTION", "coordinates": [102.0, 0.0]}')) as exp;
exp
NULL
Expand All @@ -135,5 +137,124 @@ repeat(']}', 2000)
exp
NULL
Warnings:
Warning 4040 Limit of 32 on JSON nested structures depth is reached in argument 1 to function 'st_geomfromgeojson' at position 473
Warning 4040 Limit of 32 on JSON nested structures depth is reached in argument 1 to function 'st_geomfromgeojson' at position 688
# Boundary condition: foreign-member nesting at depth 32
SET @geom := '{"type":"Point","coordinates":[1,2]}';
SET @doc := CONCAT(
REPEAT('{"x":', 29),
@geom,
REPEAT('}', 29)
);
SELECT ST_ASTEXT( ST_GeomFromGeoJSON(@doc) ) AS expr;
expr
NULL
Warnings:
Warning 4048 Incorrect GeoJSON format specified for st_geomfromgeojson function.
# Foreign-member nesting exceeds depth 32
SET @geom := '{"type":"Point","coordinates":[1,2]}';
SET @doc := CONCAT(
REPEAT('{"x":', 30),
@geom,
REPEAT('}', 30)
);
SELECT ST_GeomFromGeoJSON(@doc) AS expr;
expr
NULL
Warnings:
Warning 4040 Limit of 32 on JSON nested structures depth is reached in argument 1 to function 'st_geomfromgeojson' at position 181
# Deep foreign member attached to otherwise valid GeoJSON
SET @foreign := CONCAT(
REPEAT('{"x":', 28),
'{"leaf":1}',
REPEAT('}', 28)
);
SET @doc := CONCAT(
'{"type":"Point","coordinates":[10,20],"foreign":',
@foreign,
'}'
);
SELECT ST_ASTEXT(ST_GeomFromGeoJSON(@doc)) AS expr;
expr
POINT(10 20)
# Foreign member exceeds depth limit
SET @foreign := CONCAT(
REPEAT('{"x":', 29),
'{"leaf":1}',
REPEAT('}', 29)
);
SET @doc := CONCAT(
'{"type":"Point","coordinates":[10,20],"foreign":',
@foreign,
'}'
);
SELECT ST_ASTEXT(ST_GeomFromGeoJSON(@doc)) AS expr;
expr
POINT(10 20)
# GeometryCollection containing 33 valid GeoJSON Point objects
SET @point := '{"type":"Point","coordinates":[1,2]}';
SET @geoms := CONCAT(
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point
);
SET @doc := CONCAT(
'{"type":"GeometryCollection","geometries":[',
@geoms,
']}'
);
SELECT ST_AsText(ST_GeomFromGeoJSON(@doc)) AS expr;
expr
GEOMETRYCOLLECTION(POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2),POINT(1 2))
#
# MDEV-39981: ST_GEOMFROMGEOJSON returns wrong result with reversed key order
#
# GeometryCollection: type before geometries (baseline)
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"type":"GeometryCollection","geometries":[]}')) as expr;
expr
GEOMETRYCOLLECTION EMPTY
# GeometryCollection: geometries before type (empty)
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometries":[],"type":"GeometryCollection"}')) as expr;
expr
GEOMETRYCOLLECTION EMPTY
# GeometryCollection: geometries before type (non-empty)
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometries":[{"type":"Point","coordinates":[0,1]}],"type":"GeometryCollection"}')) as expr;
expr
GEOMETRYCOLLECTION(POINT(0 1))
# GeometryCollection: multiple geometries before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometries":[{"type":"Point","coordinates":[1,2]},{"type":"Point","coordinates":[3,4]}],"type":"GeometryCollection"}')) as expr;
expr
GEOMETRYCOLLECTION(POINT(1 2),POINT(3 4))
# Point: coordinates before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"coordinates":[0,1],"type":"Point"}')) as expr;
expr
POINT(0 1)
# LineString: coordinates before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"coordinates":[[0,0],[1,1],[2,2]],"type":"LineString"}')) as expr;
expr
LINESTRING(0 0,1 1,2 2)
# Polygon: coordinates before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"coordinates":[[[0,0],[1,0],[1,1],[0,1],[0,0]]],"type":"Polygon"}')) as expr;
expr
POLYGON((0 0,1 0,1 1,0 1,0 0))
# FeatureCollection: features before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"features":[{"geometry":{"type":"Point","coordinates":[5,6]},"type":"Feature","properties":{}}],"type":"FeatureCollection"}')) as expr;
expr
GEOMETRYCOLLECTION(POINT(5 6))
# Feature: geometry before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometry":{"coordinates":[7,8],"type":"Point"},"type":"Feature","properties":{}}')) as expr;
expr
POINT(7 8)
# Unknown keys interspersed (should be ignored)
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"foo":"bar","geometries":[],"type":"GeometryCollection","extra":123}')) as expr;
expr
GEOMETRYCOLLECTION EMPTY
# Deeply nested geometries before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometries":[{"geometries":[{"type":"Point","coordinates":[9,10]}],"type":"GeometryCollection"}],"type":"GeometryCollection"}')) as expr;
expr
GEOMETRYCOLLECTION(GEOMETRYCOLLECTION(POINT(9 10)))
# End of 10.6 tests
114 changes: 114 additions & 0 deletions mysql-test/main/gis-json.test
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,118 @@ SELECT ST_GeomFromGeoJSON(
repeat(']}', 2000)
)) as exp;

--echo # Boundary condition: foreign-member nesting at depth 32
SET @geom := '{"type":"Point","coordinates":[1,2]}';

SET @doc := CONCAT(
REPEAT('{"x":', 29),
@geom,
REPEAT('}', 29)
);

SELECT ST_ASTEXT( ST_GeomFromGeoJSON(@doc) ) AS expr;


--echo # Foreign-member nesting exceeds depth 32
SET @geom := '{"type":"Point","coordinates":[1,2]}';

SET @doc := CONCAT(
REPEAT('{"x":', 30),
@geom,
REPEAT('}', 30)
);

SELECT ST_GeomFromGeoJSON(@doc) AS expr;


--echo # Deep foreign member attached to otherwise valid GeoJSON
SET @foreign := CONCAT(
REPEAT('{"x":', 28),
'{"leaf":1}',
REPEAT('}', 28)
);

SET @doc := CONCAT(
'{"type":"Point","coordinates":[10,20],"foreign":',
@foreign,
'}'
);

SELECT ST_ASTEXT(ST_GeomFromGeoJSON(@doc)) AS expr;


--echo # Foreign member exceeds depth limit
SET @foreign := CONCAT(
REPEAT('{"x":', 29),
'{"leaf":1}',
REPEAT('}', 29)
);

SET @doc := CONCAT(
'{"type":"Point","coordinates":[10,20],"foreign":',
@foreign,
'}'
);

SELECT ST_ASTEXT(ST_GeomFromGeoJSON(@doc)) AS expr;

--echo # GeometryCollection containing 33 valid GeoJSON Point objects
SET @point := '{"type":"Point","coordinates":[1,2]}';

SET @geoms := CONCAT(
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point, ',', @point, ',', @point, ',',
@point, ',', @point, ',', @point
);

SET @doc := CONCAT(
'{"type":"GeometryCollection","geometries":[',
@geoms,
']}'
);

SELECT ST_AsText(ST_GeomFromGeoJSON(@doc)) AS expr;

--echo #
--echo # MDEV-39981: ST_GEOMFROMGEOJSON returns wrong result with reversed key order
--echo #

--echo # GeometryCollection: type before geometries (baseline)
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"type":"GeometryCollection","geometries":[]}')) as expr;

--echo # GeometryCollection: geometries before type (empty)
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometries":[],"type":"GeometryCollection"}')) as expr;

--echo # GeometryCollection: geometries before type (non-empty)
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometries":[{"type":"Point","coordinates":[0,1]}],"type":"GeometryCollection"}')) as expr;

--echo # GeometryCollection: multiple geometries before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometries":[{"type":"Point","coordinates":[1,2]},{"type":"Point","coordinates":[3,4]}],"type":"GeometryCollection"}')) as expr;

--echo # Point: coordinates before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"coordinates":[0,1],"type":"Point"}')) as expr;

--echo # LineString: coordinates before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"coordinates":[[0,0],[1,1],[2,2]],"type":"LineString"}')) as expr;

--echo # Polygon: coordinates before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"coordinates":[[[0,0],[1,0],[1,1],[0,1],[0,0]]],"type":"Polygon"}')) as expr;

--echo # FeatureCollection: features before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"features":[{"geometry":{"type":"Point","coordinates":[5,6]},"type":"Feature","properties":{}}],"type":"FeatureCollection"}')) as expr;

--echo # Feature: geometry before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometry":{"coordinates":[7,8],"type":"Point"},"type":"Feature","properties":{}}')) as expr;

--echo # Unknown keys interspersed (should be ignored)
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"foo":"bar","geometries":[],"type":"GeometryCollection","extra":123}')) as expr;

--echo # Deeply nested geometries before type
SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"geometries":[{"geometries":[{"type":"Point","coordinates":[9,10]}],"type":"GeometryCollection"}],"type":"GeometryCollection"}')) as expr;

--echo # End of 10.6 tests
3 changes: 2 additions & 1 deletion sql/item_geofunc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ String *Item_func_geometry_from_json::val_str(String *str)
(const uchar *) js->end());
je.killed_ptr= (uint32_t *) &current_thd->killed;

if ((null_value= !Geometry::create_from_json(&buffer, &je, options==1, str)))
if (!json_read_value(&je) &&
(null_value= !Geometry::create_from_json(&buffer, &je, options==1, str)))
{
int code= 0;

Expand Down
Loading