Bug #26794:

Different set of conditions is used to verify
the validity of index definitions over a GEOMETRY
column in ALTER TABLE and CREATE TABLE. 
The difference was on how sub-keys notion validity
is checked.
Fixed by extending the CREATE TABLE condition to
support the cases allowed in ALTER TABLE.
Made the SHOW CREATE TABLE not to display spatial
indexes using the sub-key notion.
parent 946745e1
...@@ -826,3 +826,37 @@ create table t1 (t varchar(255) default null, key t (t(80))) ...@@ -826,3 +826,37 @@ create table t1 (t varchar(255) default null, key t (t(80)))
engine=myisam default charset=latin1; engine=myisam default charset=latin1;
alter table t1 change t t text; alter table t1 change t t text;
drop table t1; drop table t1;
CREATE TABLE t1 (a varchar(500));
ALTER TABLE t1 ADD b GEOMETRY NOT NULL, ADD SPATIAL INDEX(b);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(500) default NULL,
`b` geometry NOT NULL,
SPATIAL KEY `b` (`b`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
ALTER TABLE t1 ADD KEY(b(50));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(500) default NULL,
`b` geometry NOT NULL,
SPATIAL KEY `b` (`b`),
KEY `b_2` (`b`(50))
) ENGINE=MyISAM DEFAULT CHARSET=latin1
ALTER TABLE t1 ADD c POINT;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(500) default NULL,
`b` geometry NOT NULL,
`c` point default NULL,
SPATIAL KEY `b` (`b`),
KEY `b_2` (`b`(50))
) ENGINE=MyISAM DEFAULT CHARSET=latin1
CREATE TABLE t2 (a INT, KEY (a(20)));
ERROR HY000: Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys
ALTER TABLE t1 ADD d INT;
ALTER TABLE t1 ADD KEY (d(20));
ERROR HY000: Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys
DROP TABLE t1;
...@@ -10,7 +10,7 @@ t1 CREATE TABLE `t1` ( ...@@ -10,7 +10,7 @@ t1 CREATE TABLE `t1` (
`fid` int(11) NOT NULL auto_increment, `fid` int(11) NOT NULL auto_increment,
`g` geometry NOT NULL, `g` geometry NOT NULL,
PRIMARY KEY (`fid`), PRIMARY KEY (`fid`),
SPATIAL KEY `g` (`g`(32)) SPATIAL KEY `g` (`g`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 (g) VALUES (GeomFromText('LineString(150 150, 150 150)')); INSERT INTO t1 (g) VALUES (GeomFromText('LineString(150 150, 150 150)'));
INSERT INTO t1 (g) VALUES (GeomFromText('LineString(149 149, 151 151)')); INSERT INTO t1 (g) VALUES (GeomFromText('LineString(149 149, 151 151)'));
...@@ -293,7 +293,7 @@ t2 CREATE TABLE `t2` ( ...@@ -293,7 +293,7 @@ t2 CREATE TABLE `t2` (
`fid` int(11) NOT NULL auto_increment, `fid` int(11) NOT NULL auto_increment,
`g` geometry NOT NULL, `g` geometry NOT NULL,
PRIMARY KEY (`fid`), PRIMARY KEY (`fid`),
SPATIAL KEY `g` (`g`(32)) SPATIAL KEY `g` (`g`)
) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=latin1 ) ENGINE=MyISAM AUTO_INCREMENT=101 DEFAULT CHARSET=latin1
SELECT count(*) FROM t2; SELECT count(*) FROM t2;
count(*) count(*)
......
...@@ -613,3 +613,26 @@ create table t1 (t varchar(255) default null, key t (t(80))) ...@@ -613,3 +613,26 @@ create table t1 (t varchar(255) default null, key t (t(80)))
engine=myisam default charset=latin1; engine=myisam default charset=latin1;
alter table t1 change t t text; alter table t1 change t t text;
drop table t1; drop table t1;
#
# Bug #26794: Adding an index with a prefix on a SPATIAL type breaks ALTER
# TABLE
#
CREATE TABLE t1 (a varchar(500));
ALTER TABLE t1 ADD b GEOMETRY NOT NULL, ADD SPATIAL INDEX(b);
SHOW CREATE TABLE t1;
ALTER TABLE t1 ADD KEY(b(50));
SHOW CREATE TABLE t1;
ALTER TABLE t1 ADD c POINT;
SHOW CREATE TABLE t1;
--error ER_WRONG_SUB_KEY
CREATE TABLE t2 (a INT, KEY (a(20)));
ALTER TABLE t1 ADD d INT;
--error ER_WRONG_SUB_KEY
ALTER TABLE t1 ADD KEY (d(20));
DROP TABLE t1;
...@@ -1011,6 +1011,7 @@ bool Field::type_can_have_key_part(enum enum_field_types type) ...@@ -1011,6 +1011,7 @@ bool Field::type_can_have_key_part(enum enum_field_types type)
case MYSQL_TYPE_BLOB: case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING: case MYSQL_TYPE_STRING:
case MYSQL_TYPE_GEOMETRY:
return TRUE; return TRUE;
default: default:
return FALSE; return FALSE;
......
...@@ -992,7 +992,7 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet) ...@@ -992,7 +992,7 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
if (key_part->field && if (key_part->field &&
(key_part->length != (key_part->length !=
table->field[key_part->fieldnr-1]->key_length() && table->field[key_part->fieldnr-1]->key_length() &&
!(key_info->flags & HA_FULLTEXT))) !(key_info->flags & (HA_FULLTEXT | HA_SPATIAL))))
{ {
buff[0] = '('; buff[0] = '(';
char* end=int10_to_str((long) key_part->length / char* end=int10_to_str((long) key_part->length /
......
...@@ -1344,6 +1344,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -1344,6 +1344,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
} }
else if (!f_is_geom(sql_field->pack_flag) && else if (!f_is_geom(sql_field->pack_flag) &&
(column->length > length || (column->length > length ||
!Field::type_can_have_key_part (sql_field->sql_type) ||
((f_is_packed(sql_field->pack_flag) || ((f_is_packed(sql_field->pack_flag) ||
((file->table_flags() & HA_NO_PREFIX_CHAR_KEYS) && ((file->table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
(key_info->flags & HA_NOSAME))) && (key_info->flags & HA_NOSAME))) &&
...@@ -3470,7 +3471,8 @@ view_err: ...@@ -3470,7 +3471,8 @@ view_err:
checking whether cfield->length < key_part_length (in chars). checking whether cfield->length < key_part_length (in chars).
*/ */
if (!Field::type_can_have_key_part(cfield->field->type()) || if (!Field::type_can_have_key_part(cfield->field->type()) ||
!Field::type_can_have_key_part(cfield->sql_type) || (!Field::type_can_have_key_part(cfield->sql_type) &&
!f_is_geom (cfield->pack_flag)) ||
(cfield->field->field_length == key_part_length && (cfield->field->field_length == key_part_length &&
!f_is_blob(key_part->key_type)) || !f_is_blob(key_part->key_type)) ||
(cfield->length && (cfield->length < key_part_length / (cfield->length && (cfield->length < key_part_length /
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment