MDEV-19923 Add type handlers for geometry sub-types

This commit is contained in:
Alexander Barkov 2019-07-03 13:05:15 +04:00
parent c1519d62d0
commit b511202335
28 changed files with 1262 additions and 889 deletions

View file

@ -1043,7 +1043,7 @@ DROP TABLE t1;
CREATE TABLE t1(f1 int); CREATE TABLE t1(f1 int);
INSERT INTO t1 values (0),(0); INSERT INTO t1 values (0),(0);
SELECT POLYGON((SELECT 1 FROM (SELECT 1 IN (GROUP_CONCAT(t1.f1)) FROM t1, t1 t GROUP BY t.f1 ) d)); SELECT POLYGON((SELECT 1 FROM (SELECT 1 IN (GROUP_CONCAT(t1.f1)) FROM t1, t1 t GROUP BY t.f1 ) d));
ERROR HY000: Illegal parameter data type int for operation 'geometrycollection' ERROR HY000: Illegal parameter data type int for operation 'polygon'
DROP TABLE t1; DROP TABLE t1;
# #
# Bug#58396 group_concat and explain extended are still crashy # Bug#58396 group_concat and explain extended are still crashy

View file

@ -3686,15 +3686,15 @@ SET TIMESTAMP=DEFAULT;
# MDEV-15702 Remove the use of STRING_ITEM from Item_func_date_format::fix_length_and_dec() # MDEV-15702 Remove the use of STRING_ITEM from Item_func_date_format::fix_length_and_dec()
# #
SELECT DATE_FORMAT('2001-01-01',POINT(1,1)); SELECT DATE_FORMAT('2001-01-01',POINT(1,1));
ERROR HY000: Illegal parameter data type geometry for operation 'date_format' ERROR HY000: Illegal parameter data type point for operation 'date_format'
SELECT DATE_FORMAT(POINT(1,1),'10'); SELECT DATE_FORMAT(POINT(1,1),'10');
ERROR HY000: Illegal parameter data type geometry for operation 'date_format' ERROR HY000: Illegal parameter data type point for operation 'date_format'
SELECT DATE_FORMAT('2001-01-01',ROW(1,1)); SELECT DATE_FORMAT('2001-01-01',ROW(1,1));
ERROR HY000: Illegal parameter data type row for operation 'date_format' ERROR HY000: Illegal parameter data type row for operation 'date_format'
SELECT DATE_FORMAT(ROW(1,1),'10'); SELECT DATE_FORMAT(ROW(1,1),'10');
ERROR HY000: Illegal parameter data type row for operation 'date_format' ERROR HY000: Illegal parameter data type row for operation 'date_format'
SELECT DATE_FORMAT('2001-01-01','%Y',POINT(1,1)); SELECT DATE_FORMAT('2001-01-01','%Y',POINT(1,1));
ERROR HY000: Illegal parameter data type geometry for operation 'date_format' ERROR HY000: Illegal parameter data type point for operation 'date_format'
SELECT DATE_FORMAT('2001-01-01','%Y',ROW(1,1)); SELECT DATE_FORMAT('2001-01-01','%Y',ROW(1,1));
ERROR HY000: Illegal parameter data type row for operation 'date_format' ERROR HY000: Illegal parameter data type row for operation 'date_format'
SELECT DATE_FORMAT('2001-01-01','%Y',@unknown_user_variable); SELECT DATE_FORMAT('2001-01-01','%Y',@unknown_user_variable);

View file

@ -357,15 +357,15 @@ SET SESSION debug_dbug="-d,Item_func_in";
# #
SET debug_dbug='+d,num_op'; SET debug_dbug='+d,num_op';
SELECT POINT(0,0)+POINT(0,0); SELECT POINT(0,0)+POINT(0,0);
ERROR HY000: Illegal parameter data types geometry and geometry for operation '+' ERROR HY000: Illegal parameter data types point and point for operation '+'
SELECT POINT(0,0)-POINT(0,0); SELECT POINT(0,0)-POINT(0,0);
ERROR HY000: Illegal parameter data types geometry and geometry for operation '-' ERROR HY000: Illegal parameter data types point and point for operation '-'
SELECT POINT(0,0)*POINT(0,0); SELECT POINT(0,0)*POINT(0,0);
ERROR HY000: Illegal parameter data types geometry and geometry for operation '*' ERROR HY000: Illegal parameter data types point and point for operation '*'
SELECT POINT(0,0)/POINT(0,0); SELECT POINT(0,0)/POINT(0,0);
ERROR HY000: Illegal parameter data types geometry and geometry for operation '/' ERROR HY000: Illegal parameter data types point and point for operation '/'
SELECT POINT(0,0) MOD POINT(0,0); SELECT POINT(0,0) MOD POINT(0,0);
ERROR HY000: Illegal parameter data types geometry and geometry for operation 'MOD' ERROR HY000: Illegal parameter data types point and point for operation 'MOD'
CREATE TABLE t1 AS SELECT CREATE TABLE t1 AS SELECT
POINT(0,0)+'0', POINT(0,0)+'0',
POINT(0,0)-'0', POINT(0,0)-'0',
@ -393,11 +393,11 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 AS SELECT '0'-POINT(0,0) LIMIT 0; CREATE TABLE t1 AS SELECT '0'-POINT(0,0) LIMIT 0;
ERROR HY000: Illegal parameter data types varchar and geometry for operation '-' ERROR HY000: Illegal parameter data types varchar and point for operation '-'
CREATE TABLE t1 AS SELECT '0'/POINT(0,0) LIMIT 0; CREATE TABLE t1 AS SELECT '0'/POINT(0,0) LIMIT 0;
ERROR HY000: Illegal parameter data types varchar and geometry for operation '/' ERROR HY000: Illegal parameter data types varchar and point for operation '/'
CREATE TABLE t1 AS SELECT '0' MOD POINT(0,0) LIMIT 0; CREATE TABLE t1 AS SELECT '0' MOD POINT(0,0) LIMIT 0;
ERROR HY000: Illegal parameter data types varchar and geometry for operation 'MOD' ERROR HY000: Illegal parameter data types varchar and point for operation 'MOD'
SET debug_dbug='-d,num_op'; SET debug_dbug='-d,num_op';
# #
# End of 10.3 tests # End of 10.3 tests
@ -418,9 +418,9 @@ Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (row) Note 1105 DBUG: [0] arg=1 handler=0 (row)
Note 1105 DBUG: [1] arg=2 handler=0 (row) Note 1105 DBUG: [1] arg=2 handler=0 (row)
Note 1105 DBUG: ROW(3 args) level=0 Note 1105 DBUG: ROW(3 args) level=0
Note 1105 DBUG: [0,0] handler=geometry Note 1105 DBUG: [0,0] handler=point
Note 1105 DBUG: [0,1] handler=geometry Note 1105 DBUG: [0,1] handler=point
Note 1105 DBUG: [0,2] handler=geometry Note 1105 DBUG: [0,2] handler=point
Note 1105 DBUG: => handler=geometry Note 1105 DBUG: => handler=geometry
Note 1105 DBUG: [1,0] handler=int Note 1105 DBUG: [1,0] handler=int
Note 1105 DBUG: [1,1] handler=int Note 1105 DBUG: [1,1] handler=int
@ -443,9 +443,9 @@ Note 1105 DBUG: [1,1] handler=row
Note 1105 DBUG: [1,2] handler=row Note 1105 DBUG: [1,2] handler=row
Note 1105 DBUG: => handler=row Note 1105 DBUG: => handler=row
Note 1105 DBUG: ROW(3 args) level=1 Note 1105 DBUG: ROW(3 args) level=1
Note 1105 DBUG: [0,0] handler=geometry Note 1105 DBUG: [0,0] handler=point
Note 1105 DBUG: [0,1] handler=geometry Note 1105 DBUG: [0,1] handler=point
Note 1105 DBUG: [0,2] handler=geometry Note 1105 DBUG: [0,2] handler=point
Note 1105 DBUG: => handler=geometry Note 1105 DBUG: => handler=geometry
Note 1105 DBUG: [1,0] handler=int Note 1105 DBUG: [1,0] handler=int
Note 1105 DBUG: [1,1] handler=int Note 1105 DBUG: [1,1] handler=int
@ -453,18 +453,18 @@ Note 1105 DBUG: [1,2] handler=int
Note 1105 DBUG: => handler=bigint Note 1105 DBUG: => handler=bigint
Note 1105 DBUG: types_compatible=yes bisect=no Note 1105 DBUG: types_compatible=yes bisect=no
SELECT (1,0) IN ((POINT(1,1),0),(0,0)); SELECT (1,0) IN ((POINT(1,1),0),(0,0));
ERROR HY000: Illegal parameter data types int and geometry for operation 'in' ERROR HY000: Illegal parameter data types int and point for operation 'in'
SHOW WARNINGS; SHOW WARNINGS;
Level Code Message Level Code Message
Note 1105 DBUG: [0] arg=1 handler=0 (row) Note 1105 DBUG: [0] arg=1 handler=0 (row)
Note 1105 DBUG: [1] arg=2 handler=0 (row) Note 1105 DBUG: [1] arg=2 handler=0 (row)
Note 1105 DBUG: ROW(3 args) level=0 Note 1105 DBUG: ROW(3 args) level=0
Note 1105 DBUG: [0,0] handler=int Note 1105 DBUG: [0,0] handler=int
Note 1105 DBUG: [0,1] handler=geometry Note 1105 DBUG: [0,1] handler=point
Note 1105 DBUG: [0,2] handler=int Note 1105 DBUG: [0,2] handler=int
Error 4078 Illegal parameter data types int and geometry for operation 'in' Error 4078 Illegal parameter data types int and point for operation 'in'
SELECT (1,(0,0)) IN ((1,(POINT(1,1),0)),(0,(0,0))); SELECT (1,(0,0)) IN ((1,(POINT(1,1),0)),(0,(0,0)));
ERROR HY000: Illegal parameter data types int and geometry for operation 'in' ERROR HY000: Illegal parameter data types int and point for operation 'in'
SHOW WARNINGS; SHOW WARNINGS;
Level Code Message Level Code Message
Note 1105 DBUG: [0] arg=1 handler=0 (row) Note 1105 DBUG: [0] arg=1 handler=0 (row)
@ -480,9 +480,9 @@ Note 1105 DBUG: [1,2] handler=row
Note 1105 DBUG: => handler=row Note 1105 DBUG: => handler=row
Note 1105 DBUG: ROW(3 args) level=1 Note 1105 DBUG: ROW(3 args) level=1
Note 1105 DBUG: [0,0] handler=int Note 1105 DBUG: [0,0] handler=int
Note 1105 DBUG: [0,1] handler=geometry Note 1105 DBUG: [0,1] handler=point
Note 1105 DBUG: [0,2] handler=int Note 1105 DBUG: [0,2] handler=int
Error 4078 Illegal parameter data types int and geometry for operation 'in' Error 4078 Illegal parameter data types int and point for operation 'in'
SET SESSION debug_dbug="-d,Predicant_to_list_comparator"; SET SESSION debug_dbug="-d,Predicant_to_list_comparator";
SET SESSION debug_dbug="-d,Item_func_in"; SET SESSION debug_dbug="-d,Item_func_in";
SET SESSION debug_dbug="-d,cmp_item"; SET SESSION debug_dbug="-d,cmp_item";

File diff suppressed because it is too large Load diff

View file

@ -2062,9 +2062,9 @@ values (1,2),(3,4,5);
ERROR HY000: The used table value constructor has a different number of values ERROR HY000: The used table value constructor has a different number of values
# illegal parameter data types in TVC # illegal parameter data types in TVC
values (1,point(1,1)),(1,1); values (1,point(1,1)),(1,1);
ERROR HY000: Illegal parameter data types geometry and int for operation 'TABLE VALUE CONSTRUCTOR' ERROR HY000: Illegal parameter data types point and int for operation 'TABLE VALUE CONSTRUCTOR'
values (1,point(1,1)+1); values (1,point(1,1)+1);
ERROR HY000: Illegal parameter data types geometry and int for operation '+' ERROR HY000: Illegal parameter data types point and int for operation '+'
# field reference in TVC # field reference in TVC
select * from (values (1), (b), (2)) as new_tvc; select * from (values (1), (b), (2)) as new_tvc;
ERROR HY000: Field reference 'b' can't be used in table value constructor ERROR HY000: Field reference 'b' can't be used in table value constructor

View file

@ -2060,9 +2060,9 @@ values (1,2),(3,4,5);
ERROR HY000: The used table value constructor has a different number of values ERROR HY000: The used table value constructor has a different number of values
# illegal parameter data types in TVC # illegal parameter data types in TVC
values (1,point(1,1)),(1,1); values (1,point(1,1)),(1,1);
ERROR HY000: Illegal parameter data types geometry and int for operation 'TABLE VALUE CONSTRUCTOR' ERROR HY000: Illegal parameter data types point and int for operation 'TABLE VALUE CONSTRUCTOR'
values (1,point(1,1)+1); values (1,point(1,1)+1);
ERROR HY000: Illegal parameter data types geometry and int for operation '+' ERROR HY000: Illegal parameter data types point and int for operation '+'
# field reference in TVC # field reference in TVC
select * from (values (1), (b), (2)) as new_tvc; select * from (values (1), (b), (2)) as new_tvc;
ERROR HY000: Field reference 'b' can't be used in table value constructor ERROR HY000: Field reference 'b' can't be used in table value constructor

View file

@ -458,7 +458,7 @@ explain extended select ST_issimple(MultiPoint(Point(3, 6), Point(4, 10))), ST_i
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings: Warnings:
Note 1003 select st_issimple(geometrycollection(point(3,6),point(4,10))) AS `ST_issimple(MultiPoint(Point(3, 6), Point(4, 10)))`,st_issimple(point(3,6)) AS `ST_issimple(Point(3, 6))` Note 1003 select st_issimple(multipoint(point(3,6),point(4,10))) AS `ST_issimple(MultiPoint(Point(3, 6), Point(4, 10)))`,st_issimple(point(3,6)) AS `ST_issimple(Point(3, 6))`
create table t1 (a geometry not null); create table t1 (a geometry not null);
insert into t1 values (ST_GeomFromText('Point(1 2)')); insert into t1 values (ST_GeomFromText('Point(1 2)'));
insert into t1 values ('Garbage'); insert into t1 values ('Garbage');
@ -1024,7 +1024,7 @@ f5 datetime YES NULL
drop view v1; drop view v1;
drop table t1; drop table t1;
SELECT MultiPoint(12345,''); SELECT MultiPoint(12345,'');
ERROR HY000: Illegal parameter data type int for operation 'geometrycollection' ERROR HY000: Illegal parameter data type int for operation 'multipoint'
SELECT 1 FROM (SELECT GREATEST(1,GEOMETRYCOLLECTION('00000','00000')) b FROM DUAL) AS d WHERE (LINESTRING(d.b)); SELECT 1 FROM (SELECT GREATEST(1,GEOMETRYCOLLECTION('00000','00000')) b FROM DUAL) AS d WHERE (LINESTRING(d.b));
ERROR HY000: Illegal parameter data type varchar for operation 'geometrycollection' ERROR HY000: Illegal parameter data type varchar for operation 'geometrycollection'
# #

View file

@ -287,7 +287,7 @@ affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0 info: Records: 0 Duplicates: 0 Warnings: 0
SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
CREATE TEMPORARY TABLE temp_tab AS SELECT * FROM tab where c1 = c2; CREATE TEMPORARY TABLE temp_tab AS SELECT * FROM tab where c1 = c2;
ERROR HY000: Illegal parameter data types int and geometry for operation '=' ERROR HY000: Illegal parameter data types int and point for operation '='
SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
CREATE TEMPORARY TABLE temp_tab AS SELECT * FROM tab; CREATE TEMPORARY TABLE temp_tab AS SELECT * FROM tab;
INSERT INTO temp_tab SELECT * FROM tab; INSERT INTO temp_tab SELECT * FROM tab;
@ -790,13 +790,13 @@ DROP TABLE t1;
create table t1 (p point not null default if(unix_timestamp()>10,POINT(1,1),LineString(Point(0,0),Point(1,1)))) ENGINE=innodb; create table t1 (p point not null default if(unix_timestamp()>10,POINT(1,1),LineString(Point(0,0),Point(1,1)))) ENGINE=innodb;
set timestamp=10; set timestamp=10;
insert into t1 values(default); insert into t1 values(default);
ERROR 22007: Incorrect POINT value: 'GEOMETRYCOLLECTION' for column `test`.`t1`.`p` at row 1 ERROR 22007: Incorrect POINT value: 'LINESTRING' for column `test`.`t1`.`p` at row 1
drop table t1; drop table t1;
SET timestamp=default; SET timestamp=default;
create table t1 (p point not null default if(unix_timestamp()>10,POINT(1,1),LineString(Point(0,0),Point(1,1)))) ENGINE=innodb; create table t1 (p point not null default if(unix_timestamp()>10,POINT(1,1),LineString(Point(0,0),Point(1,1)))) ENGINE=innodb;
set timestamp=10; set timestamp=10;
alter table t1 add column i int; alter table t1 add column i int;
ERROR 22007: Incorrect POINT value: 'GEOMETRYCOLLECTION' for column `test`.`t1`.`p` at row 1 ERROR 22007: Incorrect POINT value: 'LINESTRING' for column `test`.`t1`.`p` at row 1
drop table t1; drop table t1;
SET timestamp=default; SET timestamp=default;
CREATE OR REPLACE TABLE t1 (a INT) ENGINE=InnoDB; CREATE OR REPLACE TABLE t1 (a INT) ENGINE=InnoDB;

View file

@ -1244,7 +1244,7 @@ Table Op Msg_type Msg_text
test.tab check status OK test.tab check status OK
DROP TABLE tab; DROP TABLE tab;
CREATE TABLE tab(c1 POINT NOT NULL,CONSTRAINT tab_const check(c1 > 0) ) ENGINE=InnoDB; CREATE TABLE tab(c1 POINT NOT NULL,CONSTRAINT tab_const check(c1 > 0) ) ENGINE=InnoDB;
ERROR HY000: Illegal parameter data types geometry and int for operation '>' ERROR HY000: Illegal parameter data types point and int for operation '>'
CREATE TABLE tab(c1 POINT NOT NULL,CONSTRAINT tab_const check(CAST(c1 AS BINARY) > 0) ) ENGINE=InnoDB; CREATE TABLE tab(c1 POINT NOT NULL,CONSTRAINT tab_const check(CAST(c1 AS BINARY) > 0) ) ENGINE=InnoDB;
CREATE SPATIAL INDEX idx1 ON tab(c1) ; CREATE SPATIAL INDEX idx1 ON tab(c1) ;
SHOW CREATE TABLE tab; SHOW CREATE TABLE tab;

View file

@ -458,7 +458,7 @@ explain extended select ST_issimple(MultiPoint(Point(3, 6), Point(4, 10))), ST_i
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings: Warnings:
Note 1003 select st_issimple(geometrycollection(point(3,6),point(4,10))) AS `ST_issimple(MultiPoint(Point(3, 6), Point(4, 10)))`,st_issimple(point(3,6)) AS `ST_issimple(Point(3, 6))` Note 1003 select st_issimple(multipoint(point(3,6),point(4,10))) AS `ST_issimple(MultiPoint(Point(3, 6), Point(4, 10)))`,st_issimple(point(3,6)) AS `ST_issimple(Point(3, 6))`
create table t1 (a geometry not null); create table t1 (a geometry not null);
insert into t1 values (ST_GeomFromText('Point(1 2)')); insert into t1 values (ST_GeomFromText('Point(1 2)'));
insert into t1 values ('Garbage'); insert into t1 values ('Garbage');
@ -1020,7 +1020,7 @@ f5 datetime YES NULL
drop view v1; drop view v1;
drop table t1; drop table t1;
SELECT MultiPoint(12345,''); SELECT MultiPoint(12345,'');
ERROR HY000: Illegal parameter data type int for operation 'geometrycollection' ERROR HY000: Illegal parameter data type int for operation 'multipoint'
SELECT 1 FROM (SELECT GREATEST(1,GEOMETRYCOLLECTION('00000','00000')) b FROM DUAL) AS d WHERE (LINESTRING(d.b)); SELECT 1 FROM (SELECT GREATEST(1,GEOMETRYCOLLECTION('00000','00000')) b FROM DUAL) AS d WHERE (LINESTRING(d.b));
ERROR HY000: Illegal parameter data type varchar for operation 'geometrycollection' ERROR HY000: Illegal parameter data type varchar for operation 'geometrycollection'
# #

View file

@ -8884,32 +8884,8 @@ end_of_record:
void Field_geom::sql_type(String &res) const void Field_geom::sql_type(String &res) const
{ {
CHARSET_INFO *cs= &my_charset_latin1; CHARSET_INFO *cs= &my_charset_latin1;
switch (geom_type) const Name tmp= m_type_handler->name();
{ res.set(tmp.ptr(), tmp.length(), cs);
case GEOM_POINT:
res.set(STRING_WITH_LEN("point"), cs);
break;
case GEOM_LINESTRING:
res.set(STRING_WITH_LEN("linestring"), cs);
break;
case GEOM_POLYGON:
res.set(STRING_WITH_LEN("polygon"), cs);
break;
case GEOM_MULTIPOINT:
res.set(STRING_WITH_LEN("multipoint"), cs);
break;
case GEOM_MULTILINESTRING:
res.set(STRING_WITH_LEN("multilinestring"), cs);
break;
case GEOM_MULTIPOLYGON:
res.set(STRING_WITH_LEN("multipolygon"), cs);
break;
case GEOM_GEOMETRYCOLLECTION:
res.set(STRING_WITH_LEN("geometrycollection"), cs);
break;
default:
res.set(STRING_WITH_LEN("geometry"), cs);
}
} }
@ -8954,9 +8930,9 @@ int Field_geom::store(const char *from, size_t length, CHARSET_INFO *cs)
wkb_type > (uint32) Geometry::wkb_last) wkb_type > (uint32) Geometry::wkb_last)
goto err; goto err;
if (geom_type != Field::GEOM_GEOMETRY && if (m_type_handler->geometry_type() != Type_handler_geometry::GEOM_GEOMETRY &&
geom_type != Field::GEOM_GEOMETRYCOLLECTION && m_type_handler->geometry_type() != Type_handler_geometry::GEOM_GEOMETRYCOLLECTION &&
(uint32) geom_type != wkb_type) (uint32) m_type_handler->geometry_type() != wkb_type)
{ {
const char *db= table->s->db.str; const char *db= table->s->db.str;
const char *tab_name= table->s->table_name.str; const char *tab_name= table->s->table_name.str;
@ -8967,7 +8943,7 @@ int Field_geom::store(const char *from, size_t length, CHARSET_INFO *cs)
tab_name= ""; tab_name= "";
my_error(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, MYF(0), my_error(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, MYF(0),
Geometry::ci_collection[geom_type]->m_name.str, Geometry::ci_collection[m_type_handler->geometry_type()]->m_name.str,
Geometry::ci_collection[wkb_type]->m_name.str, Geometry::ci_collection[wkb_type]->m_name.str,
db, tab_name, field_name.str, db, tab_name, field_name.str,
(ulong) table->in_use->get_stmt_da()-> (ulong) table->in_use->get_stmt_da()->
@ -8994,25 +8970,19 @@ err_exit:
return -1; return -1;
} }
Field::geometry_type Field_geom::geometry_type_merge(geometry_type a,
geometry_type b)
{
if (a == b)
return a;
return Field::GEOM_GEOMETRY;
}
bool Field_geom::is_equal(const Column_definition &new_field) const bool Field_geom::is_equal(const Column_definition &new_field) const
{ {
return new_field.type_handler() == type_handler() && /*
/* - Allow ALTER..INPLACE to supertype (GEOMETRY),
- Allow ALTER..INPLACE to supertype (GEOMETRY), e.g. POINT to GEOMETRY or POLYGON to GEOMETRY.
e.g. POINT to GEOMETRY or POLYGON to GEOMETRY. - Allow ALTER..INPLACE to the same geometry type: POINT -> POINT
- Allow ALTER..INPLACE to the same geometry type: POINT -> POINT */
*/ if (new_field.type_handler() == m_type_handler)
(new_field.geom_type == geom_type || return true;
new_field.geom_type == GEOM_GEOMETRY); const Type_handler_geometry *gth=
dynamic_cast<const Type_handler_geometry*>(new_field.type_handler());
return gth && gth->is_binary_compatible_geom_super_type_for(m_type_handler);
} }
@ -10360,7 +10330,7 @@ void Column_definition::create_length_to_internal_length_newdecimal()
} }
bool check_expression(Virtual_column_info *vcol, LEX_CSTRING *name, bool check_expression(Virtual_column_info *vcol, const LEX_CSTRING *name,
enum_vcol_info_type type) enum_vcol_info_type type)
{ {
@ -10694,7 +10664,6 @@ Column_definition_attributes::Column_definition_attributes(const Field *field)
interval(NULL), interval(NULL),
charset(field->charset()), // May be NULL ptr charset(field->charset()), // May be NULL ptr
srid(0), srid(0),
geom_type(Field::GEOM_GEOMETRY),
pack_flag(0) pack_flag(0)
{} {}
@ -10926,6 +10895,19 @@ Column_definition::set_compressed_deprecated_column_attribute(THD *thd,
} }
bool Column_definition::check_vcol_for_key(THD *thd) const
{
if (vcol_info && (vcol_info->flags & VCOL_NOT_STRICTLY_DETERMINISTIC))
{
/* use check_expression() to report an error */
check_expression(vcol_info, &field_name, VCOL_GENERATED_STORED);
DBUG_ASSERT(thd->is_error());
return true;
}
return false;
}
Send_field::Send_field(THD *thd, Item *item) Send_field::Send_field(THD *thd, Item *item)
{ {
item->make_send_field(thd, this); item->make_send_field(thd, this);

View file

@ -721,12 +721,6 @@ public:
TIMESTAMP_DNUN_FIELD=23, // TIMESTAMP DEFAULT NOW() ON UPDATE NOW() TIMESTAMP_DNUN_FIELD=23, // TIMESTAMP DEFAULT NOW() ON UPDATE NOW()
TMYSQL_COMPRESSED= 24, // Compatibility with TMySQL TMYSQL_COMPRESSED= 24, // Compatibility with TMySQL
}; };
enum geometry_type
{
GEOM_GEOMETRY = 0, GEOM_POINT = 1, GEOM_LINESTRING = 2, GEOM_POLYGON = 3,
GEOM_MULTIPOINT = 4, GEOM_MULTILINESTRING = 5, GEOM_MULTIPOLYGON = 6,
GEOM_GEOMETRYCOLLECTION = 7
};
enum imagetype { itRAW, itMBR}; enum imagetype { itRAW, itMBR};
utype unireg_check; utype unireg_check;
@ -1589,12 +1583,6 @@ public:
{ {
return field_length / charset()->mbmaxlen; return field_length / charset()->mbmaxlen;
} }
virtual geometry_type get_geometry_type() const
{
/* shouldn't get here. */
DBUG_ASSERT(0);
return GEOM_GEOMETRY;
}
ha_storage_media field_storage_type() const ha_storage_media field_storage_type() const
{ {
@ -4238,9 +4226,10 @@ private:
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
class Field_geom :public Field_blob { class Field_geom :public Field_blob
{
const Type_handler_geometry *m_type_handler;
public: public:
enum geometry_type geom_type;
uint srid; uint srid;
uint precision; uint precision;
enum storage_type { GEOM_STORAGE_WKB= 0, GEOM_STORAGE_BINARY= 1}; enum storage_type { GEOM_STORAGE_WKB= 0, GEOM_STORAGE_BINARY= 1};
@ -4249,17 +4238,27 @@ public:
Field_geom(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, Field_geom(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg, enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
TABLE_SHARE *share, uint blob_pack_length, TABLE_SHARE *share, uint blob_pack_length,
enum geometry_type geom_type_arg, uint field_srid) const Type_handler_geometry *gth,
uint field_srid)
:Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, :Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
field_name_arg, share, blob_pack_length, &my_charset_bin) field_name_arg, share, blob_pack_length, &my_charset_bin),
{ geom_type= geom_type_arg; srid= field_srid; } m_type_handler(gth)
{ srid= field_srid; }
enum_conv_type rpl_conv_type_from(const Conv_source &source, enum_conv_type rpl_conv_type_from(const Conv_source &source,
const Relay_log_info *rli, const Relay_log_info *rli,
const Conv_param &param) const; const Conv_param &param) const;
enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; }
const Type_handler *type_handler() const const Type_handler *type_handler() const
{ {
return &type_handler_geometry; return m_type_handler;
}
const Type_handler_geometry *type_handler_geom() const
{
return m_type_handler;
}
void set_type_handler(const Type_handler_geometry *th)
{
m_type_handler= th;
} }
enum_field_types type() const enum_field_types type() const
{ {
@ -4284,17 +4283,18 @@ public:
void sql_type(String &str) const; void sql_type(String &str) const;
Copy_func *get_copy_func(const Field *from) const Copy_func *get_copy_func(const Field *from) const
{ {
if (type_handler() == from->type_handler() && const Type_handler_geometry *fth=
(geom_type == GEOM_GEOMETRY || dynamic_cast<const Type_handler_geometry*>(from->type_handler());
geom_type == static_cast<const Field_geom*>(from)->geom_type)) if (fth && m_type_handler->is_binary_compatible_geom_super_type_for(fth))
return get_identical_copy_func(); return get_identical_copy_func();
return do_conv_blob; return do_conv_blob;
} }
bool memcpy_field_possible(const Field *from) const bool memcpy_field_possible(const Field *from) const
{ {
return type_handler() == from->type_handler() && const Type_handler_geometry *fth=
(geom_type == GEOM_GEOMETRY || dynamic_cast<const Type_handler_geometry*>(from->type_handler());
geom_type == static_cast<const Field_geom*>(from)->geom_type) && return fth &&
m_type_handler->is_binary_compatible_geom_super_type_for(fth) &&
!table->copy_blobs; !table->copy_blobs;
} }
bool is_equal(const Column_definition &new_field) const; bool is_equal(const Column_definition &new_field) const;
@ -4325,8 +4325,6 @@ public:
bool load_data_set_null(THD *thd); bool load_data_set_null(THD *thd);
bool load_data_set_no_data(THD *thd, bool fixed_format); bool load_data_set_no_data(THD *thd, bool fixed_format);
geometry_type get_geometry_type() const { return geom_type; };
static geometry_type geometry_type_merge(geometry_type, geometry_type);
uint get_srid() { return srid; } uint get_srid() { return srid; }
void print_key_value(String *out, uint32 length) void print_key_value(String *out, uint32 length)
{ {
@ -4723,7 +4721,6 @@ public:
const TYPELIB *interval; // Which interval to use const TYPELIB *interval; // Which interval to use
CHARSET_INFO *charset; CHARSET_INFO *charset;
uint32 srid; uint32 srid;
Field::geometry_type geom_type;
uint pack_flag; uint pack_flag;
Column_definition_attributes() Column_definition_attributes()
:length(0), :length(0),
@ -4731,7 +4728,6 @@ public:
interval(NULL), interval(NULL),
charset(&my_charset_bin), charset(&my_charset_bin),
srid(0), srid(0),
geom_type(Field::GEOM_GEOMETRY),
pack_flag(0) pack_flag(0)
{ } { }
Column_definition_attributes(const Field *field); Column_definition_attributes(const Field *field);
@ -5009,7 +5005,6 @@ public:
interval= other.interval; interval= other.interval;
charset= other.charset; charset= other.charset;
srid= other.srid; srid= other.srid;
geom_type= other.geom_type;
pack_flag= other.pack_flag; pack_flag= other.pack_flag;
} }
@ -5027,6 +5022,8 @@ public:
{ compression_method_ptr= compression_method_arg; } { compression_method_ptr= compression_method_arg; }
Compression_method *compression_method() const Compression_method *compression_method() const
{ return compression_method_ptr; } { return compression_method_ptr; }
bool check_vcol_for_key(THD *thd) const;
}; };
@ -5363,7 +5360,7 @@ enum_field_types get_blob_type_from_length(ulong length);
int set_field_to_null(Field *field); int set_field_to_null(Field *field);
int set_field_to_null_with_conversions(Field *field, bool no_conversions); int set_field_to_null_with_conversions(Field *field, bool no_conversions);
int convert_null_to_field_value_or_error(Field *field); int convert_null_to_field_value_or_error(Field *field);
bool check_expression(Virtual_column_info *vcol, LEX_CSTRING *name, bool check_expression(Virtual_column_info *vcol, const LEX_CSTRING *name,
enum_vcol_info_type type); enum_vcol_info_type type);
/* /*

View file

@ -3877,7 +3877,6 @@ void Item_param::sync_clones()
c->null_value= null_value; c->null_value= null_value;
c->Type_std_attributes::operator=(*this); c->Type_std_attributes::operator=(*this);
c->Type_handler_hybrid_field_type::operator=(*this); c->Type_handler_hybrid_field_type::operator=(*this);
c->Type_geometry_attributes::operator=(*this);
c->state= state; c->state= state;
c->m_empty_string_is_null= m_empty_string_is_null; c->m_empty_string_is_null= m_empty_string_is_null;

View file

@ -2208,14 +2208,6 @@ public:
is_expensive_cache= walk(&Item::is_expensive_processor, 0, NULL); is_expensive_cache= walk(&Item::is_expensive_processor, 0, NULL);
return MY_TEST(is_expensive_cache); return MY_TEST(is_expensive_cache);
} }
virtual Field::geometry_type get_geometry_type() const
{ return Field::GEOM_GEOMETRY; };
uint uint_geometry_type() const
{ return get_geometry_type(); }
void set_geometry_type(uint type)
{
DBUG_ASSERT(0);
}
String *check_well_formed_result(String *str, bool send_error= 0); String *check_well_formed_result(String *str, bool send_error= 0);
bool eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs); bool eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs);
bool too_big_for_varchar() const bool too_big_for_varchar() const
@ -2423,56 +2415,6 @@ public:
}; };
class Type_geometry_attributes
{
uint m_geometry_type;
static const uint m_geometry_type_unknown= Field::GEOM_GEOMETRYCOLLECTION + 1;
void copy(const Type_handler *handler, const Type_all_attributes *gattr)
{
// Ignore implicit NULLs
m_geometry_type= handler == &type_handler_geometry ?
gattr->uint_geometry_type() :
m_geometry_type_unknown;
}
public:
Type_geometry_attributes()
:m_geometry_type(m_geometry_type_unknown)
{ }
Type_geometry_attributes(const Type_handler *handler,
const Type_all_attributes *gattr)
:m_geometry_type(m_geometry_type_unknown)
{
copy(handler, gattr);
}
void join(const Item *item)
{
// Ignore implicit NULLs
if (m_geometry_type == m_geometry_type_unknown)
copy(item->type_handler(), item);
else if (item->type_handler() == &type_handler_geometry)
{
m_geometry_type=
Field_geom::geometry_type_merge((Field_geom::geometry_type)
m_geometry_type,
(Field_geom::geometry_type)
item->uint_geometry_type());
}
}
Field::geometry_type get_geometry_type() const
{
return m_geometry_type == m_geometry_type_unknown ?
Field::GEOM_GEOMETRY :
(Field::geometry_type) m_geometry_type;
}
void set_geometry_type(uint type)
{
DBUG_ASSERT(type <= m_geometry_type_unknown);
m_geometry_type= type;
}
};
/** /**
Compare two Items for List<Item>::add_unique() Compare two Items for List<Item>::add_unique()
*/ */
@ -3465,11 +3407,6 @@ public:
DBUG_ASSERT(fixed); DBUG_ASSERT(fixed);
return field->table->pos_in_table_list->outer_join; return field->table->pos_in_table_list->outer_join;
} }
Field::geometry_type get_geometry_type() const
{
DBUG_ASSERT(field_type() == MYSQL_TYPE_GEOMETRY);
return field->get_geometry_type();
}
bool check_index_dependence(void *arg); bool check_index_dependence(void *arg);
friend class Item_default_value; friend class Item_default_value;
friend class Item_insert_value; friend class Item_insert_value;
@ -3645,8 +3582,7 @@ public:
class Item_param :public Item_basic_value, class Item_param :public Item_basic_value,
private Settable_routine_parameter, private Settable_routine_parameter,
public Rewritable_query_parameter, public Rewritable_query_parameter,
private Type_handler_hybrid_field_type, private Type_handler_hybrid_field_type
public Type_geometry_attributes
{ {
/* /*
NO_VALUE is a special value meaning that the parameter has not been NO_VALUE is a special value meaning that the parameter has not been
@ -3805,12 +3741,6 @@ public:
const Type_handler *type_handler() const const Type_handler *type_handler() const
{ return Type_handler_hybrid_field_type::type_handler(); } { return Type_handler_hybrid_field_type::type_handler(); }
Field::geometry_type get_geometry_type() const
{ return Type_geometry_attributes::get_geometry_type(); };
void set_geometry_type(uint type)
{ Type_geometry_attributes::set_geometry_type(type); }
Item_param(THD *thd, const LEX_CSTRING *name_arg, Item_param(THD *thd, const LEX_CSTRING *name_arg,
uint pos_in_query_arg, uint len_in_query_arg); uint pos_in_query_arg, uint len_in_query_arg);
@ -6958,8 +6888,7 @@ public:
single SP/PS execution. single SP/PS execution.
*/ */
class Item_type_holder: public Item, class Item_type_holder: public Item,
public Type_handler_hybrid_field_type, public Type_handler_hybrid_field_type
public Type_geometry_attributes
{ {
protected: protected:
const TYPELIB *enum_set_typelib; const TYPELIB *enum_set_typelib;
@ -6979,7 +6908,6 @@ public:
bool maybe_null_arg) bool maybe_null_arg)
:Item(thd), :Item(thd),
Type_handler_hybrid_field_type(handler), Type_handler_hybrid_field_type(handler),
Type_geometry_attributes(handler, attr),
enum_set_typelib(attr->get_typelib()) enum_set_typelib(attr->get_typelib())
{ {
name= item->name; name= item->name;
@ -7011,14 +6939,6 @@ public:
make_and_init_table_field(&name, Record_addr(maybe_null), make_and_init_table_field(&name, Record_addr(maybe_null),
*this, table); *this, table);
} }
Field::geometry_type get_geometry_type() const
{
return Type_geometry_attributes::get_geometry_type();
}
void set_geometry_type(uint type)
{
Type_geometry_attributes::set_geometry_type(type);
}
Item* get_copy(THD *thd) { return 0; } Item* get_copy(THD *thd) { return 0; }
}; };

View file

@ -436,8 +436,7 @@ public:
Functions whose returned field type is determined at fix_fields() time. Functions whose returned field type is determined at fix_fields() time.
*/ */
class Item_hybrid_func: public Item_func, class Item_hybrid_func: public Item_func,
public Type_handler_hybrid_field_type, public Type_handler_hybrid_field_type
public Type_geometry_attributes
{ {
protected: protected:
bool fix_attributes(Item **item, uint nitems); bool fix_attributes(Item **item, uint nitems);
@ -452,12 +451,6 @@ public:
:Item_func(thd, item), Type_handler_hybrid_field_type(item) { } :Item_func(thd, item), Type_handler_hybrid_field_type(item) { }
const Type_handler *type_handler() const const Type_handler *type_handler() const
{ return Type_handler_hybrid_field_type::type_handler(); } { return Type_handler_hybrid_field_type::type_handler(); }
Field::geometry_type get_geometry_type() const
{ return Type_geometry_attributes::get_geometry_type(); };
void set_geometry_type(uint type)
{
Type_geometry_attributes::set_geometry_type(type);
}
}; };

View file

@ -324,12 +324,6 @@ String *Item_func_geometry_type::val_str_ascii(String *str)
} }
Field::geometry_type Item_func_envelope::get_geometry_type() const
{
return Field::GEOM_POLYGON;
}
String *Item_func_envelope::val_str(String *str) String *Item_func_envelope::val_str(String *str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
@ -478,12 +472,6 @@ mem_error:
} }
Field::geometry_type Item_func_centroid::get_geometry_type() const
{
return Field::GEOM_POINT;
}
String *Item_func_centroid::val_str(String *str) String *Item_func_centroid::val_str(String *str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
@ -901,12 +889,6 @@ err:
*/ */
Field::geometry_type Item_func_point::get_geometry_type() const
{
return Field::GEOM_POINT;
}
String *Item_func_point::val_str(String *str) String *Item_func_point::val_str(String *str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
@ -2631,12 +2613,6 @@ mem_error:
} }
Field::geometry_type Item_func_pointonsurface::get_geometry_type() const
{
return Field::GEOM_POINT;
}
#ifndef DBUG_OFF #ifndef DBUG_OFF
longlong Item_func_gis_debug::val_int() longlong Item_func_gis_debug::val_int()
{ {

View file

@ -53,7 +53,8 @@ protected:
bool check_arguments() const bool check_arguments() const
{ {
DBUG_ASSERT(arg_count == 1); DBUG_ASSERT(arg_count == 1);
return args[0]->check_type_or_binary(func_name(), &type_handler_geometry); return Type_handler_geometry::check_type_geom_or_binary(func_name(),
args[0]);
} }
public: public:
Item_real_func_args_geometry(THD *thd, Item *a) Item_real_func_args_geometry(THD *thd, Item *a)
@ -69,7 +70,8 @@ class Item_long_func_args_geometry: public Item_long_func
bool check_arguments() const bool check_arguments() const
{ {
DBUG_ASSERT(arg_count == 1); DBUG_ASSERT(arg_count == 1);
return args[0]->check_type_or_binary(func_name(), &type_handler_geometry); return Type_handler_geometry::check_type_geom_or_binary(func_name(),
args[0]);
} }
protected: protected:
String value; String value;
@ -89,7 +91,8 @@ protected:
bool check_arguments() const bool check_arguments() const
{ {
DBUG_ASSERT(arg_count == 1); DBUG_ASSERT(arg_count == 1);
return args[0]->check_type_or_binary(func_name(), &type_handler_geometry); return Type_handler_geometry::check_type_geom_or_binary(func_name(),
args[0]);
} }
public: public:
Item_bool_func_args_geometry(THD *thd, Item *a) Item_bool_func_args_geometry(THD *thd, Item *a)
@ -106,7 +109,8 @@ protected:
bool check_arguments() const bool check_arguments() const
{ {
DBUG_ASSERT(arg_count >= 1); DBUG_ASSERT(arg_count >= 1);
return args[0]->check_type_or_binary(func_name(), &type_handler_geometry); return Type_handler_geometry::check_type_geom_or_binary(func_name(),
args[0]);
} }
public: public:
Item_str_ascii_func_args_geometry(THD *thd, Item *a) Item_str_ascii_func_args_geometry(THD *thd, Item *a)
@ -127,7 +131,8 @@ protected:
bool check_arguments() const bool check_arguments() const
{ {
DBUG_ASSERT(arg_count >= 1); DBUG_ASSERT(arg_count >= 1);
return args[0]->check_type_or_binary(func_name(), &type_handler_geometry); return Type_handler_geometry::check_type_geom_or_binary(func_name(),
args[0]);
} }
public: public:
Item_binary_func_args_geometry(THD *thd, Item *a) Item_binary_func_args_geometry(THD *thd, Item *a)
@ -144,7 +149,8 @@ protected:
bool check_arguments() const bool check_arguments() const
{ {
DBUG_ASSERT(arg_count >= 1); DBUG_ASSERT(arg_count >= 1);
return args[0]->check_type_or_binary(func_name(), &type_handler_geometry); return Type_handler_geometry::check_type_geom_or_binary(func_name(),
args[0]);
} }
public: public:
Item_geometry_func_args_geometry(THD *thd, Item *a) Item_geometry_func_args_geometry(THD *thd, Item *a)
@ -163,7 +169,8 @@ protected:
bool check_arguments() const bool check_arguments() const
{ {
DBUG_ASSERT(arg_count >= 2); DBUG_ASSERT(arg_count >= 2);
return check_argument_types_or_binary(&type_handler_geometry, 0, 2); return Type_handler_geometry::check_types_geom_or_binary(func_name(),
args, 0, 2);
} }
public: public:
Item_real_func_args_geometry_geometry(THD *thd, Item *a, Item *b) Item_real_func_args_geometry_geometry(THD *thd, Item *a, Item *b)
@ -181,7 +188,8 @@ protected:
bool check_arguments() const bool check_arguments() const
{ {
DBUG_ASSERT(arg_count >= 2); DBUG_ASSERT(arg_count >= 2);
return check_argument_types_or_binary(&type_handler_geometry, 0, 2); return Type_handler_geometry::check_types_geom_or_binary(func_name(),
args, 0, 2);
} }
public: public:
Item_bool_func_args_geometry_geometry(THD *thd, Item *a, Item *b, Item *c) Item_bool_func_args_geometry_geometry(THD *thd, Item *a, Item *b, Item *c)
@ -210,8 +218,9 @@ class Item_func_geometry_from_wkb: public Item_geometry_func
{ {
bool check_arguments() const bool check_arguments() const
{ {
return args[0]->check_type_or_binary(func_name(), &type_handler_geometry) || return
check_argument_types_can_return_int(1, MY_MIN(2, arg_count)); Type_handler_geometry::check_type_geom_or_binary(func_name(), args[0]) ||
check_argument_types_can_return_int(1, MY_MIN(2, arg_count));
} }
public: public:
Item_func_geometry_from_wkb(THD *thd, Item *a): Item_geometry_func(thd, a) {} Item_func_geometry_from_wkb(THD *thd, Item *a): Item_geometry_func(thd, a) {}
@ -363,7 +372,10 @@ public:
:Item_geometry_func_args_geometry(thd, a) {} :Item_geometry_func_args_geometry(thd, a) {}
const char *func_name() const { return "st_centroid"; } const char *func_name() const { return "st_centroid"; }
String *val_str(String *); String *val_str(String *);
Field::geometry_type get_geometry_type() const; const Type_handler *type_handler() const
{
return &type_handler_point;
}
Item *get_copy(THD *thd) Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_centroid>(thd, this); } { return get_item_copy<Item_func_centroid>(thd, this); }
}; };
@ -375,7 +387,10 @@ public:
:Item_geometry_func_args_geometry(thd, a) {} :Item_geometry_func_args_geometry(thd, a) {}
const char *func_name() const { return "st_envelope"; } const char *func_name() const { return "st_envelope"; }
String *val_str(String *); String *val_str(String *);
Field::geometry_type get_geometry_type() const; const Type_handler *type_handler() const
{
return &type_handler_polygon;
}
Item *get_copy(THD *thd) Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_envelope>(thd, this); } { return get_item_copy<Item_func_envelope>(thd, this); }
}; };
@ -425,7 +440,10 @@ public:
Item_geometry_func(thd, a, b, srid) {} Item_geometry_func(thd, a, b, srid) {}
const char *func_name() const { return "point"; } const char *func_name() const { return "point"; }
String *val_str(String *); String *val_str(String *);
Field::geometry_type get_geometry_type() const; const Type_handler *type_handler() const
{
return &type_handler_point;
}
Item *get_copy(THD *thd) Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_point>(thd, this); } { return get_item_copy<Item_func_point>(thd, this); }
}; };
@ -493,7 +511,8 @@ class Item_func_spatial_collection: public Item_geometry_func
{ {
bool check_arguments() const bool check_arguments() const
{ {
return check_argument_types_or_binary(&type_handler_geometry, 0, arg_count); return Type_handler_geometry::check_types_geom_or_binary(func_name(), args,
0, arg_count);
} }
enum Geometry::wkbType coll_type; enum Geometry::wkbType coll_type;
enum Geometry::wkbType item_type; enum Geometry::wkbType item_type;
@ -524,13 +543,112 @@ public:
} }
return FALSE; return FALSE;
} }
};
class Item_func_geometrycollection: public Item_func_spatial_collection
{
public:
Item_func_geometrycollection(THD *thd, List<Item> &list)
:Item_func_spatial_collection(thd, list,
Geometry::wkb_geometrycollection,
Geometry::wkb_point)
{ }
const Type_handler *type_handler() const
{
return &type_handler_geometrycollection;
}
const char *func_name() const { return "geometrycollection"; } const char *func_name() const { return "geometrycollection"; }
Item *get_copy(THD *thd) Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_spatial_collection>(thd, this); } { return get_item_copy<Item_func_geometrycollection>(thd, this); }
}; };
class Item_func_linestring: public Item_func_spatial_collection
{
public:
Item_func_linestring(THD *thd, List<Item> &list)
:Item_func_spatial_collection(thd, list,
Geometry::wkb_linestring,
Geometry::wkb_point)
{ }
const Type_handler *type_handler() const { return &type_handler_linestring; }
const char *func_name() const { return "linestring"; }
Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_linestring>(thd, this); }
};
class Item_func_polygon: public Item_func_spatial_collection
{
public:
Item_func_polygon(THD *thd, List<Item> &list)
:Item_func_spatial_collection(thd, list,
Geometry::wkb_polygon,
Geometry::wkb_linestring)
{ }
const Type_handler *type_handler() const { return &type_handler_polygon; }
const char *func_name() const { return "polygon"; }
Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_polygon>(thd, this); }
};
class Item_func_multilinestring: public Item_func_spatial_collection
{
public:
Item_func_multilinestring(THD *thd, List<Item> &list)
:Item_func_spatial_collection(thd, list,
Geometry::wkb_multilinestring,
Geometry::wkb_linestring)
{ }
const Type_handler *type_handler() const
{
return &type_handler_multilinestring;
}
const char *func_name() const { return "multilinestring"; }
Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_multilinestring>(thd, this); }
};
class Item_func_multipoint: public Item_func_spatial_collection
{
public:
Item_func_multipoint(THD *thd, List<Item> &list)
:Item_func_spatial_collection(thd, list,
Geometry::wkb_multipoint,
Geometry::wkb_point)
{ }
const Type_handler *type_handler() const
{
return &type_handler_multipoint;
}
const char *func_name() const { return "multipoint"; }
Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_multipoint>(thd, this); }
};
class Item_func_multipolygon: public Item_func_spatial_collection
{
public:
Item_func_multipolygon(THD *thd, List<Item> &list)
:Item_func_spatial_collection(thd, list,
Geometry::wkb_multipolygon,
Geometry::wkb_polygon)
{ }
const Type_handler *type_handler() const
{
return &type_handler_multipolygon;
}
const char *func_name() const { return "multipolygon"; }
Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_multipolygon>(thd, this); }
};
/* /*
Spatial relations Spatial relations
*/ */
@ -546,7 +664,8 @@ protected:
bool check_arguments() const bool check_arguments() const
{ {
DBUG_ASSERT(arg_count >= 2); DBUG_ASSERT(arg_count >= 2);
return check_argument_types_or_binary(&type_handler_geometry, 0, 2); return Type_handler_geometry::check_types_geom_or_binary(func_name(),
args, 0, 2);
} }
public: public:
Item_func_spatial_rel(THD *thd, Item *a, Item *b, enum Functype sp_rel): Item_func_spatial_rel(THD *thd, Item *a, Item *b, enum Functype sp_rel):
@ -641,7 +760,8 @@ class Item_func_spatial_operation: public Item_geometry_func
bool check_arguments() const bool check_arguments() const
{ {
DBUG_ASSERT(arg_count >= 2); DBUG_ASSERT(arg_count >= 2);
return check_argument_types_or_binary(&type_handler_geometry, 0, 2); return Type_handler_geometry::check_types_geom_or_binary(func_name(),
args, 0, 2);
} }
public: public:
Gcalc_function::op_type spatial_op; Gcalc_function::op_type spatial_op;
@ -945,7 +1065,10 @@ public:
:Item_geometry_func_args_geometry(thd, a) {} :Item_geometry_func_args_geometry(thd, a) {}
const char *func_name() const { return "st_pointonsurface"; } const char *func_name() const { return "st_pointonsurface"; }
String *val_str(String *); String *val_str(String *);
Field::geometry_type get_geometry_type() const; const Type_handler *type_handler() const
{
return &type_handler_point;
}
Item *get_copy(THD *thd) Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_pointonsurface>(thd, this); } { return get_item_copy<Item_func_pointonsurface>(thd, this); }
}; };
@ -971,10 +1094,12 @@ class Item_func_gis_debug: public Item_long_func
#define GEOM_NEW(thd, obj_constructor) new (thd->mem_root) obj_constructor #define GEOM_NEW(thd, obj_constructor) new (thd->mem_root) obj_constructor
#define GEOM_TYPE(x) (x)
#else /*HAVE_SPATIAL*/ #else /*HAVE_SPATIAL*/
#define GEOM_NEW(thd, obj_constructor) NULL #define GEOM_NEW(thd, obj_constructor) NULL
#define GEOM_TYPE(x) NULL
#endif /*HAVE_SPATIAL*/ #endif /*HAVE_SPATIAL*/
#endif /* ITEM_GEOFUNC_INCLUDED */ #endif /* ITEM_GEOFUNC_INCLUDED */

View file

@ -8122,13 +8122,13 @@ SEL_TREE *Item_bool_func::get_full_func_mm_tree(RANGE_OPT_PARAM *param,
table_map param_comp= ~(param->prev_tables | param->read_tables | table_map param_comp= ~(param->prev_tables | param->read_tables |
param->current_table); param->current_table);
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
Field::geometry_type sav_geom_type; const Type_handler_geometry *sav_geom_type= NULL;
const bool geometry= field_item->field->type() == MYSQL_TYPE_GEOMETRY; Field_geom *field_geom= dynamic_cast<Field_geom*>(field_item->field);
if (geometry) if (field_geom)
{ {
sav_geom_type= ((Field_geom*) field_item->field)->geom_type; sav_geom_type= field_geom->type_handler_geom();
/* We have to be able to store all sorts of spatial features here */ /* We have to be able to store all sorts of spatial features here */
((Field_geom*) field_item->field)->geom_type= Field::GEOM_GEOMETRY; field_geom->set_type_handler(&type_handler_geometry);
} }
#endif /*HAVE_SPATIAL*/ #endif /*HAVE_SPATIAL*/
@ -8159,9 +8159,10 @@ SEL_TREE *Item_bool_func::get_full_func_mm_tree(RANGE_OPT_PARAM *param,
} }
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
if (geometry) if (field_geom)
{ {
((Field_geom*) field_item->field)->geom_type= sav_geom_type; DBUG_ASSERT(sav_geom_type);
field_geom->set_type_handler(sav_geom_type);
} }
#endif /*HAVE_SPATIAL*/ #endif /*HAVE_SPATIAL*/
DBUG_RETURN(ftree); DBUG_RETURN(ftree);

View file

@ -129,6 +129,28 @@ bool Key_part_spec::operator==(const Key_part_spec& other) const
&other.field_name); &other.field_name);
} }
bool Key_part_spec::check_key_for_blob(const handler *file) const
{
if (!(file->ha_table_flags() & HA_CAN_INDEX_BLOBS))
{
my_error(ER_BLOB_USED_AS_KEY, MYF(0), field_name.str, file->table_type());
return true;
}
return false;
}
bool Key_part_spec::init_multiple_key_for_blob(const handler *file)
{
if (check_key_for_blob(file))
return true;
if (!length)
length= file->max_key_length() + 1;
return false;
}
/** /**
Construct an (almost) deep copy of this key. Only those Construct an (almost) deep copy of this key. Only those
elements that are known to never change are not copied. elements that are known to never change are not copied.

View file

@ -289,6 +289,25 @@ public:
*/ */
Key_part_spec *clone(MEM_ROOT *mem_root) const Key_part_spec *clone(MEM_ROOT *mem_root) const
{ return new (mem_root) Key_part_spec(*this); } { return new (mem_root) Key_part_spec(*this); }
bool check_key_for_blob(const class handler *file) const;
bool check_key_length_for_blob() const
{
if (!length)
{
my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), field_name.str);
return true;
}
return false;
}
bool check_primary_key_for_blob(const class handler *file) const
{
return check_key_for_blob(file) || check_key_length_for_blob();
}
bool check_foreign_key_for_blob(const class handler *file) const
{
return check_key_for_blob(file) || check_key_length_for_blob();
}
bool init_multiple_key_for_blob(const class handler *file);
}; };
@ -6829,8 +6848,7 @@ public:
class Type_holder: public Sql_alloc, class Type_holder: public Sql_alloc,
public Item_args, public Item_args,
public Type_handler_hybrid_field_type, public Type_handler_hybrid_field_type,
public Type_all_attributes, public Type_all_attributes
public Type_geometry_attributes
{ {
const TYPELIB *m_typelib; const TYPELIB *m_typelib;
bool m_maybe_null; bool m_maybe_null;
@ -6855,14 +6873,6 @@ public:
DBUG_ASSERT(0); DBUG_ASSERT(0);
return 0; return 0;
} }
void set_geometry_type(uint type)
{
Type_geometry_attributes::set_geometry_type(type);
}
uint uint_geometry_type() const
{
return Type_geometry_attributes::get_geometry_type();
}
void set_typelib(const TYPELIB *typelib) void set_typelib(const TYPELIB *typelib)
{ {
m_typelib= typelib; m_typelib= typelib;

View file

@ -448,10 +448,12 @@ static int get_geometry_column_record(THD *thd, TABLE_LIST *tables,
show_table->use_all_columns(); // Required for default show_table->use_all_columns(); // Required for default
restore_record(show_table, s->default_values); restore_record(show_table, s->default_values);
#ifdef HAVE_SPATIAL
for (; (field= *ptr) ; ptr++) for (; (field= *ptr) ; ptr++)
if (field->type() == MYSQL_TYPE_GEOMETRY) if (field->type() == MYSQL_TYPE_GEOMETRY)
{ {
Field_geom *fg= (Field_geom *) field; Field_geom *fg= (Field_geom *) field;
const Type_handler_geometry *gth= fg->type_handler_geom();
DEBUG_SYNC(thd, "get_schema_column"); DEBUG_SYNC(thd, "get_schema_column");
@ -476,7 +478,7 @@ static int get_geometry_column_record(THD *thd, TABLE_LIST *tables,
/*STORAGE_TYPE*/ /*STORAGE_TYPE*/
table->field[8]->store(1LL, TRUE); /*Always 1 (binary implementation)*/ table->field[8]->store(1LL, TRUE); /*Always 1 (binary implementation)*/
/*GEOMETRY_TYPE*/ /*GEOMETRY_TYPE*/
table->field[9]->store((longlong) (fg->get_geometry_type()), TRUE); table->field[9]->store((longlong) (gth->geometry_type()), TRUE);
/*COORD_DIMENSION*/ /*COORD_DIMENSION*/
table->field[10]->store(2LL, TRUE); table->field[10]->store(2LL, TRUE);
/*MAX_PPR*/ /*MAX_PPR*/
@ -487,6 +489,7 @@ static int get_geometry_column_record(THD *thd, TABLE_LIST *tables,
if (schema_table_store_record(thd, table)) if (schema_table_store_record(thd, table))
DBUG_RETURN(1); DBUG_RETURN(1);
} }
#endif
exit: exit:
DBUG_RETURN(0); DBUG_RETURN(0);

View file

@ -3409,6 +3409,24 @@ Type_handler_blob_common::Key_part_spec_init_ft(Key_part_spec *part,
} }
static bool
key_add_part_check_null(const handler *file, KEY *key_info,
const Column_definition *sql_field,
const Key_part_spec *column)
{
if (!(sql_field->flags & NOT_NULL_FLAG))
{
key_info->flags|= HA_NULL_PART_KEY;
if (!(file->ha_table_flags() & HA_NULL_IN_KEY))
{
my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name.str);
return true;
}
}
return false;
}
/* /*
Preparation for table creation Preparation for table creation
@ -3940,8 +3958,9 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
} }
cols2.rewind(); cols2.rewind();
if (key->type == Key::FULLTEXT) switch(key->type) {
{
case Key::FULLTEXT:
if (sql_field->type_handler()->Key_part_spec_init_ft(column, if (sql_field->type_handler()->Key_part_spec_init_ft(column,
*sql_field) || *sql_field) ||
(ft_key_charset && sql_field->charset != ft_key_charset)) (ft_key_charset && sql_field->charset != ft_key_charset))
@ -3949,111 +3968,75 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name.str); my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name.str);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
ft_key_charset=sql_field->charset; ft_key_charset= sql_field->charset;
} break;
else
{
column->length*= sql_field->charset->mbmaxlen; case Key::SPATIAL:
if (sql_field->type_handler()->Key_part_spec_init_spatial(column,
if (key->type == Key::SPATIAL) *sql_field) ||
sql_field->check_vcol_for_key(thd))
DBUG_RETURN(TRUE);
if (!(sql_field->flags & NOT_NULL_FLAG))
{ {
if (column->length) my_message(ER_SPATIAL_CANT_HAVE_NULL,
{ ER_THD(thd, ER_SPATIAL_CANT_HAVE_NULL), MYF(0));
my_error(ER_WRONG_SUB_KEY, MYF(0)); DBUG_RETURN(TRUE);
DBUG_RETURN(TRUE);
}
if (!f_is_geom(sql_field->pack_flag))
{
my_error(ER_WRONG_ARGUMENTS, MYF(0), "SPATIAL INDEX");
DBUG_RETURN(TRUE);
}
} }
break;
if (f_is_blob(sql_field->pack_flag) || case Key::PRIMARY:
(f_is_geom(sql_field->pack_flag) && key->type != Key::SPATIAL))
{
if (!(file->ha_table_flags() & HA_CAN_INDEX_BLOBS))
{
my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.str,
file->table_type());
DBUG_RETURN(TRUE);
}
if (f_is_geom(sql_field->pack_flag) && sql_field->geom_type ==
Field::GEOM_POINT)
column->length= MAX_LEN_GEOM_POINT_FIELD;
if (!column->length)
{
if (key->type == Key::UNIQUE)
is_hash_field_needed= true;
else if (key->type == Key::MULTIPLE)
column->length= file->max_key_length() + 1;
else
{
my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name.str);
DBUG_RETURN(TRUE);
}
}
}
#ifdef HAVE_SPATIAL
if (key->type == Key::SPATIAL)
{
if (!column->length)
{
/*
4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case
Lately we'll extend this code to support more dimensions
*/
column->length= 4*sizeof(double);
}
}
#endif
if (sql_field->vcol_info) if (sql_field->vcol_info)
{ {
if (key->type == Key::PRIMARY) my_error(ER_PRIMARY_KEY_BASED_ON_GENERATED_COLUMN, MYF(0));
{ DBUG_RETURN(TRUE);
my_error(ER_PRIMARY_KEY_BASED_ON_GENERATED_COLUMN, MYF(0));
DBUG_RETURN(TRUE);
}
if (sql_field->vcol_info->flags & VCOL_NOT_STRICTLY_DETERMINISTIC)
{
/* use check_expression() to report an error */
check_expression(sql_field->vcol_info, &sql_field->field_name,
VCOL_GENERATED_STORED);
DBUG_ASSERT(thd->is_error());
DBUG_RETURN(TRUE);
}
} }
if (!(sql_field->flags & NOT_NULL_FLAG)) if (sql_field->type_handler()->Key_part_spec_init_primary(column,
{ *sql_field,
if (key->type == Key::PRIMARY) file))
{ DBUG_RETURN(TRUE);
/* Implicitly set primary key fields to NOT NULL for ISO conf. */ if (!(sql_field->flags & NOT_NULL_FLAG))
sql_field->flags|= NOT_NULL_FLAG; {
sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL; /* Implicitly set primary key fields to NOT NULL for ISO conf. */
null_fields--; sql_field->flags|= NOT_NULL_FLAG;
} sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL;
else null_fields--;
{ }
key_info->flags|= HA_NULL_PART_KEY; break;
if (!(file->ha_table_flags() & HA_NULL_IN_KEY))
{ case Key::MULTIPLE:
my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name.str); if (sql_field->type_handler()->Key_part_spec_init_multiple(column,
DBUG_RETURN(TRUE); *sql_field,
} file) ||
if (key->type == Key::SPATIAL) sql_field->check_vcol_for_key(thd) ||
{ key_add_part_check_null(file, key_info, sql_field, column))
my_message(ER_SPATIAL_CANT_HAVE_NULL, DBUG_RETURN(TRUE);
ER_THD(thd, ER_SPATIAL_CANT_HAVE_NULL), MYF(0)); break;
DBUG_RETURN(TRUE);
} case Key::FOREIGN_KEY:
} if (sql_field->type_handler()->Key_part_spec_init_foreign(column,
} *sql_field,
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) file) ||
{ sql_field->check_vcol_for_key(thd) ||
if (column_nr == 0 || (file->ha_table_flags() & HA_AUTO_PART_KEY)) key_add_part_check_null(file, key_info, sql_field, column))
auto_increment--; // Field is used DBUG_RETURN(TRUE);
} break;
case Key::UNIQUE:
if (sql_field->type_handler()->Key_part_spec_init_unique(column,
*sql_field, file,
&is_hash_field_needed) ||
sql_field->check_vcol_for_key(thd) ||
key_add_part_check_null(file, key_info, sql_field, column))
DBUG_RETURN(TRUE);
break;
}
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
{
DBUG_ASSERT(key->type != Key::FULLTEXT);
DBUG_ASSERT(key->type != Key::SPATIAL);
if (column_nr == 0 || (file->ha_table_flags() & HA_AUTO_PART_KEY))
auto_increment--; // Field is used
} }
key_part_info->fieldnr= field; key_part_info->fieldnr= field;

View file

@ -118,8 +118,6 @@ enum enum_explain_filename_mode
EXPLAIN_PARTITIONS_AS_COMMENT EXPLAIN_PARTITIONS_AS_COMMENT
}; };
/* Maximum length of GEOM_POINT Field */
#define MAX_LEN_GEOM_POINT_FIELD 25
/* depends on errmsg.txt Database `db`, Table `t` ... */ /* depends on errmsg.txt Database `db`, Table `t` ... */
#define EXPLAIN_FILENAME_MAX_EXTRA_LENGTH 63 #define EXPLAIN_FILENAME_MAX_EXTRA_LENGTH 63

View file

@ -101,15 +101,58 @@ const Type_collection *Type_handler::type_collection() const
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
Type_handler_geometry type_handler_geometry; Type_handler_geometry type_handler_geometry;
Type_handler_point type_handler_point;
Type_handler_linestring type_handler_linestring;
Type_handler_polygon type_handler_polygon;
Type_handler_multipoint type_handler_multipoint;
Type_handler_multilinestring type_handler_multilinestring;
Type_handler_multipolygon type_handler_multipolygon;
Type_handler_geometrycollection type_handler_geometrycollection;
const Type_handler_geometry *
Type_handler_geometry::type_handler_geom_by_type(uint type)
{
switch (type) {
case Type_handler_geometry::GEOM_POINT:
return &type_handler_point;
case Type_handler_geometry::GEOM_LINESTRING:
return &type_handler_linestring;
case Type_handler_geometry::GEOM_POLYGON:
return &type_handler_polygon;
case Type_handler_geometry::GEOM_MULTIPOINT:
return &type_handler_multipoint;
case Type_handler_geometry::GEOM_MULTILINESTRING:
return &type_handler_multilinestring;
case Type_handler_geometry::GEOM_MULTIPOLYGON:
return &type_handler_multipolygon;
case Type_handler_geometry::GEOM_GEOMETRYCOLLECTION:
return &type_handler_geometrycollection;
case Type_handler_geometry::GEOM_GEOMETRY:
break;
}
return &type_handler_geometry;
}
const Type_handler *
Type_handler_geometry::type_handler_frm_unpack(const uchar *buffer) const
{
// charset and geometry_type share the same byte in frm
return type_handler_geom_by_type((uint) buffer[14]);
}
class Type_collection_geometry: public Type_collection class Type_collection_geometry: public Type_collection
{ {
const Type_handler *aggregate_common(const Type_handler *a, const Type_handler *aggregate_common(const Type_handler *a,
const Type_handler *b) const const Type_handler *b) const
{ {
DBUG_ASSERT(a == &type_handler_geometry); if (a == b)
DBUG_ASSERT(b == &type_handler_geometry); return a;
DBUG_ASSERT(dynamic_cast<const Type_handler_geometry*>(a));
DBUG_ASSERT(dynamic_cast<const Type_handler_geometry*>(b));
return &type_handler_geometry; return &type_handler_geometry;
} }
public: public:
@ -137,6 +180,56 @@ public:
{ {
return NULL; return NULL;
} }
bool init_aggregators(Type_handler_data *data, const Type_handler *geom) const
{
Type_aggregator *r= &data->m_type_aggregator_for_result;
Type_aggregator *c= &data->m_type_aggregator_for_comparison;
return
r->add(geom, &type_handler_null, geom) ||
r->add(geom, &type_handler_hex_hybrid, &type_handler_long_blob) ||
r->add(geom, &type_handler_tiny_blob, &type_handler_long_blob) ||
r->add(geom, &type_handler_blob, &type_handler_long_blob) ||
r->add(geom, &type_handler_medium_blob, &type_handler_long_blob) ||
r->add(geom, &type_handler_long_blob, &type_handler_long_blob) ||
r->add(geom, &type_handler_varchar, &type_handler_long_blob) ||
r->add(geom, &type_handler_string, &type_handler_long_blob) ||
c->add(geom, &type_handler_null, geom) ||
c->add(geom, &type_handler_long_blob, &type_handler_long_blob);
}
bool init(Type_handler_data *data) const
{
#ifndef DBUG_OFF
/*
The rules (geometry,geometry)->geometry and (pont,point)->geometry
are needed here to make sure
(in gis-debug.test) that they do not affect anything, and these pairs
returns an error in an expression like (POINT(0,0)+POINT(0,0)).
Both sides are from the same type collection here,
so aggregation goes only through Type_collection_xxx::aggregate_yyy()
and never reaches Type_aggregator::find_handler().
*/
Type_aggregator *nct= &data->m_type_aggregator_non_commutative_test;
if (nct->add(&type_handler_geometry,
&type_handler_geometry,
&type_handler_geometry) ||
nct->add(&type_handler_point,
&type_handler_point,
&type_handler_geometry) ||
nct->add(&type_handler_point,
&type_handler_varchar,
&type_handler_long_blob))
return true;
#endif
return
init_aggregators(data, &type_handler_geometry) ||
init_aggregators(data, &type_handler_geometrycollection) ||
init_aggregators(data, &type_handler_point) ||
init_aggregators(data, &type_handler_linestring) ||
init_aggregators(data, &type_handler_polygon) ||
init_aggregators(data, &type_handler_multipoint) ||
init_aggregators(data, &type_handler_multilinestring) ||
init_aggregators(data, &type_handler_multipolygon);
}
}; };
@ -153,56 +246,7 @@ const Type_collection *Type_handler_geometry::type_collection() const
bool Type_handler_data::init() bool Type_handler_data::init()
{ {
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
return type_collection_geometry.init(this);
#ifndef DBUG_OFF
/*
The rule (geometry,geometry)->geometry is needed here to make sure
(in gis-debug.test) that is does not affect anything, and this pair
returns an error in an expression like (POINT(0,0)+POINT(0,0)).
Both sides are from the same type collection here,
so aggregation goes only through Type_collection_xxx::aggregate_yyy()
and never reaches Type_aggregator::find_handler().
*/
if (m_type_aggregator_non_commutative_test.add(&type_handler_geometry,
&type_handler_geometry,
&type_handler_geometry) ||
m_type_aggregator_non_commutative_test.add(&type_handler_geometry,
&type_handler_varchar,
&type_handler_long_blob))
return true;
#endif
return
m_type_aggregator_for_result.add(&type_handler_geometry,
&type_handler_null,
&type_handler_geometry) ||
m_type_aggregator_for_result.add(&type_handler_geometry,
&type_handler_hex_hybrid,
&type_handler_long_blob) ||
m_type_aggregator_for_result.add(&type_handler_geometry,
&type_handler_tiny_blob,
&type_handler_long_blob) ||
m_type_aggregator_for_result.add(&type_handler_geometry,
&type_handler_blob,
&type_handler_long_blob) ||
m_type_aggregator_for_result.add(&type_handler_geometry,
&type_handler_medium_blob,
&type_handler_long_blob) ||
m_type_aggregator_for_result.add(&type_handler_geometry,
&type_handler_long_blob,
&type_handler_long_blob) ||
m_type_aggregator_for_result.add(&type_handler_geometry,
&type_handler_varchar,
&type_handler_long_blob) ||
m_type_aggregator_for_result.add(&type_handler_geometry,
&type_handler_string,
&type_handler_long_blob) ||
m_type_aggregator_for_comparison.add(&type_handler_geometry,
&type_handler_null,
&type_handler_geometry) ||
m_type_aggregator_for_comparison.add(&type_handler_geometry,
&type_handler_long_blob,
&type_handler_long_blob);
#endif #endif
return false; return false;
} }
@ -2358,8 +2402,51 @@ Field *Type_handler_blob_compressed::make_conversion_table_field(TABLE *table,
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
const Name Type_handler_geometry::m_name_geometry(STRING_WITH_LEN("geometry"));
bool Type_handler_geometry::check_type_geom_or_binary(const char *opname,
const Item *item)
{
const Type_handler *handler= item->type_handler();
if (handler->type_handler_for_comparison() == &type_handler_geometry ||
(handler->is_general_purpose_string_type() &&
item->collation.collation == &my_charset_bin))
return false;
my_error(ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION, MYF(0),
handler->name().ptr(), opname);
return true;
}
bool Type_handler_geometry::check_types_geom_or_binary(const char *opname,
Item* const *args,
uint start, uint end)
{
for (uint i= start; i < end ; i++)
{
if (check_type_geom_or_binary(opname, args[i]))
return true;
}
return false;
}
const Name
Type_handler_geometry::
m_name_geometry(STRING_WITH_LEN("geometry")),
Type_handler_point::
m_name_point(STRING_WITH_LEN("point")),
Type_handler_linestring::
m_name_linestring(STRING_WITH_LEN("linestring")),
Type_handler_polygon::
m_name_polygon(STRING_WITH_LEN("polygon")),
Type_handler_multipoint::
m_name_multipoint(STRING_WITH_LEN("multipoint")),
Type_handler_multilinestring::
m_name_multilinestring(STRING_WITH_LEN("multilinestring")),
Type_handler_multipolygon::
m_name_multipolygon(STRING_WITH_LEN("multipolygon")),
Type_handler_geometrycollection::
m_name_geometrycollection(STRING_WITH_LEN("geometrycollection"));
const Type_handler *Type_handler_geometry::type_handler_for_comparison() const const Type_handler *Type_handler_geometry::type_handler_for_comparison() const
{ {
@ -2379,10 +2466,10 @@ Field *Type_handler_geometry::make_conversion_table_field(TABLE *table,
as this is only a temporary field. as this is only a temporary field.
The statistics was already incremented when "target" was created. The statistics was already incremented when "target" was created.
*/ */
const Field_geom *fg= static_cast<const Field_geom*>(target);
return new(table->in_use->mem_root) return new(table->in_use->mem_root)
Field_geom(NULL, (uchar *) "", 1, Field::NONE, &empty_clex_str, table->s, 4, Field_geom(NULL, (uchar *) "", 1, Field::NONE, &empty_clex_str,
((const Field_geom*) target)->geom_type, table->s, 4, fg->type_handler_geom(), fg->srid);
((const Field_geom*) target)->srid);
} }
#endif #endif
@ -2634,7 +2721,6 @@ void Type_handler_geometry::
Column_definition *def, Column_definition *def,
const Field *field) const const Field *field) const
{ {
def->geom_type= ((Field_geom*) field)->geom_type;
def->srid= ((Field_geom*) field)->srid; def->srid= ((Field_geom*) field)->srid;
} }
#endif #endif
@ -2973,6 +3059,193 @@ bool Type_handler_bit::
return false; return false;
} }
/*************************************************************************/
bool Type_handler::Key_part_spec_init_primary(Key_part_spec *part,
const Column_definition &def,
const handler *file) const
{
part->length*= def.charset->mbmaxlen;
return false;
}
bool Type_handler::Key_part_spec_init_unique(Key_part_spec *part,
const Column_definition &def,
const handler *file,
bool *has_field_needed) const
{
part->length*= def.charset->mbmaxlen;
return false;
}
bool Type_handler::Key_part_spec_init_multiple(Key_part_spec *part,
const Column_definition &def,
const handler *file) const
{
part->length*= def.charset->mbmaxlen;
return false;
}
bool Type_handler::Key_part_spec_init_foreign(Key_part_spec *part,
const Column_definition &def,
const handler *file) const
{
part->length*= def.charset->mbmaxlen;
return false;
}
bool Type_handler::Key_part_spec_init_spatial(Key_part_spec *part,
const Column_definition &def)
const
{
my_error(ER_WRONG_ARGUMENTS, MYF(0), "SPATIAL INDEX");
return true;
}
bool Type_handler_blob_common::Key_part_spec_init_primary(Key_part_spec *part,
const Column_definition &def,
const handler *file) const
{
part->length*= def.charset->mbmaxlen;
return part->check_primary_key_for_blob(file);
}
bool Type_handler_blob_common::Key_part_spec_init_unique(Key_part_spec *part,
const Column_definition &def,
const handler *file,
bool *hash_field_needed) const
{
if (!(part->length*= def.charset->mbmaxlen))
*hash_field_needed= true;
return part->check_key_for_blob(file);
}
bool Type_handler_blob_common::Key_part_spec_init_multiple(Key_part_spec *part,
const Column_definition &def,
const handler *file) const
{
part->length*= def.charset->mbmaxlen;
return part->init_multiple_key_for_blob(file);
}
bool Type_handler_blob_common::Key_part_spec_init_foreign(Key_part_spec *part,
const Column_definition &def,
const handler *file) const
{
part->length*= def.charset->mbmaxlen;
return part->check_foreign_key_for_blob(file);
}
#ifdef HAVE_SPATIAL
bool Type_handler_geometry::Key_part_spec_init_primary(Key_part_spec *part,
const Column_definition &def,
const handler *file) const
{
return part->check_primary_key_for_blob(file);
}
bool Type_handler_geometry::Key_part_spec_init_unique(Key_part_spec *part,
const Column_definition &def,
const handler *file,
bool *hash_field_needed) const
{
if (!part->length)
*hash_field_needed= true;
return part->check_key_for_blob(file);
}
bool Type_handler_geometry::Key_part_spec_init_multiple(Key_part_spec *part,
const Column_definition &def,
const handler *file) const
{
return part->init_multiple_key_for_blob(file);
}
bool Type_handler_geometry::Key_part_spec_init_foreign(Key_part_spec *part,
const Column_definition &def,
const handler *file) const
{
return part->check_foreign_key_for_blob(file);
}
bool Type_handler_geometry::Key_part_spec_init_spatial(Key_part_spec *part,
const Column_definition &def)
const
{
if (part->length)
{
my_error(ER_WRONG_SUB_KEY, MYF(0));
return true;
}
/*
4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case
Lately we'll extend this code to support more dimensions
*/
part->length= 4 * sizeof(double);
return false;
}
bool Type_handler_point::Key_part_spec_init_primary(Key_part_spec *part,
const Column_definition &def,
const handler *file) const
{
/*
QQ:
The below assignment (here and in all other Key_part_spec_init_xxx methods)
overrides the explicitly given key part length, so in this query:
CREATE OR REPLACE TABLE t1 (a POINT, KEY(a(10)));
the key becomes KEY(a(25)).
This might be a bug.
*/
part->length= octet_length();
return part->check_key_for_blob(file);
}
bool Type_handler_point::Key_part_spec_init_unique(Key_part_spec *part,
const Column_definition &def,
const handler *file,
bool *hash_field_needed) const
{
part->length= octet_length();
return part->check_key_for_blob(file);
}
bool Type_handler_point::Key_part_spec_init_multiple(Key_part_spec *part,
const Column_definition &def,
const handler *file) const
{
part->length= octet_length();
return part->check_key_for_blob(file);
}
bool Type_handler_point::Key_part_spec_init_foreign(Key_part_spec *part,
const Column_definition &def,
const handler *file) const
{
part->length= octet_length();
return part->check_key_for_blob(file);
}
#endif // HAVE_SPATIAL
/*************************************************************************/ /*************************************************************************/
uint32 Type_handler_time::calc_pack_length(uint32 length) const uint32 Type_handler_time::calc_pack_length(uint32 length) const
@ -3481,9 +3754,7 @@ Field *Type_handler_geometry::make_table_field(const LEX_CSTRING *name,
{ {
return new (table->in_use->mem_root) return new (table->in_use->mem_root)
Field_geom(addr.ptr(), addr.null_ptr(), addr.null_bit(), Field_geom(addr.ptr(), addr.null_ptr(), addr.null_bit(),
Field::NONE, name, table->s, 4, Field::NONE, name, table->s, 4, this, 0);
(Field::geometry_type) attr.uint_geometry_type(),
0);
} }
#endif #endif
@ -4277,10 +4548,6 @@ bool Type_handler_geometry::
Item **items, uint nitems) const Item **items, uint nitems) const
{ {
DBUG_ASSERT(nitems > 0); DBUG_ASSERT(nitems > 0);
Type_geometry_attributes gattr(items[0]->type_handler(), items[0]);
for (uint i= 1; i < nitems; i++)
gattr.join(items[i]);
func->set_geometry_type(gattr.get_geometry_type());
func->collation.set(&my_charset_bin); func->collation.set(&my_charset_bin);
func->unsigned_flag= false; func->unsigned_flag= false;
func->decimals= 0; func->decimals= 0;
@ -6989,7 +7256,6 @@ bool Type_handler_geometry::
{ {
param->unsigned_flag= false; param->unsigned_flag= false;
param->setup_conversion_blob(thd); param->setup_conversion_blob(thd);
param->set_geometry_type(attr->uint_geometry_type());
return param->set_str(val->m_string.ptr(), val->m_string.length(), return param->set_str(val->m_string.ptr(), val->m_string.length(),
&my_charset_bin, &my_charset_bin); &my_charset_bin, &my_charset_bin);
} }
@ -7897,7 +8163,7 @@ Field *Type_handler_geometry::
return new (mem_root) return new (mem_root)
Field_geom(rec.ptr(), rec.null_ptr(), rec.null_bit(), Field_geom(rec.ptr(), rec.null_ptr(), rec.null_bit(),
attr->unireg_check, name, share, attr->unireg_check, name, share,
attr->pack_flag_to_pack_length(), attr->geom_type, attr->srid); attr->pack_flag_to_pack_length(), this, attr->srid);
} }
#endif #endif
@ -8004,7 +8270,7 @@ void Type_handler_geometry::
{ {
def->frm_pack_basic(buff); def->frm_pack_basic(buff);
buff[11]= 0; buff[11]= 0;
buff[14]= (uchar) def->geom_type; buff[14]= (uchar) geometry_type();
} }
#endif #endif
@ -8034,8 +8300,6 @@ bool Type_handler_geometry::
uint gis_opt_read, gis_length, gis_decimals; uint gis_opt_read, gis_length, gis_decimals;
Field_geom::storage_type st_type; Field_geom::storage_type st_type;
attr->frm_unpack_basic(buffer); attr->frm_unpack_basic(buffer);
// charset and geometry_type share the same byte in frm
attr->geom_type= (Field::geometry_type) buffer[14];
gis_opt_read= gis_field_options_read(gis_options->str, gis_opt_read= gis_field_options_read(gis_options->str,
gis_options->length, gis_options->length,
&st_type, &gis_length, &st_type, &gis_length,

View file

@ -3012,14 +3012,6 @@ public:
virtual void set_maybe_null(bool maybe_null_arg)= 0; virtual void set_maybe_null(bool maybe_null_arg)= 0;
// Returns total number of decimal digits // Returns total number of decimal digits
virtual uint decimal_precision() const= 0; virtual uint decimal_precision() const= 0;
/*
Field::geometry_type is not visible here.
Let's use an "uint" wrapper for now. Later when we move Field_geom
into a plugin, this method will be replaced to some generic
datatype indepented method.
*/
virtual uint uint_geometry_type() const= 0;
virtual void set_geometry_type(uint type)= 0;
virtual const TYPELIB *get_typelib() const= 0; virtual const TYPELIB *get_typelib() const= 0;
virtual void set_typelib(const TYPELIB *typelib)= 0; virtual void set_typelib(const TYPELIB *typelib)= 0;
}; };
@ -3534,6 +3526,21 @@ public:
virtual bool Column_definition_prepare_stage2(Column_definition *c, virtual bool Column_definition_prepare_stage2(Column_definition *c,
handler *file, handler *file,
ulonglong table_flags) const= 0; ulonglong table_flags) const= 0;
virtual bool Key_part_spec_init_primary(Key_part_spec *part,
const Column_definition &def,
const handler *file) const;
virtual bool Key_part_spec_init_unique(Key_part_spec *part,
const Column_definition &def,
const handler *file,
bool *has_key_needed) const;
virtual bool Key_part_spec_init_multiple(Key_part_spec *part,
const Column_definition &def,
const handler *file) const;
virtual bool Key_part_spec_init_foreign(Key_part_spec *part,
const Column_definition &def,
const handler *file) const;
virtual bool Key_part_spec_init_spatial(Key_part_spec *part,
const Column_definition &def) const;
virtual bool Key_part_spec_init_ft(Key_part_spec *part, virtual bool Key_part_spec_init_ft(Key_part_spec *part,
const Column_definition &def) const const Column_definition &def) const
{ {
@ -3566,6 +3573,10 @@ public:
virtual void virtual void
Column_definition_attributes_frm_pack(const Column_definition_attributes *at, Column_definition_attributes_frm_pack(const Column_definition_attributes *at,
uchar *buff) const; uchar *buff) const;
virtual const Type_handler *type_handler_frm_unpack(const uchar *buffer) const
{
return this;
}
virtual bool virtual bool
Column_definition_attributes_frm_unpack(Column_definition_attributes *attr, Column_definition_attributes_frm_unpack(Column_definition_attributes *attr,
TABLE_SHARE *share, TABLE_SHARE *share,
@ -6246,6 +6257,19 @@ public:
ulonglong table_flags) const; ulonglong table_flags) const;
bool Key_part_spec_init_ft(Key_part_spec *part, bool Key_part_spec_init_ft(Key_part_spec *part,
const Column_definition &def) const; const Column_definition &def) const;
bool Key_part_spec_init_primary(Key_part_spec *part,
const Column_definition &def,
const handler *file) const override;
bool Key_part_spec_init_unique(Key_part_spec *part,
const Column_definition &def,
const handler *file,
bool *has_key_needed) const override;
bool Key_part_spec_init_multiple(Key_part_spec *part,
const Column_definition &def,
const handler *file) const override;
bool Key_part_spec_init_foreign(Key_part_spec *part,
const Column_definition &def,
const handler *file) const override;
bool Item_hybrid_func_fix_attributes(THD *thd, bool Item_hybrid_func_fix_attributes(THD *thd,
const char *name, const char *name,
Type_handler_hybrid_field_type *, Type_handler_hybrid_field_type *,
@ -6364,6 +6388,18 @@ public:
class Type_handler_geometry: public Type_handler_string_result class Type_handler_geometry: public Type_handler_string_result
{ {
static const Name m_name_geometry; static const Name m_name_geometry;
public:
enum geometry_types
{
GEOM_GEOMETRY = 0, GEOM_POINT = 1, GEOM_LINESTRING = 2, GEOM_POLYGON = 3,
GEOM_MULTIPOINT = 4, GEOM_MULTILINESTRING = 5, GEOM_MULTIPOLYGON = 6,
GEOM_GEOMETRYCOLLECTION = 7
};
static bool check_type_geom_or_binary(const char *opname, const Item *item);
static bool check_types_geom_or_binary(const char *opname,
Item * const *args,
uint start, uint end);
static const Type_handler_geometry *type_handler_geom_by_type(uint type);
public: public:
virtual ~Type_handler_geometry() {} virtual ~Type_handler_geometry() {}
const Name name() const { return m_name_geometry; } const Name name() const { return m_name_geometry; }
@ -6373,6 +6409,15 @@ public:
uint32 calc_pack_length(uint32 length) const; uint32 calc_pack_length(uint32 length) const;
const Type_collection *type_collection() const override; const Type_collection *type_collection() const override;
const Type_handler *type_handler_for_comparison() const; const Type_handler *type_handler_for_comparison() const;
virtual geometry_types geometry_type() const { return GEOM_GEOMETRY; }
const Type_handler *type_handler_frm_unpack(const uchar *buffer)
const override;
bool is_binary_compatible_geom_super_type_for(const Type_handler_geometry *th)
const
{
return geometry_type() == GEOM_GEOMETRY ||
geometry_type() == th->geometry_type();
}
bool type_can_have_key_part() const bool type_can_have_key_part() const
{ {
return true; return true;
@ -6410,6 +6455,21 @@ public:
bool Column_definition_prepare_stage2(Column_definition *c, bool Column_definition_prepare_stage2(Column_definition *c,
handler *file, handler *file,
ulonglong table_flags) const; ulonglong table_flags) const;
bool Key_part_spec_init_primary(Key_part_spec *part,
const Column_definition &def,
const handler *file) const override;
bool Key_part_spec_init_unique(Key_part_spec *part,
const Column_definition &def,
const handler *file,
bool *has_key_needed) const override;
bool Key_part_spec_init_multiple(Key_part_spec *part,
const Column_definition &def,
const handler *file) const override;
bool Key_part_spec_init_foreign(Key_part_spec *part,
const Column_definition &def,
const handler *file) const override;
bool Key_part_spec_init_spatial(Key_part_spec *part,
const Column_definition &def) const override;
Field *make_table_field(const LEX_CSTRING *name, Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr, const Record_addr &addr,
const Type_all_attributes &attr, const Type_all_attributes &attr,
@ -6457,7 +6517,86 @@ public:
bool Item_datetime_typecast_fix_length_and_dec(Item_datetime_typecast *) const; bool Item_datetime_typecast_fix_length_and_dec(Item_datetime_typecast *) const;
}; };
extern MYSQL_PLUGIN_IMPORT Type_handler_geometry type_handler_geometry;
class Type_handler_point: public Type_handler_geometry
{
static const Name m_name_point;
// Binary length of a POINT value: 4 byte SRID + 21 byte WKB POINT
static uint octet_length() { return 25; }
public:
geometry_types geometry_type() const { return GEOM_POINT; }
const Name name() const { return m_name_point; }
bool Key_part_spec_init_primary(Key_part_spec *part,
const Column_definition &def,
const handler *file) const override;
bool Key_part_spec_init_unique(Key_part_spec *part,
const Column_definition &def,
const handler *file,
bool *has_key_needed) const override;
bool Key_part_spec_init_multiple(Key_part_spec *part,
const Column_definition &def,
const handler *file) const override;
bool Key_part_spec_init_foreign(Key_part_spec *part,
const Column_definition &def,
const handler *file) const override;
};
class Type_handler_linestring: public Type_handler_geometry
{
static const Name m_name_linestring;
public:
geometry_types geometry_type() const { return GEOM_LINESTRING; }
const Name name() const { return m_name_linestring; }
};
class Type_handler_polygon: public Type_handler_geometry
{
static const Name m_name_polygon;
public:
geometry_types geometry_type() const { return GEOM_POLYGON; }
const Name name() const { return m_name_polygon; }
};
class Type_handler_multipoint: public Type_handler_geometry
{
static const Name m_name_multipoint;
public:
geometry_types geometry_type() const { return GEOM_MULTIPOINT; }
const Name name() const { return m_name_multipoint; }
};
class Type_handler_multilinestring: public Type_handler_geometry
{
static const Name m_name_multilinestring;
public:
geometry_types geometry_type() const { return GEOM_MULTILINESTRING; }
const Name name() const { return m_name_multilinestring; }
};
class Type_handler_multipolygon: public Type_handler_geometry
{
static const Name m_name_multipolygon;
public:
geometry_types geometry_type() const { return GEOM_MULTIPOLYGON; }
const Name name() const { return m_name_multipolygon; }
};
class Type_handler_geometrycollection: public Type_handler_geometry
{
static const Name m_name_geometrycollection;
public:
geometry_types geometry_type() const { return GEOM_GEOMETRYCOLLECTION; }
const Name name() const { return m_name_geometrycollection; }
};
extern MYSQL_PLUGIN_IMPORT Type_handler_geometry type_handler_geometry;
extern MYSQL_PLUGIN_IMPORT Type_handler_point type_handler_point;
extern MYSQL_PLUGIN_IMPORT Type_handler_linestring type_handler_linestring;
extern MYSQL_PLUGIN_IMPORT Type_handler_polygon type_handler_polygon;
extern MYSQL_PLUGIN_IMPORT Type_handler_multipoint type_handler_multipoint;
extern MYSQL_PLUGIN_IMPORT Type_handler_multilinestring type_handler_multilinestring;
extern MYSQL_PLUGIN_IMPORT Type_handler_multipolygon type_handler_multipolygon;
extern MYSQL_PLUGIN_IMPORT Type_handler_geometrycollection type_handler_geometrycollection;
#endif #endif

View file

@ -792,7 +792,6 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
enum Condition_information_item::Name cond_info_item_name; enum Condition_information_item::Name cond_info_item_name;
enum enum_diag_condition_item_name diag_condition_item_name; enum enum_diag_condition_item_name diag_condition_item_name;
enum Diagnostics_information::Which_area diag_area; enum Diagnostics_information::Which_area diag_area;
enum Field::geometry_type geom_type;
enum enum_fk_option m_fk_option; enum enum_fk_option m_fk_option;
enum Item_udftype udf_type; enum Item_udftype udf_type;
enum Key::Keytype key_type; enum Key::Keytype key_type;
@ -1832,7 +1831,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <create_field> field_spec column_def %type <create_field> field_spec column_def
%type <geom_type> spatial_type %type <type_handler> spatial_type
%type <num> %type <num>
order_dir lock_option order_dir lock_option
@ -7013,8 +7012,7 @@ field_type_lob:
{ {
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
Lex->charset=&my_charset_bin; Lex->charset=&my_charset_bin;
Lex->last_field->geom_type= $1; $$.set($1, $2);
$$.set(&type_handler_geometry, $2);
#else #else
my_yyabort_error((ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name, my_yyabort_error((ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name,
sym_group_geom.needed_define)); sym_group_geom.needed_define));
@ -7064,14 +7062,14 @@ field_type_misc:
; ;
spatial_type: spatial_type:
GEOMETRY_SYM { $$= Field::GEOM_GEOMETRY; } GEOMETRY_SYM { $$= GEOM_TYPE(&type_handler_geometry); }
| GEOMETRYCOLLECTION { $$= Field::GEOM_GEOMETRYCOLLECTION; } | GEOMETRYCOLLECTION { $$= GEOM_TYPE(&type_handler_geometrycollection); }
| POINT_SYM { $$= Field::GEOM_POINT; } | POINT_SYM { $$= GEOM_TYPE(&type_handler_point); }
| MULTIPOINT { $$= Field::GEOM_MULTIPOINT; } | MULTIPOINT { $$= GEOM_TYPE(&type_handler_multipoint); }
| LINESTRING { $$= Field::GEOM_LINESTRING; } | LINESTRING { $$= GEOM_TYPE(&type_handler_linestring); }
| MULTILINESTRING { $$= Field::GEOM_MULTILINESTRING; } | MULTILINESTRING { $$= GEOM_TYPE(&type_handler_multilinestring); }
| POLYGON { $$= Field::GEOM_POLYGON; } | POLYGON { $$= GEOM_TYPE(&type_handler_polygon); }
| MULTIPOLYGON { $$= Field::GEOM_MULTIPOLYGON; } | MULTIPOLYGON { $$= GEOM_TYPE(&type_handler_multipolygon); }
; ;
char: char:
@ -11049,38 +11047,23 @@ geometry_function:
} }
| GEOMETRYCOLLECTION '(' expr_list ')' | GEOMETRYCOLLECTION '(' expr_list ')'
{ {
$$= GEOM_NEW(thd, $$= GEOM_NEW(thd, Item_func_geometrycollection(thd, *$3));
Item_func_spatial_collection(thd, *$3,
Geometry::wkb_geometrycollection,
Geometry::wkb_point));
} }
| LINESTRING '(' expr_list ')' | LINESTRING '(' expr_list ')'
{ {
$$= GEOM_NEW(thd, $$= GEOM_NEW(thd, Item_func_linestring(thd, *$3));
Item_func_spatial_collection(thd, *$3,
Geometry::wkb_linestring,
Geometry::wkb_point));
} }
| MULTILINESTRING '(' expr_list ')' | MULTILINESTRING '(' expr_list ')'
{ {
$$= GEOM_NEW(thd, $$= GEOM_NEW(thd, Item_func_multilinestring(thd, *$3));
Item_func_spatial_collection(thd, *$3,
Geometry::wkb_multilinestring,
Geometry::wkb_linestring));
} }
| MULTIPOINT '(' expr_list ')' | MULTIPOINT '(' expr_list ')'
{ {
$$= GEOM_NEW(thd, $$= GEOM_NEW(thd, Item_func_multipoint(thd, *$3));
Item_func_spatial_collection(thd, *$3,
Geometry::wkb_multipoint,
Geometry::wkb_point));
} }
| MULTIPOLYGON '(' expr_list ')' | MULTIPOLYGON '(' expr_list ')'
{ {
$$= GEOM_NEW(thd, $$= GEOM_NEW(thd, Item_func_multipolygon(thd, *$3));
Item_func_spatial_collection(thd, *$3,
Geometry::wkb_multipolygon,
Geometry::wkb_polygon));
} }
| POINT_SYM '(' expr ',' expr ')' | POINT_SYM '(' expr ',' expr ')'
{ {
@ -11088,10 +11071,7 @@ geometry_function:
} }
| POLYGON '(' expr_list ')' | POLYGON '(' expr_list ')'
{ {
$$= GEOM_NEW(thd, $$= GEOM_NEW(thd, Item_func_polygon(thd, *$3));
Item_func_spatial_collection(thd, *$3,
Geometry::wkb_polygon,
Geometry::wkb_linestring));
} }
| WITHIN '(' expr ',' expr ')' | WITHIN '(' expr ',' expr ')'
{ {

View file

@ -259,7 +259,6 @@ void ORAerror(THD *thd, const char *s)
enum Condition_information_item::Name cond_info_item_name; enum Condition_information_item::Name cond_info_item_name;
enum enum_diag_condition_item_name diag_condition_item_name; enum enum_diag_condition_item_name diag_condition_item_name;
enum Diagnostics_information::Which_area diag_area; enum Diagnostics_information::Which_area diag_area;
enum Field::geometry_type geom_type;
enum enum_fk_option m_fk_option; enum enum_fk_option m_fk_option;
enum Item_udftype udf_type; enum Item_udftype udf_type;
enum Key::Keytype key_type; enum Key::Keytype key_type;
@ -1305,7 +1304,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <create_field> field_spec column_def %type <create_field> field_spec column_def
%type <geom_type> spatial_type %type <type_handler> spatial_type
%type <num> %type <num>
order_dir lock_option order_dir lock_option
@ -7064,8 +7063,7 @@ field_type_lob:
{ {
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
Lex->charset=&my_charset_bin; Lex->charset=&my_charset_bin;
Lex->last_field->geom_type= $1; $$.set($1, $2);
$$.set(&type_handler_geometry, $2);
#else #else
my_yyabort_error((ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name, my_yyabort_error((ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name,
sym_group_geom.needed_define)); sym_group_geom.needed_define));
@ -7115,14 +7113,14 @@ field_type_misc:
; ;
spatial_type: spatial_type:
GEOMETRY_SYM { $$= Field::GEOM_GEOMETRY; } GEOMETRY_SYM { $$= GEOM_TYPE(&type_handler_geometry); }
| GEOMETRYCOLLECTION { $$= Field::GEOM_GEOMETRYCOLLECTION; } | GEOMETRYCOLLECTION { $$= GEOM_TYPE(&type_handler_geometrycollection); }
| POINT_SYM { $$= Field::GEOM_POINT; } | POINT_SYM { $$= GEOM_TYPE(&type_handler_point); }
| MULTIPOINT { $$= Field::GEOM_MULTIPOINT; } | MULTIPOINT { $$= GEOM_TYPE(&type_handler_multipoint); }
| LINESTRING { $$= Field::GEOM_LINESTRING; } | LINESTRING { $$= GEOM_TYPE(&type_handler_linestring); }
| MULTILINESTRING { $$= Field::GEOM_MULTILINESTRING; } | MULTILINESTRING { $$= GEOM_TYPE(&type_handler_multilinestring); }
| POLYGON { $$= Field::GEOM_POLYGON; } | POLYGON { $$= GEOM_TYPE(&type_handler_polygon); }
| MULTIPOLYGON { $$= Field::GEOM_MULTIPOLYGON; } | MULTIPOLYGON { $$= GEOM_TYPE(&type_handler_multipolygon); }
; ;
char: char:
@ -11149,38 +11147,23 @@ geometry_function:
} }
| GEOMETRYCOLLECTION '(' expr_list ')' | GEOMETRYCOLLECTION '(' expr_list ')'
{ {
$$= GEOM_NEW(thd, $$= GEOM_NEW(thd, Item_func_geometrycollection(thd, *$3));
Item_func_spatial_collection(thd, *$3,
Geometry::wkb_geometrycollection,
Geometry::wkb_point));
} }
| LINESTRING '(' expr_list ')' | LINESTRING '(' expr_list ')'
{ {
$$= GEOM_NEW(thd, $$= GEOM_NEW(thd, Item_func_linestring(thd, *$3));
Item_func_spatial_collection(thd, *$3,
Geometry::wkb_linestring,
Geometry::wkb_point));
} }
| MULTILINESTRING '(' expr_list ')' | MULTILINESTRING '(' expr_list ')'
{ {
$$= GEOM_NEW(thd, $$= GEOM_NEW(thd, Item_func_multilinestring(thd, *$3));
Item_func_spatial_collection(thd, *$3,
Geometry::wkb_multilinestring,
Geometry::wkb_linestring));
} }
| MULTIPOINT '(' expr_list ')' | MULTIPOINT '(' expr_list ')'
{ {
$$= GEOM_NEW(thd, $$= GEOM_NEW(thd, Item_func_multipoint(thd, *$3));
Item_func_spatial_collection(thd, *$3,
Geometry::wkb_multipoint,
Geometry::wkb_point));
} }
| MULTIPOLYGON '(' expr_list ')' | MULTIPOLYGON '(' expr_list ')'
{ {
$$= GEOM_NEW(thd, $$= GEOM_NEW(thd, Item_func_multipolygon(thd, *$3));
Item_func_spatial_collection(thd, *$3,
Geometry::wkb_multipolygon,
Geometry::wkb_polygon));
} }
| POINT_SYM '(' expr ',' expr ')' | POINT_SYM '(' expr ',' expr ')'
{ {
@ -11188,10 +11171,7 @@ geometry_function:
} }
| POLYGON '(' expr_list ')' | POLYGON '(' expr_list ')'
{ {
$$= GEOM_NEW(thd, $$= GEOM_NEW(thd, Item_func_polygon(thd, *$3));
Item_func_spatial_collection(thd, *$3,
Geometry::wkb_polygon,
Geometry::wkb_linestring));
} }
| WITHIN '(' expr ',' expr ')' | WITHIN '(' expr ',' expr ')'
{ {

View file

@ -2190,6 +2190,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
enum_field_types field_type= (enum_field_types) strpos[13]; enum_field_types field_type= (enum_field_types) strpos[13];
if (!(handler= Type_handler::get_handler_by_real_type(field_type))) if (!(handler= Type_handler::get_handler_by_real_type(field_type)))
goto err; // Not supported field type goto err; // Not supported field type
handler= handler->type_handler_frm_unpack(strpos);
if (handler->Column_definition_attributes_frm_unpack(&attr, share, if (handler->Column_definition_attributes_frm_unpack(&attr, share,
strpos, strpos,
&extra2.gis)) &extra2.gis))