List:Commits« Previous MessageNext Message »
From:Alexander Barkov Date:November 9 2009 11:35am
Subject:bzr commit into mysql-5.5-next-mr-bugfixing branch (bar:2944) Bug#26180
View as plain text  
#At file:///home/bar/mysql-bzr/mysql-next-mr-bugfixing/ based on revid:bar@stripped

 2944 Alexander Barkov	2009-11-09
      Bug#26180 Can't add columns to tables created with utf8 (regular) text indexes
      Backporting from 6.0.

    modified:
      mysql-test/r/ctype_utf8.result
      mysql-test/t/ctype_utf8.test
      sql/sql_table.cc
=== modified file 'mysql-test/r/ctype_utf8.result'
--- a/mysql-test/r/ctype_utf8.result	2009-10-15 12:23:43 +0000
+++ b/mysql-test/r/ctype_utf8.result	2009-11-09 11:35:18 +0000
@@ -1881,6 +1881,23 @@ CONVERT(a, CHAR)	CONVERT(b, CHAR)
 DROP TABLE t1;
 End of 5.0 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;
 CREATE TABLE t1 (
 predicted_order int NOT NULL,

=== modified file 'mysql-test/t/ctype_utf8.test'
--- a/mysql-test/t/ctype_utf8.test	2009-10-06 10:34:49 +0000
+++ b/mysql-test/t/ctype_utf8.test	2009-11-09 11:35:18 +0000
@@ -1460,6 +1460,19 @@ DROP TABLE t1;
 
 --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
 #
 --disable_warnings

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2009-10-21 10:48:22 +0000
+++ b/sql/sql_table.cc	2009-11-09 11:35:18 +0000
@@ -5934,6 +5934,35 @@ bool alter_table_manage_keys(TABLE *tabl
 
 
 /**
+  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.
 
   This function transforms parse output of ALTER TABLE - lists of
@@ -6228,6 +6257,14 @@ mysql_prepare_alter_table(THD *thd, TABL
 
           BLOBs may have cfield->length == 0, which is why we test it before
           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()) ||
             !Field::type_can_have_key_part(cfield->sql_type) ||
@@ -6235,8 +6272,11 @@ mysql_prepare_alter_table(THD *thd, TABL
             (key_info->flags & HA_SPATIAL) ||
             (cfield->field->field_length == key_part_length &&
              !f_is_blob(key_part->key_type)) ||
-	    (cfield->length && (cfield->length < key_part_length /
-                                key_part->field->charset()->mbmaxlen)))
+            (cfield->length && (((cfield->sql_type >= MYSQL_TYPE_TINY_BLOB &&
+                                  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 /= key_part->field->charset()->mbmaxlen;


Attachment: [text/bzr-bundle] bzr/bar@mysql.com-20091109113518-4nz701wqpo9it753.bundle
Thread
bzr commit into mysql-5.5-next-mr-bugfixing branch (bar:2944) Bug#26180Alexander Barkov9 Nov