Commit d0f2e1e5 authored by Alexey Botchkov's avatar Alexey Botchkov

bug 855336 ST_LENGTH does not work on GEOMETRYCOLLECTIONs fixed.

per-file comments:
  mysql-test/r/gis.result
bug 855336      ST_LENGTH does not work on GEOMETRYCOLLECTIONs fixed.
        test result updated.
  mysql-test/t/gis.test
bug 855336      ST_LENGTH does not work on GEOMETRYCOLLECTIONs fixed.
        test case added.
  sql/item_geofunc.cc
bug 855336      ST_LENGTH does not work on GEOMETRYCOLLECTIONs fixed.
        geom_length() call fixed.
  sql/spatial.cc
bug 855336      ST_LENGTH does not work on GEOMETRYCOLLECTIONs fixed.
        Geometry_collection::geom_length implemented.
  sql/spatial.h
bug 855336      ST_LENGTH does not work on GEOMETRYCOLLECTIONs fixed.
        Geometry_collection::geom_length declaration added.
parent 6b64baf3
...@@ -1097,6 +1097,9 @@ DROP TABLE t2; ...@@ -1097,6 +1097,9 @@ DROP TABLE t2;
select ST_AREA(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))')); select ST_AREA(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))'));
ST_AREA(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))')) ST_AREA(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))'))
1.5 1.5
select ST_LENGTH(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 100 30, 20 30), POINT(3 3), LINESTRING(20 20, 30 20))'));
ST_LENGTH(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 100 30, 20 30), POINT(3 3), LINESTRING(20 20, 30 20))'))
160
DROP DATABASE IF EXISTS gis_ogs; DROP DATABASE IF EXISTS gis_ogs;
CREATE DATABASE gis_ogs; CREATE DATABASE gis_ogs;
USE gis_ogs; USE gis_ogs;
......
...@@ -808,6 +808,8 @@ DROP TABLE t2; ...@@ -808,6 +808,8 @@ DROP TABLE t2;
#bug 850775 ST_AREA does not work on GEOMETRYCOLLECTIONs in maria-5.3-gis #bug 850775 ST_AREA does not work on GEOMETRYCOLLECTIONs in maria-5.3-gis
select ST_AREA(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))')); select ST_AREA(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 31 10, 77 80), POLYGON((0 0,4 7,1 1,0 0)), POINT(20 20))'));
#bug 855336 ST_LENGTH does not work on GEOMETRYCOLLECTIONs
select ST_LENGTH(ST_GEOMCOLLFROMTEXT(' GEOMETRYCOLLECTION(LINESTRING(100 100, 100 30, 20 30), POINT(3 3), LINESTRING(20 20, 30 20))'));
# Conformance tests # Conformance tests
......
...@@ -1719,12 +1719,13 @@ double Item_func_glength::val_real() ...@@ -1719,12 +1719,13 @@ double Item_func_glength::val_real()
String *swkb= args[0]->val_str(&value); String *swkb= args[0]->val_str(&value);
Geometry_buffer buffer; Geometry_buffer buffer;
Geometry *geom; Geometry *geom;
const char *end;
null_value= (!swkb || null_value= (!swkb ||
!(geom= Geometry::construct(&buffer, !(geom= Geometry::construct(&buffer,
swkb->ptr(), swkb->ptr(),
swkb->length())) || swkb->length())) ||
geom->geom_length(&res)); geom->geom_length(&res, &end));
return res; return res;
} }
......
...@@ -518,6 +518,14 @@ int Gis_point::area(double *ar, const char **end) const ...@@ -518,6 +518,14 @@ int Gis_point::area(double *ar, const char **end) const
} }
int Gis_point::geom_length(double *len, const char **end) const
{
*len= 0;
*end= m_data+ POINT_DATA_SIZE;
return 0;
}
int Gis_point::store_shapes(Gcalc_shape_transporter *trn) const int Gis_point::store_shapes(Gcalc_shape_transporter *trn) const
{ {
double x, y; double x, y;
...@@ -634,7 +642,7 @@ bool Gis_line_string::get_mbr(MBR *mbr, const char **end) const ...@@ -634,7 +642,7 @@ bool Gis_line_string::get_mbr(MBR *mbr, const char **end) const
} }
int Gis_line_string::geom_length(double *len) const int Gis_line_string::geom_length(double *len, const char **end) const
{ {
uint32 n_points; uint32 n_points;
double prev_x, prev_y; double prev_x, prev_y;
...@@ -659,6 +667,7 @@ int Gis_line_string::geom_length(double *len) const ...@@ -659,6 +667,7 @@ int Gis_line_string::geom_length(double *len) const
prev_x= x; prev_x= x;
prev_y= y; prev_y= y;
} }
*end= data;
return 0; return 0;
} }
...@@ -1628,10 +1637,11 @@ int Gis_multi_line_string::geometry_n(uint32 num, String *result) const ...@@ -1628,10 +1637,11 @@ int Gis_multi_line_string::geometry_n(uint32 num, String *result) const
} }
int Gis_multi_line_string::geom_length(double *len) const int Gis_multi_line_string::geom_length(double *len, const char **end) const
{ {
uint32 n_line_strings; uint32 n_line_strings;
const char *data= m_data; const char *data= m_data;
const char *line_end;
if (no_data(data, 4)) if (no_data(data, 4))
return 1; return 1;
...@@ -1645,7 +1655,7 @@ int Gis_multi_line_string::geom_length(double *len) const ...@@ -1645,7 +1655,7 @@ int Gis_multi_line_string::geom_length(double *len) const
Gis_line_string ls; Gis_line_string ls;
data+= WKB_HEADER_SIZE; data+= WKB_HEADER_SIZE;
ls.set_data_ptr(data, (uint32) (m_data_end - data)); ls.set_data_ptr(data, (uint32) (m_data_end - data));
if (ls.geom_length(&ls_len)) if (ls.geom_length(&ls_len, &line_end))
return 1; return 1;
*len+= ls_len; *len+= ls_len;
/* /*
...@@ -1654,6 +1664,7 @@ int Gis_multi_line_string::geom_length(double *len) const ...@@ -1654,6 +1664,7 @@ int Gis_multi_line_string::geom_length(double *len) const
*/ */
data+= ls.get_data_size(); data+= ls.get_data_size();
} }
*end= data;
return 0; return 0;
} }
...@@ -2319,7 +2330,7 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const ...@@ -2319,7 +2330,7 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const
} }
int Gis_geometry_collection::area(double *ar, const char **end_of_data) const int Gis_geometry_collection::area(double *ar, const char **end) const
{ {
uint32 n_objects; uint32 n_objects;
const char *data= m_data; const char *data= m_data;
...@@ -2351,12 +2362,50 @@ int Gis_geometry_collection::area(double *ar, const char **end_of_data) const ...@@ -2351,12 +2362,50 @@ int Gis_geometry_collection::area(double *ar, const char **end_of_data) const
return 1; return 1;
result+= *ar; result+= *ar;
} }
*end_of_data= data; *end= data;
*ar= result; *ar= result;
return 0; return 0;
} }
int Gis_geometry_collection::geom_length(double *len, const char **end) const
{
uint32 n_objects;
const char *data= m_data;
Geometry_buffer buffer;
Geometry *geom;
double result;
if (no_data(data, 4))
return 1;
n_objects= uint4korr(data);
data+= 4;
if (n_objects == 0)
return 1;
result= 0.0;
while (n_objects--)
{
uint32 wkb_type;
if (no_data(data, WKB_HEADER_SIZE))
return 1;
wkb_type= uint4korr(data + 1);
data+= WKB_HEADER_SIZE;
if (!(geom= create_by_typeid(&buffer, wkb_type)))
return 1;
geom->set_data_ptr(data, (uint32) (m_data_end - data));
if (geom->geom_length(len, &data))
return 1;
result+= *len;
}
*end= data;
*len= result;
return 0;
}
int Gis_geometry_collection::num_geometries(uint32 *num) const int Gis_geometry_collection::num_geometries(uint32 *num) const
{ {
if (no_data(m_data, 4)) if (no_data(m_data, 4))
......
...@@ -259,7 +259,7 @@ public: ...@@ -259,7 +259,7 @@ public:
virtual bool dimension(uint32 *dim, const char **end) const=0; virtual bool dimension(uint32 *dim, const char **end) const=0;
virtual int get_x(double *x) const { return -1; } virtual int get_x(double *x) const { return -1; }
virtual int get_y(double *y) const { return -1; } virtual int get_y(double *y) const { return -1; }
virtual int geom_length(double *len) const { return -1; } virtual int geom_length(double *len, const char **end) const { return -1; }
virtual int area(double *ar, const char **end) const { return -1;} virtual int area(double *ar, const char **end) const { return -1;}
virtual int is_closed(int *closed) const { return -1; } virtual int is_closed(int *closed) const { return -1; }
virtual int num_interior_ring(uint32 *n_int_rings) const { return -1; } virtual int num_interior_ring(uint32 *n_int_rings) const { return -1; }
...@@ -364,6 +364,7 @@ public: ...@@ -364,6 +364,7 @@ public:
return 0; return 0;
} }
int geom_length(double *len, const char **end) const;
int area(double *ar, const char **end) const; int area(double *ar, const char **end) const;
bool dimension(uint32 *dim, const char **end) const bool dimension(uint32 *dim, const char **end) const
{ {
...@@ -388,7 +389,7 @@ public: ...@@ -388,7 +389,7 @@ public:
uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res); uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);
bool get_data_as_wkt(String *txt, const char **end) const; bool get_data_as_wkt(String *txt, const char **end) const;
bool get_mbr(MBR *mbr, const char **end) const; bool get_mbr(MBR *mbr, const char **end) const;
int geom_length(double *len) const; int geom_length(double *len, const char **end) const;
int area(double *ar, const char **end) const; int area(double *ar, const char **end) const;
int is_closed(int *closed) const; int is_closed(int *closed) const;
int num_points(uint32 *n_points) const; int num_points(uint32 *n_points) const;
...@@ -477,7 +478,7 @@ public: ...@@ -477,7 +478,7 @@ public:
bool get_mbr(MBR *mbr, const char **end) const; bool get_mbr(MBR *mbr, const char **end) const;
int num_geometries(uint32 *num) const; int num_geometries(uint32 *num) const;
int geometry_n(uint32 num, String *result) const; int geometry_n(uint32 num, String *result) const;
int geom_length(double *len) const; int geom_length(double *len, const char **end) const;
int is_closed(int *closed) const; int is_closed(int *closed) const;
bool dimension(uint32 *dim, const char **end) const bool dimension(uint32 *dim, const char **end) const
{ {
...@@ -532,6 +533,7 @@ public: ...@@ -532,6 +533,7 @@ public:
bool get_data_as_wkt(String *txt, const char **end) const; bool get_data_as_wkt(String *txt, const char **end) const;
bool get_mbr(MBR *mbr, const char **end) const; bool get_mbr(MBR *mbr, const char **end) const;
int area(double *ar, const char **end) const; int area(double *ar, const char **end) const;
int geom_length(double *len, const char **end) const;
int num_geometries(uint32 *num) const; int num_geometries(uint32 *num) const;
int geometry_n(uint32 num, String *result) const; int geometry_n(uint32 num, String *result) const;
bool dimension(uint32 *dim, const char **end) const; bool dimension(uint32 *dim, const char **end) const;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment