summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <ram@mysql.r18.ru>2003-03-18 15:30:32 +0400
committerunknown <ram@mysql.r18.ru>2003-03-18 15:30:32 +0400
commit3ccd93c704556d9496b643e580dca8a9fcd2f4d4 (patch)
tree0e83c851e37727716fb38186353324ae67952771 /sql
parent1c1f407dd33951d44b4e2eaa30d4025998514e47 (diff)
downloadmariadb-git-3ccd93c704556d9496b643e580dca8a9fcd2f4d4.tar.gz
SRID support.
GeomertyFromWKB() function. SRID() function. ::store() methods for Field_geom. Code cleanup. myisam/sp_key.c: SRID support. mysql-test/r/gis.result: We should use GeometryFromWKB(). mysql-test/t/gis.test: We should use GeometryFromWKB(). sql/field.cc: SRID support. ::store() methods for Field_geom. Code cleanup. sql/field.h: SRID support. ::store() methods for Field_geom. Code cleanup. sql/item_cmpfunc.cc: SRID support. Code cleanup. sql/item_create.cc: Code cleanup. sql/item_create.h: Code cleanup. sql/item_func.cc: SRID support. Code cleanup. sql/item_func.h: SRID support. sql/item_strfunc.cc: SRID support. GeometryFromWKB() function. Code cleanup. sql/item_strfunc.h: SRID support. GeometryFromWKB() function. Code cleanup. sql/lex.h: GeometryFromWKB() function. SRID() function. sql/spatial.cc: Code cleanup. sql/spatial.h: Code cleanup. sql/sql_yacc.yy: Fix for xxxFromText() functions. GeometryFromWKB() function.
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc89
-rw-r--r--sql/field.h10
-rw-r--r--sql/item_cmpfunc.cc35
-rw-r--r--sql/item_create.cc74
-rw-r--r--sql/item_create.h64
-rw-r--r--sql/item_func.cc120
-rw-r--r--sql/item_func.h11
-rw-r--r--sql/item_strfunc.cc195
-rw-r--r--sql/item_strfunc.h16
-rw-r--r--sql/lex.h5
-rw-r--r--sql/spatial.cc18
-rw-r--r--sql/spatial.h1
-rw-r--r--sql/sql_yacc.yy21
13 files changed, 401 insertions, 258 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 0c17209003c..b5ed7885af5 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4525,7 +4525,7 @@ void Field_blob::get_key_image(char *buff,uint length,
MBR mbr;
Geometry gobj;
- gobj.create_from_wkb(blob,blob_length);
+ gobj.create_from_wkb(blob + SRID_SIZE, blob_length - SRID_SIZE);
gobj.get_mbr(&mbr);
float8store(buff, mbr.xmin);
float8store(buff+8, mbr.xmax);
@@ -4555,35 +4555,6 @@ void Field_blob::set_key_image(char *buff,uint length, CHARSET_INFO *cs)
}
-void Field_geom::get_key_image(char *buff,uint length,CHARSET_INFO *cs,
- imagetype type)
-{
- length-=HA_KEY_BLOB_LENGTH;
- ulong blob_length=get_length(ptr);
- char *blob;
- get_ptr(&blob);
-
- MBR mbr;
- Geometry gobj;
- gobj.create_from_wkb(blob,blob_length);
- gobj.get_mbr(&mbr);
- float8store(buff, mbr.xmin);
- float8store(buff+8, mbr.xmax);
- float8store(buff+16, mbr.ymin);
- float8store(buff+24, mbr.ymax);
- return;
-}
-
-void Field_geom::set_key_image(char *buff,uint length,CHARSET_INFO *cs)
-{
- Field_blob::set_key_image(buff, length, cs);
-}
-
-void Field_geom::sql_type(String &res) const
-{
- res.set("geometry", 8, &my_charset_latin1);
-}
-
int Field_blob::key_cmp(const byte *key_ptr, uint max_key_length)
{
char *blob1;
@@ -4776,6 +4747,64 @@ uint Field_blob::max_packed_col_length(uint max_length)
return (max_length > 255 ? 2 : 1)+max_length;
}
+
+void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
+ imagetype type)
+{
+ length-= HA_KEY_BLOB_LENGTH;
+ ulong blob_length= get_length(ptr);
+ char *blob;
+ get_ptr(&blob);
+
+ MBR mbr;
+ Geometry gobj;
+ gobj.create_from_wkb(blob + SRID_SIZE, blob_length - SRID_SIZE);
+ gobj.get_mbr(&mbr);
+ float8store(buff, mbr.xmin);
+ float8store(buff + 8, mbr.xmax);
+ float8store(buff + 16, mbr.ymin);
+ float8store(buff + 24, mbr.ymax);
+ return;
+}
+
+
+void Field_geom::set_key_image(char *buff, uint length, CHARSET_INFO *cs)
+{
+ Field_blob::set_key_image(buff, length, cs);
+}
+
+void Field_geom::sql_type(String &res) const
+{
+ res.set("geometry", 8, &my_charset_latin1);
+}
+
+
+int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
+{
+ if (!length)
+ {
+ bzero(ptr, Field_blob::pack_length());
+ }
+ else
+ {
+ // Should check given WKB
+ if (length < 4 + 1 + 4 + 8 + 8) // SRID + WKB_HEADER + X + Y
+ return 1;
+ uint32 wkb_type= uint4korr(from + 5);
+ if (wkb_type < 1 || wkb_type > 7)
+ return 1;
+ Field_blob::store_length(length);
+ if (table->copy_blobs || length <= MAX_FIELD_WIDTH)
+ { // Must make a copy
+ value.copy(from, length, cs);
+ from= value.ptr();
+ }
+ bmove(ptr + packlength, (char*) &from, sizeof(char*));
+ }
+ return 0;
+}
+
+
/****************************************************************************
** enum type.
** This is a string which only can have a selection of different values.
diff --git a/sql/field.h b/sql/field.h
index 37d194ac372..e14fa06f86a 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -843,9 +843,10 @@ public:
class Field_blob :public Field_str {
+ bool geom_flag;
+protected:
uint packlength;
String value; // For temporaries
- bool geom_flag;
public:
Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
@@ -855,7 +856,7 @@ public:
struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, table_arg, cs),
- packlength(3), geom_flag(true)
+ geom_flag(true), packlength(3)
{
flags|= BLOB_FLAG;
}
@@ -940,8 +941,11 @@ public:
:Field_blob(len_arg, maybe_null_arg, field_name_arg,
table_arg, &my_charset_bin) {}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY; }
- enum_field_types type() const { return FIELD_TYPE_GEOMETRY;}
+ enum_field_types type() const { return FIELD_TYPE_GEOMETRY; }
void sql_type(String &str) const;
+ int store(const char *to, uint length, CHARSET_INFO *charset);
+ int store(double nr) { return 1; }
+ int store(longlong nr) { return 1; }
void get_key_image(char *buff,uint length, CHARSET_INFO *cs,imagetype type);
void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 998b38513a9..1ae16827e0b 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -2200,17 +2200,19 @@ longlong Item_cond_xor::val_int()
longlong Item_func_spatial_rel::val_int()
{
- String *res1=args[0]->val_str(&tmp_value1);
- String *res2=args[1]->val_str(&tmp_value2);
+ String *res1= args[0]->val_str(&tmp_value1);
+ String *res2= args[1]->val_str(&tmp_value2);
Geometry g1, g2;
- MBR mbr1,mbr2;
-
- if ((null_value=(args[0]->null_value ||
- args[1]->null_value ||
- g1.create_from_wkb(res1->ptr(),res1->length()) ||
- g2.create_from_wkb(res2->ptr(),res2->length()) ||
- g1.get_mbr(&mbr1) ||
- g2.get_mbr(&mbr2))))
+ MBR mbr1, mbr2;
+
+ if ((null_value= (args[0]->null_value ||
+ args[1]->null_value ||
+ g1.create_from_wkb(res1->ptr() + SRID_SIZE,
+ res1->length() - SRID_SIZE) ||
+ g2.create_from_wkb(res2->ptr() + SRID_SIZE,
+ res2->length() - SRID_SIZE) ||
+ g1.get_mbr(&mbr1) ||
+ g2.get_mbr(&mbr2))))
return 0;
switch (spatial_rel)
@@ -2260,15 +2262,16 @@ longlong Item_func_issimple::val_int()
longlong Item_func_isclosed::val_int()
{
String tmp;
- String *wkb=args[0]->val_str(&tmp);
+ String *swkb= args[0]->val_str(&tmp);
Geometry geom;
int isclosed;
- null_value= (!wkb ||
- args[0]->null_value ||
- geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
- !GEOM_METHOD_PRESENT(geom,is_closed) ||
- geom.is_closed(&isclosed));
+ null_value= (!swkb ||
+ args[0]->null_value ||
+ geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
+ swkb->length() - SRID_SIZE) ||
+ !GEOM_METHOD_PRESENT(geom,is_closed) ||
+ geom.is_closed(&isclosed));
return (longlong) isclosed;
}
diff --git a/sql/item_create.cc b/sql/item_create.cc
index d90c708fc0f..eff0c8ab137 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -480,157 +480,157 @@ Item *create_func_quote(Item* a)
return new Item_func_quote(a);
}
-Item *create_func_geometry_from_text(Item* a)
+Item *create_func_as_text(Item *a)
{
- return new Item_func_geometry_from_text(a);
+ return new Item_func_as_text(a);
}
-Item *create_func_as_text(Item* a)
+Item *create_func_srid(Item *a)
{
- return new Item_func_as_text(a);
+ return new Item_func_srid(a);
}
-Item *create_func_startpoint(Item* a)
+Item *create_func_startpoint(Item *a)
{
return new Item_func_spatial_decomp(a, Item_func::SP_STARTPOINT);
}
-Item *create_func_endpoint(Item* a)
+Item *create_func_endpoint(Item *a)
{
return new Item_func_spatial_decomp(a, Item_func::SP_ENDPOINT);
}
-Item *create_func_exteriorring(Item* a)
+Item *create_func_exteriorring(Item *a)
{
return new Item_func_spatial_decomp(a, Item_func::SP_EXTERIORRING);
}
-Item *create_func_pointn(Item* a, Item* b)
+Item *create_func_pointn(Item *a, Item *b)
{
- return new Item_func_spatial_decomp_n(a,b,Item_func::SP_POINTN);
+ return new Item_func_spatial_decomp_n(a, b, Item_func::SP_POINTN);
}
-Item *create_func_interiorringn(Item* a, Item* b)
+Item *create_func_interiorringn(Item *a, Item *b)
{
- return new Item_func_spatial_decomp_n(a,b,Item_func::SP_INTERIORRINGN);
+ return new Item_func_spatial_decomp_n(a, b, Item_func::SP_INTERIORRINGN);
}
-Item *create_func_geometryn(Item* a, Item* b)
+Item *create_func_geometryn(Item *a, Item *b)
{
- return new Item_func_spatial_decomp_n(a,b,Item_func::SP_GEOMETRYN);
+ return new Item_func_spatial_decomp_n(a, b, Item_func::SP_GEOMETRYN);
}
-Item *create_func_centroid(Item* a)
+Item *create_func_centroid(Item *a)
{
return new Item_func_centroid(a);
}
-Item *create_func_envelope(Item* a)
+Item *create_func_envelope(Item *a)
{
return new Item_func_envelope(a);
}
-Item *create_func_equals(Item* a, Item* b)
+Item *create_func_equals(Item *a, Item *b)
{
return new Item_func_spatial_rel(a, b, Item_func::SP_EQUALS_FUNC);
}
-Item *create_func_disjoint(Item* a, Item* b)
+Item *create_func_disjoint(Item *a, Item *b)
{
return new Item_func_spatial_rel(a, b, Item_func::SP_DISJOINT_FUNC);
}
-Item *create_func_intersects(Item* a, Item* b)
+Item *create_func_intersects(Item *a, Item *b)
{
return new Item_func_spatial_rel(a, b, Item_func::SP_INTERSECTS_FUNC);
}
-Item *create_func_touches(Item* a, Item* b)
+Item *create_func_touches(Item *a, Item *b)
{
return new Item_func_spatial_rel(a, b, Item_func::SP_TOUCHES_FUNC);
}
-Item *create_func_crosses(Item* a, Item* b)
+Item *create_func_crosses(Item *a, Item *b)
{
return new Item_func_spatial_rel(a, b, Item_func::SP_CROSSES_FUNC);
}
-Item *create_func_within(Item* a, Item* b)
+Item *create_func_within(Item *a, Item *b)
{
return new Item_func_spatial_rel(a, b, Item_func::SP_WITHIN_FUNC);
}
-Item *create_func_contains(Item* a, Item* b)
+Item *create_func_contains(Item *a, Item *b)
{
return new Item_func_spatial_rel(a, b, Item_func::SP_CONTAINS_FUNC);
}
-Item *create_func_overlaps(Item* a, Item* b)
+Item *create_func_overlaps(Item *a, Item *b)
{
return new Item_func_spatial_rel(a, b, Item_func::SP_OVERLAPS_FUNC);
}
-Item *create_func_isempty(Item* a)
+Item *create_func_isempty(Item *a)
{
return new Item_func_isempty(a);
}
-Item *create_func_issimple(Item* a)
+Item *create_func_issimple(Item *a)
{
return new Item_func_issimple(a);
}
-Item *create_func_isclosed(Item* a)
+Item *create_func_isclosed(Item *a)
{
return new Item_func_isclosed(a);
}
-Item *create_func_geometry_type(Item* a)
+Item *create_func_geometry_type(Item *a)
{
return new Item_func_geometry_type(a);
}
-Item *create_func_dimension(Item* a)
+Item *create_func_dimension(Item *a)
{
return new Item_func_dimension(a);
}
-Item *create_func_x(Item* a)
+Item *create_func_x(Item *a)
{
return new Item_func_x(a);
}
-Item *create_func_y(Item* a)
+Item *create_func_y(Item *a)
{
return new Item_func_y(a);
}
-Item *create_func_numpoints(Item* a)
+Item *create_func_numpoints(Item *a)
{
return new Item_func_numpoints(a);
}
-Item *create_func_numinteriorring(Item* a)
+Item *create_func_numinteriorring(Item *a)
{
return new Item_func_numinteriorring(a);
}
-Item *create_func_numgeometries(Item* a)
+Item *create_func_numgeometries(Item *a)
{
return new Item_func_numgeometries(a);
}
-Item *create_func_area(Item* a)
+Item *create_func_area(Item *a)
{
return new Item_func_area(a);
}
-Item *create_func_glength(Item* a)
+Item *create_func_glength(Item *a)
{
return new Item_func_glength(a);
}
-Item *create_func_point(Item* a, Item* b)
+Item *create_func_point(Item *a, Item *b)
{
- return new Item_func_point(a,b);
+ return new Item_func_point(a, b);
}
diff --git a/sql/item_create.h b/sql/item_create.h
index 135bd6b02c4..14812c47cdc 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -102,40 +102,40 @@ Item *create_load_file(Item* a);
Item *create_func_is_free_lock(Item* a);
Item *create_func_quote(Item* a);
-Item *create_func_geometry_from_text(Item* a);
-Item *create_func_as_text(Item* a);
-Item *create_func_startpoint(Item* a);
-Item *create_func_endpoint(Item* a);
-Item *create_func_exteriorring(Item* a);
-Item *create_func_centroid(Item* a);
-Item *create_func_envelope(Item* a);
-Item *create_func_pointn(Item* a, Item* b);
-Item *create_func_interiorringn(Item* a, Item* b);
-Item *create_func_geometryn(Item* a, Item* b);
+Item *create_func_geometry_from_text(Item *a);
+Item *create_func_as_text(Item *a);
+Item *create_func_srid(Item *a);
+Item *create_func_startpoint(Item *a);
+Item *create_func_endpoint(Item *a);
+Item *create_func_exteriorring(Item *a);
+Item *create_func_centroid(Item *a);
+Item *create_func_envelope(Item *a);
+Item *create_func_pointn(Item *a, Item *b);
+Item *create_func_interiorringn(Item *a, Item *b);
+Item *create_func_geometryn(Item *a, Item *b);
-Item *create_func_equals(Item* a, Item* b);
-Item *create_func_disjoint(Item* a, Item* b);
-Item *create_func_intersects(Item* a, Item* b);
-Item *create_func_touches(Item* a, Item* b);
-Item *create_func_crosses(Item* a, Item* b);
-Item *create_func_within(Item* a, Item* b);
-Item *create_func_contains(Item* a, Item* b);
-Item *create_func_overlaps(Item* a, Item* b);
+Item *create_func_equals(Item *a, Item *b);
+Item *create_func_disjoint(Item *a, Item *b);
+Item *create_func_intersects(Item *a, Item *b);
+Item *create_func_touches(Item *a, Item *b);
+Item *create_func_crosses(Item *a, Item *b);
+Item *create_func_within(Item *a, Item *b);
+Item *create_func_contains(Item *a, Item *b);
+Item *create_func_overlaps(Item *a, Item *b);
-Item *create_func_isempty(Item* a);
-Item *create_func_issimple(Item* a);
-Item *create_func_isclosed(Item* a);
+Item *create_func_isempty(Item *a);
+Item *create_func_issimple(Item *a);
+Item *create_func_isclosed(Item *a);
-Item *create_func_geometry_type(Item* a);
-Item *create_func_dimension(Item* a);
-Item *create_func_x(Item* a);
-Item *create_func_y(Item* a);
-Item *create_func_area(Item* a);
-Item *create_func_glength(Item* a);
+Item *create_func_geometry_type(Item *a);
+Item *create_func_dimension(Item *a);
+Item *create_func_x(Item *a);
+Item *create_func_y(Item *a);
+Item *create_func_area(Item *a);
+Item *create_func_glength(Item *a);
-Item *create_func_numpoints(Item* a);
-Item *create_func_numinteriorring(Item* a);
-Item *create_func_numgeometries(Item* a);
-
-Item *create_func_point(Item* a,Item* b);
+Item *create_func_numpoints(Item *a);
+Item *create_func_numinteriorring(Item *a);
+Item *create_func_numgeometries(Item *a);
+Item *create_func_point(Item *a, Item *b);
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 2099a5a4ccf..6bd61a4e1e2 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2706,115 +2706,129 @@ longlong Item_func_is_free_lock::val_int()
longlong Item_func_dimension::val_int()
{
uint32 dim;
- String *wkb=args[0]->val_str(&value);
+ String *swkb= args[0]->val_str(&value);
Geometry geom;
- null_value= (!wkb ||
- args[0]->null_value ||
- geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
- geom.dimension(&dim));
-
+ null_value= (!swkb ||
+ args[0]->null_value ||
+ geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
+ swkb->length() - SRID_SIZE) ||
+ geom.dimension(&dim));
return (longlong) dim;
}
longlong Item_func_numinteriorring::val_int()
{
uint32 num;
- String *wkb=args[0]->val_str(&value);
+ String *swkb= args[0]->val_str(&value);
Geometry geom;
- null_value= (!wkb ||
- geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
- !GEOM_METHOD_PRESENT(geom,num_interior_ring) ||
+ null_value= (!swkb ||
+ geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
+ swkb->length() - SRID_SIZE) ||
+ !GEOM_METHOD_PRESENT(geom, num_interior_ring) ||
geom.num_interior_ring(&num));
-
return (longlong) num;
}
longlong Item_func_numgeometries::val_int()
{
- uint32 num=0;
- String *wkb=args[0]->val_str(&value);
+ uint32 num= 0;
+ String *swkb= args[0]->val_str(&value);
Geometry geom;
- null_value= (!wkb ||
- geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
- !GEOM_METHOD_PRESENT(geom,num_geometries) ||
- geom.num_geometries(&num));
-
+ null_value= (!swkb ||
+ geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
+ swkb->length() - SRID_SIZE) ||
+ !GEOM_METHOD_PRESENT(geom, num_geometries) ||
+ geom.num_geometries(&num));
return (longlong) num;
}
longlong Item_func_numpoints::val_int()
{
- uint32 num=0;
- String *wkb=args[0]->val_str(&value);
+ uint32 num;
+ String *swkb= args[0]->val_str(&value);
Geometry geom;
- null_value= (!wkb ||
- args[0]->null_value ||
- geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
- !GEOM_METHOD_PRESENT(geom,num_points) ||
- geom.num_points(&num));
-
+ null_value= (!swkb ||
+ args[0]->null_value ||
+ geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
+ swkb->length() - SRID_SIZE) ||
+ !GEOM_METHOD_PRESENT(geom, num_points) ||
+ geom.num_points(&num));
return (longlong) num;
}
double Item_func_x::val()
{
- double res=0;
- String *wkb=args[0]->val_str(&value);
+ double res;
+ String *swkb= args[0]->val_str(&value);
Geometry geom;
- null_value= (!wkb ||
- geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
- !GEOM_METHOD_PRESENT(geom,get_x) ||
- geom.get_x(&res));
-
+ null_value= (!swkb ||
+ geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
+ swkb->length() - SRID_SIZE) ||
+ !GEOM_METHOD_PRESENT(geom, get_x) ||
+ geom.get_x(&res));
return res;
}
double Item_func_y::val()
{
- double res=0;
- String *wkb=args[0]->val_str(&value);
+ double res;
+ String *swkb= args[0]->val_str(&value);
Geometry geom;
- null_value= (!wkb ||
- geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
- !GEOM_METHOD_PRESENT(geom,get_y) ||
- geom.get_y(&res));
-
+ null_value= (!swkb ||
+ geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
+ swkb->length() - SRID_SIZE) ||
+ !GEOM_METHOD_PRESENT(geom, get_y) ||
+ geom.get_y(&res));
return res;
}
double Item_func_area::val()
{
- double res=0;
- String *wkb=args[0]->val_str(&value);
+ double res;
+ String *swkb= args[0]->val_str(&value);
Geometry geom;
- null_value= (!wkb ||
- geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
- !GEOM_METHOD_PRESENT(geom,area) ||
- geom.area(&res));
-
+ null_value= (!swkb ||
+ geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
+ swkb->length() - SRID_SIZE) ||
+ !GEOM_METHOD_PRESENT(geom, area) ||
+ geom.area(&res));
return res;
}
double Item_func_glength::val()
{
- double res=0;
- String *wkb=args[0]->val_str(&value);
+ double res;
+ String *swkb= args[0]->val_str(&value);
Geometry geom;
- null_value= (!wkb ||
- geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
- !GEOM_METHOD_PRESENT(geom,length) ||
- geom.length(&res));
+ null_value= (!swkb ||
+ geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
+ swkb->length() - SRID_SIZE) ||
+ !GEOM_METHOD_PRESENT(geom, length) ||
+ geom.length(&res));
return res;
}
+
+
+longlong Item_func_srid::val_int()
+{
+ String *swkb= args[0]->val_str(&value);
+ Geometry geom;
+
+ null_value= (!swkb ||
+ geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
+ swkb->length() - SRID_SIZE));
+ uint32 res= uint4korr(swkb->ptr());
+ return (longlong) res;
+}
diff --git a/sql/item_func.h b/sql/item_func.h
index 860ddbbbadf..772b90fd38e 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1112,6 +1112,17 @@ public:
};
+class Item_func_srid: public Item_int_func
+{
+ String value;
+public:
+ Item_func_srid(Item *a): Item_int_func(a) {}
+ longlong val_int();
+ const char *func_name() const { return "srid"; }
+ void fix_length_and_dec() { max_length= 10; }
+};
+
+
class Item_func_match_nl :public Item_func_match
{
public:
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index f68a0dc9e73..320a4258a49 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -2509,10 +2509,19 @@ String *Item_func_geometry_from_text::val_str(String *str)
{
Geometry geom;
String arg_val;
- String *wkt = args[0]->val_str(&arg_val);
+ String *wkt= args[0]->val_str(&arg_val);
GTextReadStream trs(wkt->ptr(), wkt->length());
+ uint32 srid;
+ if ((arg_count == 2) && !args[1]->null_value)
+ srid= 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_wkt(&trs, str, 0))))
return 0;
return str;
@@ -2525,19 +2534,51 @@ void Item_func_geometry_from_text::fix_length_and_dec()
}
+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;
+
+ if ((arg_count == 2) && !args[1]->null_value)
+ srid= 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()))))
+ return 0;
+
+ str->append(*wkb);
+ return str;
+}
+
+
+void Item_func_geometry_from_wkb::fix_length_and_dec()
+{
+ max_length=MAX_BLOB_WIDTH;
+}
+
+
String *Item_func_as_text::val_str(String *str)
{
String arg_val;
- String *wkt = args[0]->val_str(&arg_val);
+ String *swkb= args[0]->val_str(&arg_val);
Geometry geom;
- if ((null_value=(args[0]->null_value ||
- geom.create_from_wkb(wkt->ptr(),wkt->length()))))
+ if ((null_value= (args[0]->null_value ||
+ geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
+ swkb->length() - SRID_SIZE))))
return 0;
str->length(0);
- if ((null_value=geom.as_wkt(str)))
+ if ((null_value= geom.as_wkt(str)))
return 0;
return str;
@@ -2550,11 +2591,12 @@ void Item_func_as_text::fix_length_and_dec()
String *Item_func_geometry_type::val_str(String *str)
{
- String *wkt = args[0]->val_str(str);
+ String *swkb= args[0]->val_str(str);
Geometry geom;
- if ((null_value=(args[0]->null_value ||
- geom.create_from_wkb(wkt->ptr(),wkt->length()))))
+ if ((null_value= (args[0]->null_value ||
+ 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),
@@ -2565,14 +2607,19 @@ String *Item_func_geometry_type::val_str(String *str)
String *Item_func_envelope::val_str(String *str)
{
- String *res = args[0]->val_str(str);
+ String *res= args[0]->val_str(str);
Geometry geom;
- if ((null_value = args[0]->null_value ||
- geom.create_from_wkb(res->ptr(),res->length())))
+ if ((null_value= args[0]->null_value ||
+ geom.create_from_wkb(res->ptr() + SRID_SIZE,
+ res->length() - SRID_SIZE)))
return 0;
+ uint32 srid= uint4korr(res->ptr());
+ if (res->reserve(SRID_SIZE, 512))
+ return 0;
res->length(0);
+ res->q_append(srid);
return (null_value= geom.envelope(res)) ? 0 : res;
}
@@ -2580,15 +2627,22 @@ String *Item_func_envelope::val_str(String *str)
String *Item_func_centroid::val_str(String *str)
{
String arg_val;
- String *wkb = args[0]->val_str(&arg_val);
+ String *swkb= args[0]->val_str(&arg_val);
Geometry geom;
- null_value = args[0]->null_value ||
- geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
- !GEOM_METHOD_PRESENT(geom,centroid) ||
- geom.centroid(str);
+ if ((null_value= args[0]->null_value ||
+ geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
+ swkb->length() - SRID_SIZE) ||
+ !GEOM_METHOD_PRESENT(geom, centroid)))
+ return 0;
- return null_value ? 0: str;
+ if (str->reserve(SRID_SIZE, 512))
+ return 0;
+ str->length(0);
+ uint32 srid= uint4korr(swkb->ptr());
+ str->q_append(srid);
+
+ return (null_value= geom.centroid(str)) ? 0 : str;
}
@@ -2599,15 +2653,20 @@ String *Item_func_centroid::val_str(String *str)
String *Item_func_spatial_decomp::val_str(String *str)
{
String arg_val;
- String *wkb = args[0]->val_str(&arg_val);
+ String *swkb= args[0]->val_str(&arg_val);
Geometry geom;
- if ((null_value = (args[0]->null_value ||
- geom.create_from_wkb(wkb->ptr(),wkb->length()))))
+ if ((null_value= (args[0]->null_value ||
+ geom.create_from_wkb(swkb->ptr() + SRID_SIZE,
+ swkb->length() - SRID_SIZE))))
return 0;
- null_value=1;
+ null_value= 1;
+ if (str->reserve(SRID_SIZE, 512))
+ return 0;
str->length(0);
+ uint32 srid= uint4korr(swkb->ptr());
+ str->q_append(srid);
switch(decomp_func)
{
case SP_STARTPOINT:
@@ -2628,7 +2687,7 @@ String *Item_func_spatial_decomp::val_str(String *str)
default:
goto ret;
}
- null_value=0;
+ null_value= 0;
ret:
return null_value ? 0 : str;
@@ -2638,28 +2697,30 @@ ret:
String *Item_func_spatial_decomp_n::val_str(String *str)
{
String arg_val;
- String *wkb = args[0]->val_str(&arg_val);
- long n = (long) args[1]->val_int();
+ String *swkb= args[0]->val_str(&arg_val);
+ long n= (long) args[1]->val_int();
Geometry geom;
- if ((null_value = (args[0]->null_value ||
- args[1]->null_value ||
- geom.create_from_wkb(wkb->ptr(),wkb->length()) )))
+ 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;
-
+ null_value= 1;
+ if (str->reserve(SRID_SIZE, 512))
+ return 0;
+ str->length(0);
+ uint32 srid= uint4korr(swkb->ptr());
+ str->q_append(srid);
switch(decomp_func_n)
{
case SP_POINTN:
- if (!GEOM_METHOD_PRESENT(geom,point_n) ||
- geom.point_n(n,str))
+ if (!GEOM_METHOD_PRESENT(geom,point_n) || geom.point_n(n,str))
goto ret;
break;
case SP_GEOMETRYN:
- if (!GEOM_METHOD_PRESENT(geom,geometry_n) ||
- geom.geometry_n(n,str))
+ if (!GEOM_METHOD_PRESENT(geom,geometry_n) || geom.geometry_n(n,str))
goto ret;
break;
@@ -2672,7 +2733,7 @@ String *Item_func_spatial_decomp_n::val_str(String *str)
default:
goto ret;
}
- null_value=0;
+ null_value= 0;
ret:
return null_value ? 0 : str;
@@ -2695,9 +2756,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 + 8 + 8))))
return 0;
str->length(0);
@@ -2724,19 +2785,19 @@ String *Item_func_spatial_collection::val_str(String *str)
String arg_value;
uint i;
- null_value=1;
+ null_value= 1;
str->length(0);
- if (str->reserve(9,512))
+ if (str->reserve(1 + 4 + 4, 512))
return 0;
- str->q_append((char)Geometry::wkbNDR);
- str->q_append((uint32)coll_type);
- str->q_append((uint32)arg_count);
+ str->q_append((char) Geometry::wkbNDR);
+ str->q_append((uint32) coll_type);
+ str->q_append((uint32) arg_count);
- for (i = 0; i < arg_count; ++i)
+ for (i= 0; i < arg_count; ++i)
{
- String *res = args[i]->val_str(&arg_value);
+ String *res= args[i]->val_str(&arg_value);
if (args[i]->null_value)
goto ret;
@@ -2747,16 +2808,16 @@ String *Item_func_spatial_collection::val_str(String *str)
any checkings for item types, so just copy them
into target collection
*/
- if ((null_value=(str->reserve(res->length(),512))))
+ if ((null_value= str->reserve(res->length(), 512)))
goto ret;
- str->q_append(res->ptr(),res->length());
+ str->q_append(res->ptr(), res->length());
}
else
{
enum Geometry::wkbType wkb_type;
uint32 len=res->length();
- const char *data=res->ptr()+1;
+ const char *data= res->ptr() + 1;
/*
In the case of named collection we must to
@@ -2767,8 +2828,8 @@ String *Item_func_spatial_collection::val_str(String *str)
if (len < 5)
goto ret;
wkb_type= (Geometry::wkbType) uint4korr(data);
- data+=4;
- len-=5;
+ data+= 4;
+ len-= 5;
if (wkb_type != item_type)
goto ret;
@@ -2779,17 +2840,17 @@ String *Item_func_spatial_collection::val_str(String *str)
if (len < WKB_HEADER_SIZE)
goto ret;
- data-=WKB_HEADER_SIZE;
- len+=WKB_HEADER_SIZE;
- if (str->reserve(len,512))
+ data-= WKB_HEADER_SIZE;
+ len+= WKB_HEADER_SIZE;
+ if (str->reserve(len, 512))
goto ret;
- str->q_append(data,len);
+ str->q_append(data, len);
break;
case Geometry::wkbLineString:
- if (str->reserve(POINT_DATA_SIZE,512))
+ if (str->reserve(POINT_DATA_SIZE, 512))
goto ret;
- str->q_append(data,POINT_DATA_SIZE);
+ str->q_append(data, POINT_DATA_SIZE);
break;
case Geometry::wkbPolygon:
@@ -2800,25 +2861,25 @@ String *Item_func_spatial_collection::val_str(String *str)
if (len < 4 + 2 * POINT_DATA_SIZE)
goto ret;
- uint32 llen=len;
- const char *ldata=data;
+ uint32 llen= len;
+ const char *ldata= data;
- n_points=uint4korr(data);
- data+=4;
- float8get(x1,data);
- data+=8;
- float8get(y1,data);
- data+=8;
+ n_points= uint4korr(data);
+ data+= 4;
+ float8get(x1, data);
+ data+= 8;
+ float8get(y1, data);
+ data+= 8;
- data+=(n_points-2) * POINT_DATA_SIZE;
+ data+= (n_points - 2) * POINT_DATA_SIZE;
- float8get(x2,data);
- float8get(y2,data+8);
+ float8get(x2, data);
+ float8get(y2, data + 8);
if ((x1 != x2) || (y1 != y2))
goto ret;
- if (str->reserve(llen,512))
+ if (str->reserve(llen, 512))
goto ret;
str->q_append(ldata, llen);
}
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 8bfa4317698..726008716c5 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -632,15 +632,28 @@ public:
Spatial functions
********************************************************/
+#define SRID_SIZE sizeof(uint32)
+
class Item_func_geometry_from_text :public Item_str_func
{
public:
Item_func_geometry_from_text(Item *a) :Item_str_func(a) {}
+ Item_func_geometry_from_text(Item *a, Item *srid) :Item_str_func(a, srid) {}
const char *func_name() const { return "geometryfromtext"; }
String *val_str(String *);
void fix_length_and_dec();
};
+class Item_func_geometry_from_wkb: public Item_str_func
+{
+public:
+ Item_func_geometry_from_wkb(Item *a) :Item_str_func(a) {}
+ Item_func_geometry_from_wkb(Item *a, Item *srid) :Item_str_func(a, srid) {}
+ const char *func_name() const { return "geometryfromwkb"; }
+ String *val_str(String *);
+ void fix_length_and_dec();
+};
+
class Item_func_as_text :public Item_str_func
{
public:
@@ -683,7 +696,8 @@ public:
class Item_func_point :public Item_str_func
{
public:
- Item_func_point(Item *a,Item *b) :Item_str_func(a,b) {}
+ Item_func_point(Item *a, Item *b) :Item_str_func(a, b) {}
+ Item_func_point(Item *a, Item *b, Item *srid) :Item_str_func(a, b, srid) {}
const char *func_name() const { return "point"; }
String *val_str(String *);
void fix_length_and_dec(){max_length=MAX_BLOB_WIDTH;}
diff --git a/sql/lex.h b/sql/lex.h
index 80f84628d27..9c50ab0119b 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -495,7 +495,9 @@ static SYMBOL sql_functions[] = {
{ "GEOMCOLLFROMTEXT", SYM(GEOMCOLLFROMTEXT),0,0},
{ "GEOMFROMTEXT", SYM(GEOMFROMTEXT),0,0},
{ "GEOMETRYFROMTEXT", SYM(GEOMFROMTEXT),0,0},
- { "GLENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_glength)},
+ { "GEOMFROMWKB", SYM(GEOMFROMWKB),0,0},
+ { "GEOMETRYFROMWKB", SYM(GEOMFROMWKB),0,0},
+ { "GLENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_glength)},
{ "GREATEST", SYM(GREATEST_SYM),0,0},
{ "GROUP_UNIQUE_USERS", SYM(GROUP_UNIQUE_USERS),0,0},
{ "HEX", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_hex)},
@@ -578,6 +580,7 @@ static SYMBOL sql_functions[] = {
{ "SOUNDEX", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_soundex)},
{ "SPACE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_space)},
{ "SQRT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sqrt)},
+ { "SRID", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_srid)},
{ "STARTPOINT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_startpoint)},
{ "STD", SYM(STD_SYM),0,0},
{ "STDDEV", SYM(STD_SYM),0,0},
diff --git a/sql/spatial.cc b/sql/spatial.cc
index 3345c2756e7..df28733782f 100644
--- a/sql/spatial.cc
+++ b/sql/spatial.cc
@@ -78,17 +78,17 @@ int Geometry::create_from_wkb(const char *data, uint32 data_len)
{
uint32 geom_type;
- if (data_len < 1+4)
+ if (data_len < 1 + 4)
return 1;
- data += sizeof(char);
-
+ data++;
//FIXME: check byte ordering
- geom_type = uint4korr(data);
- data += 4;
- m_vmt = find_class(geom_type);
- if (!m_vmt) return -1;
- m_data = data;
- m_data_end = data + data_len;
+ geom_type= uint4korr(data);
+ data+= 4;
+ m_vmt= find_class(geom_type);
+ if (!m_vmt)
+ return -1;
+ m_data= data;
+ m_data_end= data + data_len;
return 0;
}
diff --git a/sql/spatial.h b/sql/spatial.h
index 15e4f7353ed..d9c14afbe30 100644
--- a/sql/spatial.h
+++ b/sql/spatial.h
@@ -225,7 +225,6 @@ public:
wkbNDR = 1 /* Little Endian */
};
-
class GClassInfo
{
public:
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 76df8ba54b2..7749aea0040 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -458,6 +458,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token FROM_UNIXTIME
%token GEOMCOLLFROMTEXT
%token GEOMFROMTEXT
+%token GEOMFROMWKB
%token GEOMETRYCOLLECTION
%token GROUP_UNIQUE_USERS
%token HOUR_MINUTE_SYM
@@ -2256,7 +2257,11 @@ simple_expr:
| GEOMFROMTEXT '(' expr ')'
{ $$= new Item_func_geometry_from_text($3); }
| GEOMFROMTEXT '(' expr ',' expr ')'
- { $$= new Item_func_geometry_from_text($3); }
+ { $$= new Item_func_geometry_from_text($3, $5); }
+ | GEOMFROMWKB '(' expr ')'
+ { $$= new Item_func_geometry_from_wkb($3); }
+ | GEOMFROMWKB '(' expr ',' expr ')'
+ { $$= new Item_func_geometry_from_wkb($3, $5); }
| GEOMETRYCOLLECTION '(' expr_list ')'
{ $$= new Item_func_spatial_collection(* $3,
Geometry::wkbGeometryCollection,
@@ -2302,7 +2307,7 @@ simple_expr:
| GEOMCOLLFROMTEXT '(' expr ')'
{ $$= new Item_func_geometry_from_text($3); }
| GEOMCOLLFROMTEXT '(' expr ',' expr ')'
- { $$= new Item_func_geometry_from_text($3); }
+ { $$= new Item_func_geometry_from_text($3, $5); }
| GREATEST_SYM '(' expr ',' expr_list ')'
{ $5->push_front($3); $$= new Item_func_max(*$5); }
| LEAST_SYM '(' expr ',' expr_list ')'
@@ -2314,7 +2319,7 @@ simple_expr:
| LINEFROMTEXT '(' expr ')'
{ $$= new Item_func_geometry_from_text($3); }
| LINEFROMTEXT '(' expr ',' expr ')'
- { $$= new Item_func_geometry_from_text($3); }
+ { $$= new Item_func_geometry_from_text($3, $5); }
| MASTER_POS_WAIT '(' expr ',' expr ')'
{
$$= new Item_master_pos_wait($3, $5);
@@ -2337,15 +2342,15 @@ simple_expr:
| MLINEFROMTEXT '(' expr ')'
{ $$= new Item_func_geometry_from_text($3); }
| MLINEFROMTEXT '(' expr ',' expr ')'
- { $$= new Item_func_geometry_from_text($3); }
+ { $$= new Item_func_geometry_from_text($3, $5); }
| MPOINTFROMTEXT '(' expr ')'
{ $$= new Item_func_geometry_from_text($3); }
| MPOINTFROMTEXT '(' expr ',' expr ')'
- { $$= new Item_func_geometry_from_text($3); }
+ { $$= new Item_func_geometry_from_text($3, $5); }
| MPOLYFROMTEXT '(' expr ')'
{ $$= new Item_func_geometry_from_text($3); }
| MPOLYFROMTEXT '(' expr ',' expr ')'
- { $$= new Item_func_geometry_from_text($3); }
+ { $$= new Item_func_geometry_from_text($3, $5); }
| MULTIPOINT '(' expr_list ')'
{ $$= new Item_func_spatial_collection(* $3,
Geometry::wkbMultiPoint, Geometry::wkbPoint); }
@@ -2365,11 +2370,11 @@ simple_expr:
| POINTFROMTEXT '(' expr ')'
{ $$= new Item_func_geometry_from_text($3); }
| POINTFROMTEXT '(' expr ',' expr ')'
- { $$= new Item_func_geometry_from_text($3); }
+ { $$= new Item_func_geometry_from_text($3, $5); }
| POLYFROMTEXT '(' expr ')'
{ $$= new Item_func_geometry_from_text($3); }
| POLYFROMTEXT '(' expr ',' expr ')'
- { $$= new Item_func_geometry_from_text($3); }
+ { $$= new Item_func_geometry_from_text($3, $5); }
| POLYGON '(' expr_list ')'
{ $$= new Item_func_spatial_collection(* $3,
Geometry::wkbPolygon, Geometry::wkbLineString); }