Commit d17f4d9d authored by Alexander Barkov's avatar Alexander Barkov

Bug#26180 Can't add columns to tables created with utf8 (regular) text indexes

Backporting from 6.0.
parent 510844e7
...@@ -1881,6 +1881,23 @@ CONVERT(a, CHAR) CONVERT(b, CHAR) ...@@ -1881,6 +1881,23 @@ CONVERT(a, CHAR) CONVERT(b, CHAR)
DROP TABLE t1; DROP TABLE t1;
End of 5.0 tests End of 5.0 tests
Start of 5.4 tests Start of 5.4 tests
CREATE TABLE t1 (
clipid INT NOT NULL,
Tape TINYTEXT,
PRIMARY KEY (clipid),
KEY tape(Tape(255))
) CHARACTER SET=utf8;
ALTER TABLE t1 ADD mos TINYINT DEFAULT 0 AFTER clipid;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`clipid` int(11) NOT NULL,
`mos` tinyint(4) DEFAULT '0',
`Tape` tinytext,
PRIMARY KEY (`clipid`),
KEY `tape` (`Tape`(255))
) ENGINE=MyISAM DEFAULT CHARSET=utf8
DROP TABLE t1;
DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t1;
CREATE TABLE t1 ( CREATE TABLE t1 (
predicted_order int NOT NULL, predicted_order int NOT NULL,
......
...@@ -1459,6 +1459,19 @@ DROP TABLE t1; ...@@ -1459,6 +1459,19 @@ DROP TABLE t1;
--echo Start of 5.4 tests --echo Start of 5.4 tests
#
# Bug#26180: Can't add columns to tables created with utf8 text indexes
#
CREATE TABLE t1 (
clipid INT NOT NULL,
Tape TINYTEXT,
PRIMARY KEY (clipid),
KEY tape(Tape(255))
) CHARACTER SET=utf8;
ALTER TABLE t1 ADD mos TINYINT DEFAULT 0 AFTER clipid;
SHOW CREATE TABLE t1;
DROP TABLE t1;
# #
# Bug#26474: Add Sinhala script (Sri Lanka) collation to MySQL # Bug#26474: Add Sinhala script (Sri Lanka) collation to MySQL
# #
......
...@@ -5933,6 +5933,35 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled, ...@@ -5933,6 +5933,35 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
} }
/**
maximum possible length for certain blob types.
@param[in] type Blob type (e.g. MYSQL_TYPE_TINY_BLOB)
@return
length
*/
static uint
blob_length_by_type(enum_field_types type)
{
switch (type)
{
case MYSQL_TYPE_TINY_BLOB:
return 255;
case MYSQL_TYPE_BLOB:
return 65535;
case MYSQL_TYPE_MEDIUM_BLOB:
return 16777215;
case MYSQL_TYPE_LONG_BLOB:
return 4294967295U;
default:
DBUG_ASSERT(0); // we should never go here
return 0;
}
}
/** /**
Prepare column and key definitions for CREATE TABLE in ALTER TABLE. Prepare column and key definitions for CREATE TABLE in ALTER TABLE.
...@@ -6228,6 +6257,14 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, ...@@ -6228,6 +6257,14 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
BLOBs may have cfield->length == 0, which is why we test it before BLOBs may have cfield->length == 0, which is why we test it before
checking whether cfield->length < key_part_length (in chars). checking whether cfield->length < key_part_length (in chars).
In case of TEXTs we check the data type maximum length *in bytes*
to key part length measured *in characters* (i.e. key_part_length
devided to mbmaxlen). This is because it's OK to have:
CREATE TABLE t1 (a tinytext, key(a(254)) character set utf8);
In case of this example:
- data type maximum length is 255.
- key_part_length is 1016 (=254*4, where 4 is mbmaxlen)
*/ */
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) ||
...@@ -6235,8 +6272,11 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, ...@@ -6235,8 +6272,11 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
(key_info->flags & HA_SPATIAL) || (key_info->flags & HA_SPATIAL) ||
(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->sql_type >= MYSQL_TYPE_TINY_BLOB &&
key_part->field->charset()->mbmaxlen))) cfield->sql_type <= MYSQL_TYPE_BLOB) ?
blob_length_by_type(cfield->sql_type) :
cfield->length) <
key_part_length / key_part->field->charset()->mbmaxlen)))
key_part_length= 0; // Use whole field key_part_length= 0; // Use whole field
} }
key_part_length /= key_part->field->charset()->mbmaxlen; key_part_length /= key_part->field->charset()->mbmaxlen;
......
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