diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2013-03-26 21:47:06 +0400 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2013-03-26 21:47:06 +0400 |
commit | 045c498691f77ac8e0d8c8b9b705325b3425c69d (patch) | |
tree | d1e64ca715c07e5cf1d93afb7de6e37858f7a03f /sql | |
parent | 51a707486433d3707ac38deb72c6ad7d3d7bb882 (diff) | |
download | mariadb-git-045c498691f77ac8e0d8c8b9b705325b3425c69d.tar.gz |
GEOMETRYCOLLECTION EMPTY handling fixed.
The get_mbr() method shouldn't return the error, rather an invalid MBR
in this case.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_geofunc.cc | 12 | ||||
-rw-r--r-- | sql/spatial.cc | 19 | ||||
-rw-r--r-- | sql/spatial.h | 3 |
3 files changed, 23 insertions, 11 deletions
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 7d0f06d6237..1168813e275 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -559,8 +559,8 @@ longlong Item_func_spatial_mbr_rel::val_int() args[1]->null_value || !(g1= Geometry::construct(&buffer1, res1->ptr(), res1->length())) || !(g2= Geometry::construct(&buffer2, res2->ptr(), res2->length())) || - g1->get_mbr(&mbr1, &dummy) || - g2->get_mbr(&mbr2, &dummy)))) + g1->get_mbr(&mbr1, &dummy) || !mbr1.valid() || + g2->get_mbr(&mbr2, &dummy) || !mbr2.valid()))) return 0; switch (spatial_rel) { @@ -686,8 +686,8 @@ longlong Item_func_spatial_rel::val_int() (args[0]->null_value || args[1]->null_value || !(g1= Geometry::construct(&buffer1, res1->ptr(), res1->length())) || !(g2= Geometry::construct(&buffer2, res2->ptr(), res2->length())) || - g1->get_mbr(&mbr1, &c_end) || - g2->get_mbr(&mbr2, &c_end)))) + g1->get_mbr(&mbr1, &c_end) || !mbr1.valid() || + g2->get_mbr(&mbr2, &c_end) || !mbr2.valid()))) goto exit; umbr= mbr1; @@ -824,8 +824,8 @@ String *Item_func_spatial_operation::val_str(String *str_value) (args[0]->null_value || args[1]->null_value || !(g1= Geometry::construct(&buffer1, res1->ptr(), res1->length())) || !(g2= Geometry::construct(&buffer2, res2->ptr(), res2->length())) || - g1->get_mbr(&mbr1, &c_end) || - g2->get_mbr(&mbr2, &c_end)))) + g1->get_mbr(&mbr1, &c_end) || !mbr1.valid() || + g2->get_mbr(&mbr2, &c_end) || !mbr2.valid()))) { str_value= 0; goto exit; diff --git a/sql/spatial.cc b/sql/spatial.cc index 0da2fdf40b3..cec6150c22a 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -308,6 +308,9 @@ bool Geometry::envelope(String *result) const const char *end; if (get_mbr(&mbr, &end)) + return 1; + + if (!mbr.valid()) { /* Empty geometry */ if (result->reserve(1 + 4*2)) @@ -2322,7 +2325,7 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const n_objects= uint4korr(data); data+= 4; if (n_objects == 0) - return 1; + goto exit; while (n_objects--) { @@ -2339,6 +2342,7 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const if (geom->get_mbr(mbr, &data)) return 1; } +exit: *end= data; return 0; } @@ -2356,10 +2360,11 @@ int Gis_geometry_collection::area(double *ar, const char **end) const return 1; n_objects= uint4korr(data); data+= 4; - if (n_objects == 0) - return 1; result= 0.0; + if (n_objects == 0) + goto exit; + while (n_objects--) { uint32 wkb_type; @@ -2376,6 +2381,7 @@ int Gis_geometry_collection::area(double *ar, const char **end) const return 1; result+= *ar; } +exit: *end= data; *ar= result; return 0; @@ -2394,10 +2400,11 @@ int Gis_geometry_collection::geom_length(double *len, const char **end) const return 1; n_objects= uint4korr(data); data+= 4; + result= 0.0; + if (n_objects == 0) - return 1; + goto exit; - result= 0.0; while (n_objects--) { uint32 wkb_type; @@ -2414,6 +2421,8 @@ int Gis_geometry_collection::geom_length(double *len, const char **end) const return 1; result+= *len; } + +exit: *end= data; *len= result; return 0; diff --git a/sql/spatial.h b/sql/spatial.h index 6850cc804d0..1108f5d5e50 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -199,6 +199,9 @@ struct MBR return (d == intersection.dimension()); } + + int valid() const + { return xmin <= xmax && ymin <= ymax; } }; |