diff --git a/mysql-test/main/gis-json.result b/mysql-test/main/gis-json.result index 4ea2fec767443..fd4fd854980ca 100644 --- a/mysql-test/main/gis-json.result +++ b/mysql-test/main/gis-json.result @@ -123,3 +123,22 @@ Warning 4048 Incorrect GeoJSON format specified for st_geomfromgeojson function. # # End of 10.2 tests # +# +# MDEV-34079: ST_AsGeoJSON returns incorrect value for empty geometry +# +SELECT ST_AsGeoJSON(GeomFromText('GeometryCollection EMPTY')); +ST_AsGeoJSON(GeomFromText('GeometryCollection EMPTY')) +{"type": "GeometryCollection", "geometries": []} +SELECT ST_AsGeoJSON(ST_DIFFERENCE(POINT(0,0), POINT(0,0))); +ST_AsGeoJSON(ST_DIFFERENCE(POINT(0,0), POINT(0,0))) +{"type": "GeometryCollection", "geometries": []} +SELECT ST_AsGeoJSON(GeomFromText('MultiPoint EMPTY')); +ST_AsGeoJSON(GeomFromText('MultiPoint EMPTY')) +NULL +SELECT ST_AsGeoJSON(GeomFromText('MultiLineString EMPTY')); +ST_AsGeoJSON(GeomFromText('MultiLineString EMPTY')) +NULL +SELECT ST_AsGeoJSON(GeomFromText('MultiPolygon EMPTY')); +ST_AsGeoJSON(GeomFromText('MultiPolygon EMPTY')) +NULL +# End of 10.11 tests diff --git a/mysql-test/main/gis-json.test b/mysql-test/main/gis-json.test index 766a036609c7e..da9345aaf9eae 100644 --- a/mysql-test/main/gis-json.test +++ b/mysql-test/main/gis-json.test @@ -58,3 +58,14 @@ SELECT ST_ASTEXT(ST_GEOMFROMGEOJSON('{"type": ["POINT"], "coINates": [0,0] }')) --echo # --echo # End of 10.2 tests --echo # +--echo # +--echo # MDEV-34079: ST_AsGeoJSON returns incorrect value for empty geometry +--echo # + +SELECT ST_AsGeoJSON(GeomFromText('GeometryCollection EMPTY')); +SELECT ST_AsGeoJSON(ST_DIFFERENCE(POINT(0,0), POINT(0,0))); +SELECT ST_AsGeoJSON(GeomFromText('MultiPoint EMPTY')); +SELECT ST_AsGeoJSON(GeomFromText('MultiLineString EMPTY')); +SELECT ST_AsGeoJSON(GeomFromText('MultiPolygon EMPTY')); + +--echo # End of 10.11 tests diff --git a/sql/spatial.cc b/sql/spatial.cc index 9bf6110c991c2..b633d76e247ed 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -855,15 +855,18 @@ static void append_json_point(String *txt, uint max_dec, const char *data) static const char *append_json_points(String *txt, uint max_dec, uint32 n_points, const char *data, uint32 offset) { + bool any_points= false; txt->qs_append('['); while (n_points--) { + any_points= true; data+= offset; append_json_point(txt, max_dec, data); data+= POINT_DATA_SIZE; txt->qs_append(", ", 2); } - txt->length(txt->length() - 2);// Remove ending ', ' + if (any_points) + txt->length(txt->length() - 2);// Remove ending ', ' txt->qs_append(']'); return data; } @@ -1747,9 +1750,11 @@ bool Gis_polygon::get_data_as_json(String *txt, uint max_dec_digits, n_linear_rings= uint4korr(data); data+= 4; + bool any_rings= false; txt->qs_append('['); while (n_linear_rings--) { + any_rings= true; uint32 n_points; if (no_data(data, 4)) return 1; @@ -1761,7 +1766,8 @@ bool Gis_polygon::get_data_as_json(String *txt, uint max_dec_digits, data= append_json_points(txt, max_dec_digits, n_points, data, 0); txt->qs_append(", ", 2); } - txt->length(txt->length() - 2);// Remove ending ', ' + if (any_rings) + txt->length(txt->length() - 2);// Remove ending ', ' txt->qs_append(']'); *end= data; return 0; @@ -2622,9 +2628,11 @@ bool Gis_multi_line_string::get_data_as_json(String *txt, uint max_dec_digits, n_line_strings= uint4korr(data); data+= 4; + bool any_ls= false; txt->qs_append('['); while (n_line_strings--) { + any_ls= true; uint32 n_points; if (no_data(data, (WKB_HEADER_SIZE + 4))) return 1; @@ -2636,7 +2644,8 @@ bool Gis_multi_line_string::get_data_as_json(String *txt, uint max_dec_digits, data= append_json_points(txt, max_dec_digits, n_points, data, 0); txt->qs_append(", ", 2); } - txt->length(txt->length() - 2); + if (any_ls) + txt->length(txt->length() - 2); txt->qs_append(']'); *end= data; return 0; @@ -3032,9 +3041,11 @@ bool Gis_multi_polygon::get_data_as_json(String *txt, uint max_dec_digits, n_polygons= uint4korr(data); data+= 4; + bool any_polygons= false; txt->q_append('['); while (n_polygons--) { + any_polygons= true; uint32 n_linear_rings; if (no_data(data, 4 + WKB_HEADER_SIZE) || txt->reserve(1, 512)) @@ -3043,8 +3054,10 @@ bool Gis_multi_polygon::get_data_as_json(String *txt, uint max_dec_digits, data+= 4 + WKB_HEADER_SIZE; txt->q_append('['); + bool any_rings= false; while (n_linear_rings--) { + any_rings= true; if (no_data(data, 4)) return 1; uint32 n_points= uint4korr(data); @@ -3056,10 +3069,12 @@ bool Gis_multi_polygon::get_data_as_json(String *txt, uint max_dec_digits, data= append_json_points(txt, max_dec_digits, n_points, data, 0); txt->qs_append(", ", 2); } - txt->length(txt->length() - 2); + if (any_rings) + txt->length(txt->length() - 2); txt->qs_append("], ", 3); } - txt->length(txt->length() - 2); + if (any_polygons) + txt->length(txt->length() - 2); txt->q_append(']'); *end= data; return 0; @@ -3511,9 +3526,11 @@ bool Gis_geometry_collection::get_data_as_json(String *txt, uint max_dec_digits, n_objects= uint4korr(data); data+= 4; + bool any_objects= false; txt->qs_append('['); while (n_objects--) { + any_objects= true; uint32 wkb_type; if (no_data(data, WKB_HEADER_SIZE)) @@ -3529,7 +3546,8 @@ bool Gis_geometry_collection::get_data_as_json(String *txt, uint max_dec_digits, txt->append(STRING_WITH_LEN("}, "), 512)) return 1; } - txt->length(txt->length() - 2); + if (any_objects) + txt->length(txt->length() - 2); if (txt->append(']')) return 1;