Commit b2ddac55 authored by Magne Mahre's avatar Magne Mahre

Bug#50542 5.5.x doesn't check length of key prefixes:

          corruption and crash results
      
An index creation statement where the index key
is larger/wider than the column it references 
should throw an error.
      
A statement like:
  CREATE TABLE t1 (a CHAR(1), PRIMARY KEY (A(255)))
did not error, but a segmentation fault followed when
an insertion was attempted on the table
      
The partial key validiation clause has been 
restructured to (hopefully) better document which
uses of partial keys are valid.
parent 21e68e4f
...@@ -1354,3 +1354,15 @@ DROP i, ...@@ -1354,3 +1354,15 @@ DROP i,
ADD i INT UNSIGNED NOT NULL AUTO_INCREMENT, ADD i INT UNSIGNED NOT NULL AUTO_INCREMENT,
AUTO_INCREMENT = 1; AUTO_INCREMENT = 1;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (a CHAR(1), PRIMARY KEY (a(255)));
ERROR HY000: Incorrect prefix 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 prefix keys
CREATE TABLE t1 (a CHAR(1));
ALTER TABLE t1 ADD PRIMARY KEY (a(20));
ERROR HY000: Incorrect prefix 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 prefix keys
ALTER TABLE t1 ADD KEY (a(20));
ERROR HY000: Incorrect prefix 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 prefix keys
CREATE UNIQUE INDEX i1 ON t1 (a(20));
ERROR HY000: Incorrect prefix 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 prefix keys
CREATE INDEX i2 ON t1 (a(20));
ERROR HY000: Incorrect prefix 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 prefix keys
DROP TABLE t1;
...@@ -1089,3 +1089,31 @@ ALTER TABLE t1 ...@@ -1089,3 +1089,31 @@ ALTER TABLE t1
ADD i INT UNSIGNED NOT NULL AUTO_INCREMENT, ADD i INT UNSIGNED NOT NULL AUTO_INCREMENT,
AUTO_INCREMENT = 1; AUTO_INCREMENT = 1;
DROP TABLE t1; DROP TABLE t1;
#
# Bug#50542 5.5.x doesn't check length of key prefixes:
# corruption and crash results
#
# This case is related to Bug#31031 (above)
# A statement where the index key is larger/wider than
# the column type, should cause an error
#
--error ER_WRONG_SUB_KEY
CREATE TABLE t1 (a CHAR(1), PRIMARY KEY (a(255)));
# Test other variants of creating indices
CREATE TABLE t1 (a CHAR(1));
# ALTER TABLE
--error ER_WRONG_SUB_KEY
ALTER TABLE t1 ADD PRIMARY KEY (a(20));
--error ER_WRONG_SUB_KEY
ALTER TABLE t1 ADD KEY (a(20));
# CREATE INDEX
--error ER_WRONG_SUB_KEY
CREATE UNIQUE INDEX i1 ON t1 (a(20));
--error ER_WRONG_SUB_KEY
CREATE INDEX i2 ON t1 (a(20));
# cleanup
DROP TABLE t1;
...@@ -3292,22 +3292,21 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -3292,22 +3292,21 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
} }
} }
} }
// Catch invalid use of partial keys
else if (!f_is_geom(sql_field->pack_flag) && else if (!f_is_geom(sql_field->pack_flag) &&
((column->length > length && // is the key partial?
!Field::type_can_have_key_part (sql_field->sql_type)) || column->length != length &&
((f_is_packed(sql_field->pack_flag) || // is prefix length bigger than field length?
((file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS) && (column->length > length ||
(key_info->flags & HA_NOSAME))) && // can the field have a partial key?
column->length != length))) !Field::type_can_have_key_part (sql_field->sql_type) ||
{ // a packed field can't be used in a partial key
/* Catch invalid uses of partial keys. f_is_packed(sql_field->pack_flag) ||
A key is identified as 'partial' if column->length != length. // does the storage engine allow prefixed search?
A partial key is invalid if they data type does ((file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
not allow it, or the field is packed (as in MyISAM), // and is this a 'unique' key?
or the storage engine doesn't allow prefixed search and (key_info->flags & HA_NOSAME))))
the key is primary key. {
*/
my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0)); my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0));
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
......
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