Optimized GIS functions

heap/hp_delete.c:
  Added comments
mysql-test/r/gis.result:
  Updated results after name changes (all results line are unchanged)
mysql-test/r/show_check.result:
  Update test results after fix in hp_delete.cc
mysql-test/t/gis.test:
  Changed table names to longer, hopefully non conflicting ones.
  Added missing drop table
mysys/hash.c:
  Inendation cleanup
mysys/tree.c:
  Updated comments
  Decrease tree->allocated on delete (for status)
sql/field.cc:
  Added safety checking for GIS objects
sql/gstream.cc:
  Added copyright message
  Made a lot of speed/space optimizations
  Changed class names to be MySQL compliant
sql/gstream.h:
  Made a lot of speed/space optimizations
  Changed class names to be MySQL compliant
sql/item_create.cc:
  Indentation fixup
sql/item_geofunc.cc:
  Use new gis interface functions and new gis class names.
  Simple optimizations
  Indentation fixups
  Fixed a lot of unlikely but possible errors.
sql/item_geofunc.h:
  Moved SRID_SIZE to spatial.h
sql/spatial.cc:
  Added copyright message
  Made a lot of speed/space optimizations
  Changed class names to be MySQL compliant
sql/spatial.h:
  Made a lot of speed/space optimizations
  Changed class names to be MySQL compliant
  Indentation fixes
  Use bool instead of int as result type for functions that only return 0 or 1
sql/sql_string.cc:
  Simple optimizations
sql/sql_string.h:
  Simple cleanups
sql/structs.h:
  Added LEX_STRING_WITH_INIT (needed by spatial.cc)
This commit is contained in:
unknown 2004-03-04 08:50:37 +02:00
commit afa6728a9f
17 changed files with 1599 additions and 1534 deletions

View file

@ -27,18 +27,17 @@
#include "sql_acl.h"
#include <m_ctype.h>
String *Item_func_geometry_from_text::val_str(String *str)
{
Geometry geom;
String arg_val;
String *wkt= args[0]->val_str(&arg_val);
GTextReadStream trs(wkt->ptr(), wkt->length());
uint32 srid;
Gis_read_stream trs(wkt->c_ptr(), wkt->length());
uint32 srid= 0;
if ((arg_count == 2) && !args[1]->null_value)
srid= (uint32)args[1]->val_int();
else
srid= 0;
if (str->reserve(SRID_SIZE, 512))
return 0;
@ -61,22 +60,19 @@ String *Item_func_geometry_from_wkb::val_str(String *str)
String arg_val;
String *wkb= args[0]->val_str(&arg_val);
Geometry geom;
uint32 srid;
uint32 srid= 0;
if ((arg_count == 2) && !args[1]->null_value)
srid= (uint32)args[1]->val_int();
else
srid= 0;
if (str->reserve(SRID_SIZE, 512))
return 0;
str->length(0);
str->q_append(srid);
if ((null_value= (args[0]->null_value ||
geom.create_from_wkb(wkb->ptr(), wkb->length()))))
geom.create_from_wkb(wkb->ptr(), wkb->length()))) ||
str->append(*wkb))
return 0;
str->append(*wkb);
return str;
}
@ -92,6 +88,7 @@ String *Item_func_as_wkt::val_str(String *str)
String arg_val;
String *swkb= args[0]->val_str(&arg_val);
Geometry geom;
const char *dummy;
if ((null_value= (args[0]->null_value ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
@ -99,18 +96,19 @@ String *Item_func_as_wkt::val_str(String *str)
return 0;
str->length(0);
if ((null_value= geom.as_wkt(str)))
if ((null_value= geom.as_wkt(str, &dummy)))
return 0;
return str;
}
void Item_func_as_wkt::fix_length_and_dec()
{
max_length=MAX_BLOB_WIDTH;
}
String *Item_func_as_wkb::val_str(String *str)
{
String arg_val;
@ -127,11 +125,13 @@ String *Item_func_as_wkb::val_str(String *str)
return str;
}
void Item_func_as_wkb::fix_length_and_dec()
{
max_length= MAX_BLOB_WIDTH;
}
String *Item_func_geometry_type::val_str(String *str)
{
String *swkb= args[0]->val_str(str);
@ -141,9 +141,10 @@ String *Item_func_geometry_type::val_str(String *str)
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE))))
return 0;
str->copy(geom.get_class_info()->m_name,
strlen(geom.get_class_info()->m_name),
default_charset());
/* String will not move */
str->set(geom.get_class_info()->m_name.str,
geom.get_class_info()->m_name.length,
default_charset());
return str;
}
@ -153,13 +154,14 @@ String *Item_func_envelope::val_str(String *str)
String arg_val;
String *swkb= args[0]->val_str(&arg_val);
Geometry geom;
uint32 srid;
if ((null_value= args[0]->null_value ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE)))
return 0;
uint32 srid= uint4korr(swkb->ptr());
srid= uint4korr(swkb->ptr());
str->length(0);
if (str->reserve(SRID_SIZE, 512))
return 0;
@ -173,20 +175,21 @@ String *Item_func_centroid::val_str(String *str)
String arg_val;
String *swkb= args[0]->val_str(&arg_val);
Geometry geom;
uint32 srid;
if ((null_value= args[0]->null_value ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE) ||
!GEOM_METHOD_PRESENT(geom, centroid)))
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE) ||
!GEOM_METHOD_PRESENT(geom, centroid)))
return 0;
if (str->reserve(SRID_SIZE, 512))
return 0;
str->length(0);
uint32 srid= uint4korr(swkb->ptr());
srid= uint4korr(swkb->ptr());
str->q_append(srid);
return (null_value= geom.centroid(str)) ? 0 : str;
return (null_value= test(geom.centroid(str))) ? 0 : str;
}
@ -199,42 +202,42 @@ String *Item_func_spatial_decomp::val_str(String *str)
String arg_val;
String *swkb= args[0]->val_str(&arg_val);
Geometry geom;
uint32 srid;
if ((null_value= (args[0]->null_value ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE))))
return 0;
null_value= 1;
srid= uint4korr(swkb->ptr());
if (str->reserve(SRID_SIZE, 512))
return 0;
goto err;
str->length(0);
uint32 srid= uint4korr(swkb->ptr());
str->q_append(srid);
switch(decomp_func)
{
switch (decomp_func) {
case SP_STARTPOINT:
if (!GEOM_METHOD_PRESENT(geom,start_point) || geom.start_point(str))
goto ret;
goto err;
break;
case SP_ENDPOINT:
if (!GEOM_METHOD_PRESENT(geom,end_point) || geom.end_point(str))
goto ret;
goto err;
break;
case SP_EXTERIORRING:
if (!GEOM_METHOD_PRESENT(geom,exterior_ring) || geom.exterior_ring(str))
goto ret;
goto err;
break;
default:
goto ret;
goto err;
}
null_value= 0;
return str;
ret:
return null_value ? 0 : str;
err:
null_value= 1;
return 0;
}
@ -244,43 +247,44 @@ String *Item_func_spatial_decomp_n::val_str(String *str)
String *swkb= args[0]->val_str(&arg_val);
long n= (long) args[1]->val_int();
Geometry geom;
uint32 srid;
if ((null_value= (args[0]->null_value || args[1]->null_value ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE))))
return 0;
null_value= 1;
if (str->reserve(SRID_SIZE, 512))
return 0;
goto err;
srid= uint4korr(swkb->ptr());
str->length(0);
uint32 srid= uint4korr(swkb->ptr());
str->q_append(srid);
switch(decomp_func_n)
switch (decomp_func_n)
{
case SP_POINTN:
if (!GEOM_METHOD_PRESENT(geom,point_n) || geom.point_n(n,str))
goto ret;
goto err;
break;
case SP_GEOMETRYN:
if (!GEOM_METHOD_PRESENT(geom,geometry_n) || geom.geometry_n(n,str))
goto ret;
goto err;
break;
case SP_INTERIORRINGN:
if (!GEOM_METHOD_PRESENT(geom,interior_ring_n) ||
geom.interior_ring_n(n,str))
goto ret;
goto err;
break;
default:
goto ret;
goto err;
}
null_value= 0;
return str;
ret:
return null_value ? 0 : str;
err:
null_value=1;
return 0;
}
@ -299,9 +303,9 @@ String *Item_func_point::val_str(String *str)
double x= args[0]->val();
double y= args[1]->val();
if ( (null_value= (args[0]->null_value ||
args[1]->null_value ||
str->realloc(1 + 4 + 8 + 8))))
if ((null_value= (args[0]->null_value ||
args[1]->null_value ||
str->realloc(1 + 4 + SIZEOF_STORED_DOUBLE*2))))
return 0;
str->length(0);
@ -328,11 +332,9 @@ String *Item_func_spatial_collection::val_str(String *str)
String arg_value;
uint i;
null_value= 1;
str->length(0);
if (str->reserve(1 + 4 + 4, 512))
return 0;
goto err;
str->q_append((char) Geometry::wkbNDR);
str->q_append((uint32) coll_type);
@ -342,19 +344,16 @@ String *Item_func_spatial_collection::val_str(String *str)
{
String *res= args[i]->val_str(&arg_value);
if (args[i]->null_value)
goto ret;
goto err;
if ( coll_type == Geometry::wkbGeometryCollection )
if (coll_type == Geometry::wkbGeometryCollection)
{
/*
In the case of GeometryCollection we don't need
any checkings for item types, so just copy them
into target collection
In the case of GeometryCollection we don't need any checkings
for item types, so just copy them into target collection
*/
if ((null_value= str->reserve(res->length(), 512)))
goto ret;
str->q_append(res->ptr(), res->length());
if (str->append(res->ptr(), res->length(), (uint32) 512))
goto err;
}
else
{
@ -363,86 +362,75 @@ String *Item_func_spatial_collection::val_str(String *str)
const char *data= res->ptr() + 1;
/*
In the case of named collection we must to
check that items are of specific type, let's
do this checking now
In the case of named collection we must to check that items
are of specific type, let's do this checking now
*/
if (len < 5)
goto ret;
goto err;
wkb_type= (Geometry::wkbType) uint4korr(data);
data+= 4;
len-= 5;
if (wkb_type != item_type)
goto ret;
goto err;
switch (coll_type) {
case Geometry::wkbMultiPoint:
case Geometry::wkbMultiLineString:
case Geometry::wkbMultiPolygon:
if (len < WKB_HEADER_SIZE)
goto ret;
data-= WKB_HEADER_SIZE;
len+= WKB_HEADER_SIZE;
if (str->reserve(len, 512))
goto ret;
str->q_append(data, len);
if (len < WKB_HEADER_SIZE ||
str->append(data-WKB_HEADER_SIZE, len+WKB_HEADER_SIZE, 512))
goto err;
break;
case Geometry::wkbLineString:
if (str->reserve(POINT_DATA_SIZE, 512))
goto ret;
str->q_append(data, POINT_DATA_SIZE);
if (str->append(data, POINT_DATA_SIZE, 512))
goto err;
break;
case Geometry::wkbPolygon:
{
uint32 n_points;
double x1, y1, x2, y2;
const char *org_data= data;
if (len < 4 + 2 * POINT_DATA_SIZE)
goto ret;
uint32 llen= len;
const char *ldata= data;
goto err;
n_points= uint4korr(data);
data+= 4;
float8get(x1, data);
data+= 8;
data+= SIZEOF_STORED_DOUBLE;
float8get(y1, data);
data+= 8;
data+= SIZEOF_STORED_DOUBLE;
data+= (n_points - 2) * POINT_DATA_SIZE;
float8get(x2, data);
float8get(y2, data + 8);
float8get(y2, data + SIZEOF_STORED_DOUBLE);
if ((x1 != x2) || (y1 != y2))
goto ret;
if (str->reserve(llen, 512))
goto ret;
str->q_append(ldata, llen);
if ((x1 != x2) || (y1 != y2) ||
str->append(org_data, len, 512))
goto err;
}
break;
default:
goto ret;
goto err;
}
}
}
if (str->length() > current_thd->variables.max_allowed_packet)
goto ret;
goto err;
null_value = 0;
return str;
ret:
return null_value ? 0 : str;
err:
null_value= 1;
return 0;
}
/*
Functions for spatial relations
*/
@ -453,6 +441,7 @@ longlong Item_func_spatial_rel::val_int()
String *res2= args[1]->val_str(&tmp_value2);
Geometry g1, g2;
MBR mbr1, mbr2;
const char *dummy;
if ((null_value= (args[0]->null_value ||
args[1]->null_value ||
@ -460,12 +449,11 @@ longlong Item_func_spatial_rel::val_int()
res1->length() - SRID_SIZE) ||
g2.create_from_wkb(res2->ptr() + SRID_SIZE,
res2->length() - SRID_SIZE) ||
g1.get_mbr(&mbr1) ||
g2.get_mbr(&mbr2))))
g1.get_mbr(&mbr1, &dummy) ||
g2.get_mbr(&mbr2, &dummy))))
return 0;
switch (spatial_rel)
{
switch (spatial_rel) {
case SP_CONTAINS_FUNC:
return mbr1.contains(&mbr2);
case SP_WITHIN_FUNC:
@ -490,6 +478,7 @@ longlong Item_func_spatial_rel::val_int()
return 0;
}
longlong Item_func_isempty::val_int()
{
String tmp;
@ -497,23 +486,25 @@ longlong Item_func_isempty::val_int()
return args[0]->null_value ? 1 : 0;
}
longlong Item_func_issimple::val_int()
{
String tmp;
String *wkb=args[0]->val_str(&tmp);
if ((null_value= (!wkb || args[0]->null_value )))
if ((null_value= (!wkb || args[0]->null_value)))
return 0;
/* TODO: Ramil or Holyfoot, add real IsSimple calculation */
return 0;
}
longlong Item_func_isclosed::val_int()
{
String tmp;
String *swkb= args[0]->val_str(&tmp);
Geometry geom;
int isclosed;
int isclosed= 0; // In case of error
null_value= (!swkb ||
args[0]->null_value ||
@ -529,23 +520,26 @@ longlong Item_func_isclosed::val_int()
Numerical functions
*/
longlong Item_func_dimension::val_int()
{
uint32 dim;
uint32 dim= 0; // In case of error
String *swkb= args[0]->val_str(&value);
Geometry geom;
const char *dummy;
null_value= (!swkb ||
args[0]->null_value ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE) ||
geom.dimension(&dim));
geom.dimension(&dim, &dummy));
return (longlong) dim;
}
longlong Item_func_numinteriorring::val_int()
{
uint32 num;
uint32 num= 0; // In case of error
String *swkb= args[0]->val_str(&value);
Geometry geom;
@ -557,9 +551,10 @@ longlong Item_func_numinteriorring::val_int()
return (longlong) num;
}
longlong Item_func_numgeometries::val_int()
{
uint32 num= 0;
uint32 num= 0; // In case of errors
String *swkb= args[0]->val_str(&value);
Geometry geom;
@ -571,9 +566,10 @@ longlong Item_func_numgeometries::val_int()
return (longlong) num;
}
longlong Item_func_numpoints::val_int()
{
uint32 num;
uint32 num= 0; // In case of errors
String *swkb= args[0]->val_str(&value);
Geometry geom;
@ -586,9 +582,10 @@ longlong Item_func_numpoints::val_int()
return (longlong) num;
}
double Item_func_x::val()
{
double res;
double res= 0.0; // In case of errors
String *swkb= args[0]->val_str(&value);
Geometry geom;
@ -600,9 +597,10 @@ double Item_func_x::val()
return res;
}
double Item_func_y::val()
{
double res;
double res= 0; // In case of errors
String *swkb= args[0]->val_str(&value);
Geometry geom;
@ -614,23 +612,25 @@ double Item_func_y::val()
return res;
}
double Item_func_area::val()
{
double res;
double res= 0; // In case of errors
String *swkb= args[0]->val_str(&value);
Geometry geom;
const char *dummy;
null_value= (!swkb ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE) ||
!GEOM_METHOD_PRESENT(geom, area) ||
geom.area(&res));
geom.area(&res, &dummy));
return res;
}
double Item_func_glength::val()
{
double res;
double res= 0; // In case of errors
String *swkb= args[0]->val_str(&value);
Geometry geom;
@ -650,8 +650,10 @@ longlong Item_func_srid::val_int()
null_value= (!swkb ||
geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
swkb->length() - SRID_SIZE));
uint32 res= uint4korr(swkb->ptr());
return (longlong) res;
if (null_value)
return 0;
return (longlong) (uint4korr(swkb->ptr()));
}
#endif /*HAVE_SPATIAL*/