summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorAlexey Botchkov <holyfoot@askmonty.org>2011-09-04 19:11:04 +0500
committerAlexey Botchkov <holyfoot@askmonty.org>2011-09-04 19:11:04 +0500
commiteefff87652cde1cb0c986fd167ed057e87230250 (patch)
tree610484de1f8231ab6291ebb0678a12927c2d424f /sql
parentc937b7588f007d24c1cf93ee0b2da9e0e244d711 (diff)
downloadmariadb-git-eefff87652cde1cb0c986fd167ed057e87230250.tar.gz
bug 801466 ST_INTERSECTION() returns invalid value on empty intersection in maria-5.3-gis.
We didn't implement an empty geometry. And returning NULL instead of it is not quite correct. So here is the implementation of the empty value as GEOMETRYCOLLECTION(). per-file comments: mysql-test/r/gis-precise.result bug 801466 ST_INTERSECTION() returns invalid value on empty intersection in maria-5.3-gis. test result updated. mysql-test/r/gis.result bug 801466 ST_INTERSECTION() returns invalid value on empty intersection in maria-5.3-gis. test result updated. mysql-test/t/gis-precise.test bug 801466 ST_INTERSECTION() returns invalid value on empty intersection in maria-5.3-gis. test case added. mysql-test/t/gis.test bug 801466 ST_INTERSECTION() returns invalid value on empty intersection in maria-5.3-gis. test case added. sql/field.cc bug 801466 ST_INTERSECTION() returns invalid value on empty intersection in maria-5.3-gis. store GEOMETRYCOLLECTION() properly. sql/gcalc_tools.cc bug 801466 ST_INTERSECTION() returns invalid value on empty intersection in maria-5.3-gis. create the GEOMETRYCOLLECTION() for the empty result. sql/gstream.h bug 801466 ST_INTERSECTION() returns invalid value on empty intersection in maria-5.3-gis. next_symbol() added. sql/spatial.cc bug 801466 ST_INTERSECTION() returns invalid value on empty intersection in maria-5.3-gis. code modified to handle 0 geometries in the GEOMETRYCOLLECTION properly.
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc2
-rw-r--r--sql/gcalc_tools.cc9
-rw-r--r--sql/gstream.h8
-rw-r--r--sql/spatial.cc26
4 files changed, 28 insertions, 17 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 50f66363c1f..42324674838 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -8008,7 +8008,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
goto err;
// Check given WKB
uint32 wkb_type;
- if (length < SRID_SIZE + WKB_HEADER_SIZE + SIZEOF_STORED_DOUBLE*2)
+ if (length < SRID_SIZE + WKB_HEADER_SIZE + 4)
goto err;
wkb_type= uint4korr(from + SRID_SIZE + 1);
if (wkb_type < (uint32) Geometry::wkb_point ||
diff --git a/sql/gcalc_tools.cc b/sql/gcalc_tools.cc
index ab173803323..0d5c1c52d61 100644
--- a/sql/gcalc_tools.cc
+++ b/sql/gcalc_tools.cc
@@ -137,6 +137,8 @@ int Gcalc_function::count_internal()
cur_func+= 4;
if (next_func == op_shape)
return i_states[c_op & ~(op_any | op_not)] ^ mask;
+ if (n_ops == 0)
+ return mask;
result= count_internal();
@@ -442,11 +444,9 @@ void Gcalc_result_receiver::reset()
int Gcalc_result_receiver::get_result_typeid()
{
- if (!n_shapes)
- return 0;
-
- if (collection_result)
+ if (!n_shapes || collection_result)
return Geometry::wkb_geometrycollection;
+
switch (common_shapetype)
{
case Gcalc_function::shape_polygon:
@@ -1186,6 +1186,7 @@ int Gcalc_operation_reducer::get_result(Gcalc_result_receiver *storage)
poly_instance *polygons= NULL;
*m_res_hook= NULL;
+
while (m_result)
{
Gcalc_function::shape_type shape= m_result->type;
diff --git a/sql/gstream.h b/sql/gstream.h
index 1ef90ad5bf0..a1850e9a333 100644
--- a/sql/gstream.h
+++ b/sql/gstream.h
@@ -57,6 +57,14 @@ public:
m_cur++;
return 0;
}
+ /* Returns the next notempty character. */
+ char next_symbol()
+ {
+ skip_space();
+ if (m_cur >= m_limit)
+ return 0; /* EOL meet. */
+ return *m_cur;
+ }
void set_error_msg(const char *msg);
// caller should free this pointer
diff --git a/sql/spatial.cc b/sql/spatial.cc
index 67ece027141..67e36ccb12b 100644
--- a/sql/spatial.cc
+++ b/sql/spatial.cc
@@ -2075,19 +2075,22 @@ bool Gis_geometry_collection::init_from_wkt(Gis_read_stream *trs, String *wkb)
return 1;
wkb->length(wkb->length()+4); // Reserve space for points
- for (;;)
+ if (trs->next_symbol() != ')')
{
- if (!(g= create_from_wkt(&buffer, trs, wkb)))
- return 1;
-
- if (g->get_class_info()->m_type_id == wkb_geometrycollection)
+ for (;;)
{
- trs->set_error_msg("Unexpected GEOMETRYCOLLECTION");
- return 1;
+ if (!(g= create_from_wkt(&buffer, trs, wkb)))
+ return 1;
+
+ if (g->get_class_info()->m_type_id == wkb_geometrycollection)
+ {
+ trs->set_error_msg("Unexpected GEOMETRYCOLLECTION");
+ return 1;
+ }
+ n_objects++;
+ if (trs->skip_char(',')) // Didn't find ','
+ break;
}
- n_objects++;
- if (trs->skip_char(',')) // Didn't find ','
- break;
}
wkb->write_at_position(no_pos, n_objects);
@@ -2208,10 +2211,9 @@ bool Gis_geometry_collection::get_data_as_wkt(String *txt,
geom->set_data_ptr(data, (uint) (m_data_end - data));
if (geom->as_wkt(txt, &data))
return 1;
- if (txt->append(STRING_WITH_LEN(","), 512))
+ if (n_objects && txt->append(STRING_WITH_LEN(","), 512))
return 1;
}
- txt->length(txt->length() - 1);
*end= data;
return 0;
}