Commit 031ac2a7 authored by ram@mysql.r18.ru's avatar ram@mysql.r18.ru

SRID support.

GeomertyFromWKB() function.
SRID() function.
::store() methods for Field_geom.
Code cleanup.
parent 34681a80
......@@ -47,7 +47,7 @@ uint sp_make_key(register MI_INFO *info, uint keynr, uchar *key,
dlen = _mi_calc_blob_length(keyseg->bit_start, pos);
memcpy_fixed(&dptr, pos + keyseg->bit_start, sizeof(char*));
sp_mbr_from_wkb(dptr, dlen, SPDIMS, mbr);
sp_mbr_from_wkb(dptr + 4, dlen - 4, SPDIMS, mbr); /* SRID */
for (i = 0, keyseg = keyinfo->seg; keyseg->type; keyseg++, i++)
{
......
......@@ -15,26 +15,26 @@ INSERT INTO pt VALUES
INSERT INTO ls VALUES
(105, LineFromText('LINESTRING(0 0,0 10,10 0)')),
(106, LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')),
(107, LineString(Point(10, 10), Point(40, 10)));
(107, GeometryFromWKB(LineString(Point(10, 10), Point(40, 10))));
INSERT INTO p VALUES
(108, PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),
(109, PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')),
(110, Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))));
(110, GeometryFromWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0)))));
INSERT INTO mpt VALUES
(111, MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')),
(112, MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')),
(113, MultiPoint(Point(3, 6), Point(4, 10)));
(113, GeometryFromWKB(MultiPoint(Point(3, 6), Point(4, 10))));
INSERT INTO mls VALUES
(114, MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')),
(115, MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')),
(116, MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7))));
(116, GeometryFromWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7)))));
INSERT INTO mp VALUES
(117, MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
(118, MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
(119, MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))));
(119, GeometryFromWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3))))));
INSERT INTO gc VALUES
(120, GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')),
(121, GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9))));
(121, GeometryFromWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))));
INSERT into geo SELECT * FROM pt;
INSERT into geo SELECT * FROM ls;
INSERT into geo SELECT * FROM p;
......
......@@ -24,32 +24,32 @@ INSERT INTO pt VALUES
INSERT INTO ls VALUES
(105, LineFromText('LINESTRING(0 0,0 10,10 0)')),
(106, LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')),
(107, LineString(Point(10, 10), Point(40, 10)));
(107, GeometryFromWKB(LineString(Point(10, 10), Point(40, 10))));
INSERT INTO p VALUES
(108, PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),
(109, PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')),
(110, Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))));
(110, GeometryFromWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0)))));
INSERT INTO mpt VALUES
(111, MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')),
(112, MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')),
(113, MultiPoint(Point(3, 6), Point(4, 10)));
(113, GeometryFromWKB(MultiPoint(Point(3, 6), Point(4, 10))));
INSERT INTO mls VALUES
(114, MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')),
(115, MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')),
(116, MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7))));
(116, GeometryFromWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7)))));
INSERT INTO mp VALUES
(117, MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
(118, MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
(119, MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))));
(119, GeometryFromWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3))))));
INSERT INTO gc VALUES
(120, GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')),
(121, GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9))));
(121, GeometryFromWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))));
INSERT into geo SELECT * FROM pt;
INSERT into geo SELECT * FROM ls;
......
......@@ -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.
......
......@@ -843,9 +843,10 @@ class Field_varstring :public Field_str {
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 @@ class Field_blob :public Field_str {
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 @@ class Field_geom :public Field_blob {
: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);
......
......@@ -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;
}
......@@ -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);
}
......@@ -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);
......@@ -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;
}
......@@ -1112,6 +1112,17 @@ class Item_func_glength :public Item_real_func
};
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:
......
......@@ -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 @@ String *Item_func_spatial_decomp::val_str(String *str)
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);
}
......
......@@ -632,15 +632,28 @@ class Item_func_collation :public Item_str_func
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 @@ class Item_func_envelope :public Item_str_func
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;}
......
......@@ -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},
......
......@@ -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;
}
......
......@@ -225,7 +225,6 @@ class Geometry
wkbNDR = 1 /* Little Endian */
};
class GClassInfo
{
public:
......
......@@ -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); }
......
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