List:Commits« Previous MessageNext Message »
From:Raghav Kapoor Date:April 30 2012 7:14am
Subject:bzr push into mysql-trunk branch (raghav.kapoor:3750 to 3751) Bug#11746295
View as plain text  
 3751 Raghav Kapoor	2012-04-30
      BUG#11746295 - 25168: "INCORRECT TABLE NAME" INSTEAD OF 
      		      "IDENTIFIER TOO LONG" IF TABLE NAME > 64 
      
      BACKGROUND:
      When table/database name is more then 64 character, 
      "Incorrect table name" error is thrown. But expected error 
      is "Identifier too long".
      
      FIX:
      This bug has been fixed by reporting ER_TOO_LONG_IDENT error 
      when table/database/function/procedure name etc is greater 
      than 64 characters. 
      Also please note the behaviour changes in check_table_name() 
      and check_and_convert_db_name() functions in table.cc file. 
      Their return type has been changed accordingly to report 
      the appropriate error and now they return enum instead of 
      bool. Other files have also been appropriately modified at 
      relevant places to report the appropriate error in each 
      case.
      Also a testcase has been written in create.test and 
      corresponding result files have been updated.

    modified:
      mysql-test/r/create.result
      mysql-test/r/ctype_create.result
      mysql-test/r/drop.result
      mysql-test/r/events_2.result
      mysql-test/r/mysql.result
      mysql-test/t/create.test
      mysql-test/t/ctype_create.test
      mysql-test/t/drop.test
      mysql-test/t/events_2.test
      mysql-test/t/overflow.test
      sql/datadict.cc
      sql/partition_info.cc
      sql/sql_db.cc
      sql/sql_parse.cc
      sql/sql_table.cc
      sql/sql_yacc.yy
      sql/table.cc
      sql/table.h
 3750 gopal.shankar@stripped	2012-04-30
      Bug#13979228 - MEMORY CORRUPTION IN READ_TEXTS() (SQL/DERROR.CC)
      
      PROBLEM:
      --------
      The following command could cause mysqld to crash.
      mysql> set LC_TIME_NAMES='ru_RU';
      
      The problem is seen only when there are more new error messages
      are added to sql/share/errmsg-utf8.txt, before compilation.
      
      ANALYSIS:-
      ----------
      errmsg-utf8.txt contains all the error messages. For faster access
      errmsg.sys files are created for each language. The errmsg.sys file
      has following file format.
      
      --------------------------------------------------------------
      Current errmsg.sys File Format:
      --------------------------------------------------------------
      SECTION1:
      Header=32 bytes,
         length = (uint16) of byte 6 & 7
         count  = (uint16) of byte 8 & 9
      
      SECTION2:
      Array of offset pointer to messages= count*2 bytes
         Every 2 bytes [after header, until header_size+count*2]
         contains offset of error message in the errmsg.sys file.
         These offsets point to section3.
      
      SECTION3:
      All error messages, each one is null terminated.
      --------------------------------------------------------------
      
      PROBLEM1) With the current file format, the length of SECTION3 is stored in
      errmsg.sys file header byte 6 and 7. These 2 bytes can hold maximum
      size of section till 2^16 = 64k. If the SECTION3 increases in size more
      than 64K, then these two bytes in header are not enough to hold the size.
      
      PROBLEM2) As the number of error message increase, the SECTION3 grows.
      Consequently, error messages could be places at offset greater than 2^16=64K.
      SECTION2 contains offsets that point to start of each error messages in
      SECTION3. If the error message is stored past 64K size in SECTION3, then the
      2 bytes element in offset array of SECTION2 will not be sufficient to
      store the offset.
      
      Above two problems might cause server to read invalid 'length'/'offset'. Due
      to which the code would write bytes more than allocated.
      
      FIX:
      ----
      Both of above mentioned problems, demand increase in number of bytes to hold
      the length (also count) of SECTION3 and offsets in SECTION2. Following changes
      in existing file format would solve the problem. Note that the header currently
      has many unused bytes, so using more bytes for length and count is not a problem.
      
      --------------------------------------------------------------
      New errmsg.sys File Format:
      --------------------------------------------------------------
      SECTION1:
      Header=32 bytes,
         length = (uint32) of byte 6 to 10
         count  = (uint32) of byte 10 to 14
      
      SECTION2:
      Array of offset pointer to messages= count*4 bytes
         Every 4 bytes [after header, until header_size+count*4]
         contains offset of error message in the errmsg.sys file.
         These offsets point to SECTION3.
      
      SECTION3:
      All error messages, each one is null terminated.
      --------------------------------------------------------------
      
      With the new changes to file format, the length, count in header and offset
      array in SECTION2 are now 4bytes instead of 2bytes. Hence, the errmsg.sys can
      can now grow upto 4GB (currently its 64K), which seem to be too-much-of-memory
      for error messages.
      
      Each errmsg.sys has version associated with it. Version is stored at
      3rd byte from begining of errmsg.sys. The current version of file is '2' and
      the new version will be '3'. If new mysql binary tries to use old errmsg.sys,
      we report an error.
      
      TESTING:
      --------
      This bug depends on number of messages in sql/share/errmsg-utf8.txt.
      As the size of errmsg.sys keeps changing over time, its hard to write
      test case based on it.

    modified:
      extra/comp_err.c
      sql/derror.cc
=== modified file 'mysql-test/r/create.result'
--- a/mysql-test/r/create.result	2012-03-19 17:59:14 +0000
+++ b/mysql-test/r/create.result	2012-04-30 07:13:31 +0000
@@ -51,7 +51,7 @@ create table t1 like `a/a`;
 drop table `a/a`;
 drop table `t1`;
 create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int);
-ERROR 42000: Incorrect table name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
 create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int);
 ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
 create table t1 (a int default 100 auto_increment);
@@ -1616,13 +1616,13 @@ a	b
 1	1
 drop table t1,t2;
 CREATE DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
-ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
 DROP DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
-ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
 USE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
-ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
 SHOW CREATE DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
-ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
 set names utf8;
 create database имя_базы_в_кодировке_утф8_длиной_боль_утф8_длиной_больше_чем_45;
@@ -2456,3 +2456,11 @@ drop function f;
 #
 CREATE TABLE t1 (v varchar(65535));
 ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
+#
+# Bug#11746295 - 25168: "INCORRECT TABLE NAME" INSTEAD OF "IDENTIFIER TOO
+#                       LONG" IF TABLE NAME > 64 CHARACTERS
+#
+CREATE TABLE t01234567890123456789012345678901234567890123456789012345678901234567890123456789(a int);
+ERROR 42000: Identifier name 't01234567890123456789012345678901234567890123456789012345678901234567890123456789' is too long
+CREATE DATABASE t01234567890123456789012345678901234567890123456789012345678901234567890123456789;
+ERROR 42000: Identifier name 't01234567890123456789012345678901234567890123456789012345678901234567890123456789' is too long

=== modified file 'mysql-test/r/ctype_create.result'
--- a/mysql-test/r/ctype_create.result	2006-10-16 16:57:33 +0000
+++ b/mysql-test/r/ctype_create.result	2012-04-30 07:13:31 +0000
@@ -73,6 +73,6 @@ drop database mysqltest2;
 ALTER DATABASE DEFAULT CHARACTER SET latin2;
 ERROR 3D000: No database selected
 ALTER DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa DEFAULT CHARACTER SET latin2;
-ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
 ALTER DATABASE `` DEFAULT CHARACTER SET latin2;
 ERROR 42000: Incorrect database name ''

=== modified file 'mysql-test/r/drop.result'
--- a/mysql-test/r/drop.result	2010-08-30 06:38:09 +0000
+++ b/mysql-test/r/drop.result	2012-04-30 07:13:31 +0000
@@ -135,11 +135,11 @@ create database mysqltestbug26703;
 use mysqltestbug26703;
 create table `#mysql50#abc``def` ( id int );
 create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
-ERROR 42000: Incorrect table name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
 create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
 create table `#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
 create table `#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
-ERROR 42000: Incorrect table name '#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+ERROR 42000: Identifier name '#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
 use test;
 drop database mysqltestbug26703;
 End of 5.1 tests

=== modified file 'mysql-test/r/events_2.result'
--- a/mysql-test/r/events_2.result	2011-11-09 10:55:44 +0000
+++ b/mysql-test/r/events_2.result	2012-04-30 07:13:31 +0000
@@ -115,7 +115,7 @@ ERROR 0A000: Not allowed to return a res
 drop table t1;
 drop event e1;
 SHOW EVENTS FROM aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
-ERROR 42000: Incorrect database name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
+ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
 SHOW EVENTS FROM ``;
 ERROR 42000: Incorrect database name ''
 SHOW EVENTS FROM `events\\test`;

=== modified file 'mysql-test/r/mysql.result'
--- a/mysql-test/r/mysql.result	2011-11-15 14:27:21 +0000
+++ b/mysql-test/r/mysql.result	2012-04-30 07:13:31 +0000
@@ -167,7 +167,7 @@ ERROR 2005 (HY000) at line 1: Unknown My
 The commands reported in the bug report
 ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'cyril has found a bug :)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' (errno)
 Too long dbname
-ERROR 1102 (42000) at line 1: Incorrect database name 'test_really_long_dbnamexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
+ERROR 1059 (42000) at line 1: Identifier name 'test_really_long_dbnamexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' is too long
 Too long hostname
 ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'cyrils_superlonghostnameXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' (errno)
 1

=== modified file 'mysql-test/t/create.test'
--- a/mysql-test/t/create.test	2012-03-19 17:59:14 +0000
+++ b/mysql-test/t/create.test	2012-04-30 07:13:31 +0000
@@ -47,7 +47,7 @@ show create table `a/a`;
 create table t1 like `a/a`;
 drop table `a/a`;
 drop table `t1`;
---error 1103
+--error ER_TOO_LONG_IDENT
 create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa int);
 --error 1059
 create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int);
@@ -1276,9 +1276,9 @@ drop table t1,t2;
 # Test incorrect database names
 #
 
---error 1102
+--error ER_TOO_LONG_IDENT
 CREATE DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
---error 1102
+--error ER_TOO_LONG_IDENT
 DROP DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
 
 # TODO: enable these tests when RENAME DATABASE is implemented.
@@ -1291,9 +1291,9 @@ DROP DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaa
 # RENAME DATABASE mysqltest TO aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
 # drop database mysqltest;
 
---error 1102
+--error ER_TOO_LONG_IDENT
 USE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
---error 1102
+--error ER_TOO_LONG_IDENT
 SHOW CREATE DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
 
 #
@@ -2086,3 +2086,13 @@ drop function f;
 
 --error ER_TOO_BIG_ROWSIZE
 CREATE TABLE t1 (v varchar(65535));
+
+--echo #
+--echo # Bug#11746295 - 25168: "INCORRECT TABLE NAME" INSTEAD OF "IDENTIFIER TOO
+--echo #                       LONG" IF TABLE NAME > 64 CHARACTERS
+--echo #
+
+--error ER_TOO_LONG_IDENT
+CREATE TABLE t01234567890123456789012345678901234567890123456789012345678901234567890123456789(a int);
+--error ER_TOO_LONG_IDENT
+CREATE DATABASE t01234567890123456789012345678901234567890123456789012345678901234567890123456789;

=== modified file 'mysql-test/t/ctype_create.test'
--- a/mysql-test/t/ctype_create.test	2006-10-16 16:57:33 +0000
+++ b/mysql-test/t/ctype_create.test	2012-04-30 07:13:31 +0000
@@ -101,7 +101,7 @@ ALTER DATABASE DEFAULT CHARACTER SET lat
 
 # End of 4.1 tests
 
---error 1102
+--error ER_TOO_LONG_IDENT
 ALTER DATABASE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa DEFAULT CHARACTER SET latin2;
 --error 1102
 ALTER DATABASE `` DEFAULT CHARACTER SET latin2;

=== modified file 'mysql-test/t/drop.test'
--- a/mysql-test/t/drop.test	2010-08-30 06:38:09 +0000
+++ b/mysql-test/t/drop.test	2012-04-30 07:13:31 +0000
@@ -225,11 +225,11 @@ DROP DATABASE mysql_test;
 create database mysqltestbug26703;
 use mysqltestbug26703;
 create table `#mysql50#abc``def` ( id int );
---error ER_WRONG_TABLE_NAME
+--error ER_TOO_LONG_IDENT
 create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
 create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
 create table `#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
---error ER_WRONG_TABLE_NAME
+--error ER_TOO_LONG_IDENT
 create table `#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
 use test;
 drop database mysqltestbug26703;

=== modified file 'mysql-test/t/events_2.test'
--- a/mysql-test/t/events_2.test	2010-11-11 17:11:05 +0000
+++ b/mysql-test/t/events_2.test	2012-04-30 07:13:31 +0000
@@ -187,7 +187,7 @@ drop event e1;
 # Test wrong syntax
 #
 
---error ER_WRONG_DB_NAME 
+--error ER_TOO_LONG_IDENT 
 SHOW EVENTS FROM aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
 --error ER_WRONG_DB_NAME
 SHOW EVENTS FROM ``;

=== modified file 'mysql-test/t/overflow.test'
--- a/mysql-test/t/overflow.test	2009-02-05 20:47:23 +0000
+++ b/mysql-test/t/overflow.test	2012-04-30 07:13:31 +0000
@@ -3,7 +3,7 @@
 
 connect (con1,localhost,root,,);
 connection con1;
---error ER_PARSE_ERROR,ER_WRONG_DB_NAME,ER_WRONG_NAME_FOR_INDEX
+--error ER_PARSE_ERROR,ER_TOO_LONG_IDENT,ER_WRONG_NAME_FOR_INDEX
 drop database AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA;
 connection default;
 disconnect con1;

=== modified file 'sql/datadict.cc'
--- a/sql/datadict.cc	2010-08-20 09:15:16 +0000
+++ b/sql/datadict.cc	2012-04-30 07:13:31 +0000
@@ -90,17 +90,21 @@ bool dd_frm_storage_engine(THD *thd, con
   DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db,
                                              table_name, MDL_SHARED));
 
-  if (check_and_convert_db_name(&db_name, FALSE))
-  {
-    my_error(ER_WRONG_DB_NAME, MYF(0), db_name.str);
+  if (check_and_convert_db_name(&db_name, FALSE) != IDENT_NAME_OK)
     return TRUE;
-  }
 
-  if (check_table_name(table_name, strlen(table_name), FALSE))
+  enum_ident_name_check ident_check_status=
+    check_table_name(table_name, strlen(table_name), FALSE);
+  if (ident_check_status == IDENT_NAME_WRONG)
   {
     my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name);
     return TRUE;
   }
+  else if (ident_check_status == IDENT_NAME_TOO_LONG)
+  {
+    my_error(ER_TOO_LONG_IDENT, MYF(0), table_name);
+    return TRUE;
+  }
 
   (void) build_table_filename(path, sizeof(path) - 1, db,
                               table_name, reg_ext, 0);

=== modified file 'sql/partition_info.cc'
--- a/sql/partition_info.cc	2012-04-16 09:26:56 +0000
+++ b/sql/partition_info.cc	2012-04-30 07:13:31 +0000
@@ -1395,12 +1395,19 @@ bool partition_info::check_partition_inf
           num_parts_not_set++;
           part_elem->engine_type= default_engine_type;
         }
-        if (check_table_name(part_elem->partition_name,
-                             strlen(part_elem->partition_name), FALSE))
+        enum_ident_name_check ident_check_status=
+          check_table_name(part_elem->partition_name,
+                           strlen(part_elem->partition_name), FALSE);
+        if (ident_check_status == IDENT_NAME_WRONG)
         {
           my_error(ER_WRONG_PARTITION_NAME, MYF(0));
           goto end;
         }
+        else if (ident_check_status == IDENT_NAME_TOO_LONG)
+        {
+          my_error(ER_TOO_LONG_IDENT, MYF(0));
+          goto end;
+        }
         DBUG_PRINT("info", ("part = %d engine = %s",
                    i, ha_resolve_storage_engine_name(part_elem->engine_type)));
       }
@@ -1414,12 +1421,19 @@ bool partition_info::check_partition_inf
         {
           sub_elem= sub_it++;
           warn_if_dir_in_part_elem(thd, sub_elem);
-          if (check_table_name(sub_elem->partition_name,
-                               strlen(sub_elem->partition_name), FALSE))
+          enum_ident_name_check ident_check_status=
+            check_table_name(sub_elem->partition_name,
+                             strlen(sub_elem->partition_name), FALSE);
+          if (ident_check_status == IDENT_NAME_WRONG)
           {
             my_error(ER_WRONG_PARTITION_NAME, MYF(0));
             goto end;
           }
+          else if (ident_check_status == IDENT_NAME_TOO_LONG)
+          {
+            my_error(ER_TOO_LONG_IDENT, MYF(0));
+            goto end;
+          }
           if (sub_elem->engine_type == NULL)
           {
             if (part_elem->engine_type != NULL)

=== modified file 'sql/sql_db.cc'
--- a/sql/sql_db.cc	2012-03-06 14:29:42 +0000
+++ b/sql/sql_db.cc	2012-04-30 07:13:31 +0000
@@ -1502,14 +1502,12 @@ bool mysql_change_db(THD *thd, const LEX
     in this case to be sure.
   */
 
-  if (check_and_convert_db_name(&new_db_file_name, FALSE))
+  if (check_and_convert_db_name(&new_db_file_name, FALSE) != IDENT_NAME_OK)
   {
-    my_error(ER_WRONG_DB_NAME, MYF(0), new_db_file_name.str);
     my_free(new_db_file_name.str);
 
     if (force_switch)
       mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
-
     DBUG_RETURN(TRUE);
   }
 

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2012-04-21 12:11:15 +0000
+++ b/sql/sql_parse.cc	2012-04-30 07:13:31 +0000
@@ -1382,12 +1382,19 @@ bool dispatch_command(enum enum_server_c
     }
     thd->convert_string(&table_name, system_charset_info,
 			packet, arg_length, thd->charset());
-    if (check_table_name(table_name.str, table_name.length, FALSE))
+    enum_ident_name_check ident_check_status=
+      check_table_name(table_name.str, table_name.length, FALSE);
+    if (ident_check_status == IDENT_NAME_WRONG)
     {
       /* this is OK due to convert_string() null-terminating the string */
       my_error(ER_WRONG_TABLE_NAME, MYF(0), table_name.str);
       break;
     }
+    else if (ident_check_status == IDENT_NAME_TOO_LONG)
+    {
+      my_error(ER_TOO_LONG_IDENT, MYF(0), table_name.str);
+      break;
+    }
     packet= arg_end + 1;
     mysql_reset_thd_for_next_command(thd);
     lex_start(thd);
@@ -1859,11 +1866,8 @@ int prepare_schema_table(THD *thd, LEX *
       schema_select_lex->table_list.first= NULL;
       db.length= strlen(db.str);
 
-      if (check_and_convert_db_name(&db, FALSE))
-      {
-        my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
+      if (check_and_convert_db_name(&db, FALSE) != IDENT_NAME_OK)
         DBUG_RETURN(1);
-      }
       break;
     }
 #endif
@@ -3671,11 +3675,8 @@ end_with_restore_list:
     HA_CREATE_INFO create_info(lex->create_info);
     char *alias;
     if (!(alias=thd->strmake(lex->name.str, lex->name.length)) ||
-        check_and_convert_db_name(&lex->name, FALSE))
-    {
-      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
+        (check_and_convert_db_name(&lex->name, FALSE) != IDENT_NAME_OK))
       break;
-    }
     /*
       If in a slave thread :
       CREATE DATABASE DB was certainly not preceded by USE DB.
@@ -3698,11 +3699,8 @@ end_with_restore_list:
   }
   case SQLCOM_DROP_DB:
   {
-    if (check_and_convert_db_name(&lex->name, FALSE))
-    {
-      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
+    if (check_and_convert_db_name(&lex->name, FALSE) != IDENT_NAME_OK)
       break;
-    }
     /*
       If in a slave thread :
       DROP DATABASE DB may not be preceded by USE DB.
@@ -3733,11 +3731,8 @@ end_with_restore_list:
       break;
     }
 #endif
-    if (check_and_convert_db_name(db, FALSE))
-    {
-      my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
+    if (check_and_convert_db_name(db, FALSE) != IDENT_NAME_OK)
       break;
-    }
     if (check_access(thd, ALTER_ACL, db->str, NULL, NULL, 1, 0) ||
         check_access(thd, DROP_ACL, db->str, NULL, NULL, 1, 0) ||
         check_access(thd, CREATE_ACL, db->str, NULL, NULL, 1, 0))
@@ -3754,11 +3749,8 @@ end_with_restore_list:
   {
     LEX_STRING *db= &lex->name;
     HA_CREATE_INFO create_info(lex->create_info);
-    if (check_and_convert_db_name(db, FALSE))
-    {
-      my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
+    if (check_and_convert_db_name(db, FALSE) != IDENT_NAME_OK)
       break;
-    }
     /*
       If in a slave thread :
       ALTER DATABASE DB may not be preceded by USE DB.
@@ -3782,11 +3774,8 @@ end_with_restore_list:
   {
     DBUG_EXECUTE_IF("4x_server_emul",
                     my_error(ER_UNKNOWN_ERROR, MYF(0)); goto error;);
-    if (check_and_convert_db_name(&lex->name, TRUE))
-    {
-      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
+    if (check_and_convert_db_name(&lex->name, TRUE) != IDENT_NAME_OK)
       break;
-    }
     res= mysqld_show_create_db(thd, lex->name.str, &lex->create_info);
     break;
   }
@@ -4208,11 +4197,8 @@ end_with_restore_list:
       Verify that the database name is allowed, optionally
       lowercase it.
     */
-    if (check_and_convert_db_name(&lex->sphead->m_db, FALSE))
-    {
-      my_error(ER_WRONG_DB_NAME, MYF(0), lex->sphead->m_db.str);
+    if (check_and_convert_db_name(&lex->sphead->m_db, FALSE) != IDENT_NAME_OK)
       goto create_sp_error;
-    }
 
     if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str,
                      NULL, NULL, 0, 0))
@@ -6316,19 +6302,24 @@ TABLE_LIST *st_select_lex::add_table_to_
   if (!table)
     DBUG_RETURN(0);				// End of memory
   alias_str= alias ? alias->str : table->table.str;
-  if (!test(table_options & TL_OPTION_ALIAS) && 
-      check_table_name(table->table.str, table->table.length, FALSE))
+  if (!test(table_options & TL_OPTION_ALIAS))
   {
-    my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
-    DBUG_RETURN(0);
+    enum_ident_name_check ident_check_status=
+      check_table_name(table->table.str, table->table.length, FALSE);
+    if (ident_check_status == IDENT_NAME_WRONG)
+    {
+      my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
+      DBUG_RETURN(0);
+    }
+    else if (ident_check_status == IDENT_NAME_TOO_LONG)
+    {
+      my_error(ER_TOO_LONG_IDENT, MYF(0), table->table.str);
+      DBUG_RETURN(0);
+    }
   }
-
   if (table->is_derived_table() == FALSE && table->db.str &&
-      check_and_convert_db_name(&table->db, FALSE))
-  {
-    my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
+      (check_and_convert_db_name(&table->db, FALSE) != IDENT_NAME_OK))
     DBUG_RETURN(0);
-  }
 
   if (!alias)					/* Alias is case sensitive */
   {

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2012-04-25 15:46:11 +0000
+++ b/sql/sql_table.cc	2012-04-30 07:13:31 +0000
@@ -495,7 +495,7 @@ uint tablename_to_filename(const char *f
       a lot of places don't check the return value and expect 
       a zero terminated string.
     */  
-    if (check_table_name(to, length, TRUE))
+    if (check_table_name(to, length, TRUE) != IDENT_NAME_OK)
     {
       to[0]= 0;
       length= 0;

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2012-04-25 15:46:11 +0000
+++ b/sql/sql_yacc.yy	2012-04-30 07:13:31 +0000
@@ -2705,11 +2705,9 @@ clear_privileges:
 sp_name:
           ident '.' ident
           {
-            if (!$1.str || check_and_convert_db_name(&$1, FALSE))
-            {
-              my_error(ER_WRONG_DB_NAME, MYF(0), $1.str);
+            if (!$1.str ||
+                (check_and_convert_db_name(&$1, FALSE) != IDENT_NAME_OK))
               MYSQL_YYABORT;
-            }
             if (check_routine_name(&$3))
             {
               MYSQL_YYABORT;
@@ -7455,12 +7453,21 @@ alter_list_item:
             {
               MYSQL_YYABORT;
             }
-            if (check_table_name($3->table.str,$3->table.length, FALSE) ||
-                ($3->db.str && check_and_convert_db_name(&$3->db, FALSE)))
+            enum_ident_name_check ident_check_status=
+              check_table_name($3->table.str,$3->table.length, FALSE);
+            if (ident_check_status == IDENT_NAME_WRONG)
             {
               my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str);
               MYSQL_YYABORT;
             }
+            else if (ident_check_status == IDENT_NAME_TOO_LONG)
+            {
+              my_error(ER_TOO_LONG_IDENT, MYF(0), $3->table.str);
+              MYSQL_YYABORT;
+            }
+            if ($3->db.str &&
+                (check_and_convert_db_name(&$3->db, FALSE) != IDENT_NAME_OK))
+              MYSQL_YYABORT;
             lex->name= $3->table;
             lex->alter_info.flags|= Alter_info::ALTER_RENAME;
           }
@@ -9670,11 +9677,9 @@ function_call_generic:
               version() (a vendor can specify any schema).
             */
 
-            if (!$1.str || check_and_convert_db_name(&$1, FALSE))
-            {
-              my_error(ER_WRONG_DB_NAME, MYF(0), $1.str);
+            if (!$1.str ||
+                (check_and_convert_db_name(&$1, FALSE) != IDENT_NAME_OK))
               MYSQL_YYABORT;
-            }
             if (check_routine_name(&$3))
             {
               MYSQL_YYABORT;
@@ -11235,11 +11240,9 @@ drop:
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
             sp_name *spname;
-            if ($4.str && check_and_convert_db_name(&$4, FALSE))
-            {
-               my_error(ER_WRONG_DB_NAME, MYF(0), $4.str);
+            if ($4.str &&
+                (check_and_convert_db_name(&$4, FALSE) != IDENT_NAME_OK))
                MYSQL_YYABORT;
-            }
             if (lex->sphead)
             {
               my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION");

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2012-04-18 13:06:39 +0000
+++ b/sql/table.cc	2012-04-30 07:13:31 +0000
@@ -2922,31 +2922,37 @@ uint calculate_key_len(TABLE *table, uin
   return length;
 }
 
-/*
+/**
   Check if database name is valid
 
-  SYNPOSIS
-    check_db_name()
-    org_name		Name of database and length
-    preserve_lettercase Preserve lettercase if true
-
-  NOTES
-    If lower_case_table_names is true and preserve_lettercase is false then
-    database is converted to lower case
-
-  RETURN
-    0	ok
-    1   error
+  @param org_name             Name of database and length
+  @param preserve_lettercase  Preserve lettercase if true
+
+  @note If lower_case_table_names is true and preserve_lettercase
+  is false then database is converted to lower case
+
+  @retval  IDENT_NAME_OK        Identifier name is Ok (Success)
+  @retval  IDENT_NAME_WRONG     Identifier name is Wrong (ER_WRONG_TABLE_NAME)
+  @retval  IDENT_NAME_TOO_LONG  Identifier name is too long if it is greater
+                                than 64 characters (ER_TOO_LONG_IDENT)
+
+  @note In case of IDENT_NAME_WRONG and IDENT_NAME_TOO_LONG, this
+  function reports an error (my_error)
 */
 
-bool check_and_convert_db_name(LEX_STRING *org_name, bool preserve_lettercase)
+enum_ident_name_check check_and_convert_db_name(LEX_STRING *org_name,
+                                                bool preserve_lettercase)
 {
   char *name= org_name->str;
   uint name_length= org_name->length;
   bool check_for_path_chars;
+  enum_ident_name_check ident_check_status;
 
   if (!name_length || name_length > NAME_LEN)
-    return 1;
+  {
+    my_error(ER_WRONG_DB_NAME, MYF(0), org_name->str);
+    return IDENT_NAME_WRONG;
+  }
 
   if ((check_for_path_chars= check_mysql50_prefix(name)))
   {
@@ -2957,28 +2963,44 @@ bool check_and_convert_db_name(LEX_STRIN
   if (!preserve_lettercase && lower_case_table_names && name != any_db)
     my_casedn_str(files_charset_info, name);
 
-  return check_table_name(name, name_length, check_for_path_chars);
+  ident_check_status= check_table_name(name, name_length, check_for_path_chars);
+  if (ident_check_status == IDENT_NAME_WRONG)
+    my_error(ER_WRONG_DB_NAME, MYF(0), org_name->str);
+  else if (ident_check_status == IDENT_NAME_TOO_LONG)
+    my_error(ER_TOO_LONG_IDENT, MYF(0), org_name->str);
+  return ident_check_status;
 }
 
 
-/*
-  Allow anything as a table name, as long as it doesn't contain an
-  ' ' at the end
-  returns 1 on error
+/**
+  Function to check if table name is valid or not. If it is invalid,
+  return appropriate error in each case to the caller.
+
+  @param name                  Table name
+  @param length                Length of table name
+  @param check_for_path_chars  Check if the table name contains path chars
+
+  @retval  IDENT_NAME_OK        Identifier name is Ok (Success)
+  @retval  IDENT_NAME_WRONG     Identifier name is Wrong (ER_WRONG_TABLE_NAME)
+  @retval  IDENT_NAME_TOO_LONG  Identifier name is too long if it is greater
+                                than 64 characters (ER_TOO_LONG_IDENT)
+
+  @note Reporting error to the user is the responsiblity of the caller.
 */
 
-bool check_table_name(const char *name, size_t length, bool check_for_path_chars)
+enum_ident_name_check check_table_name(const char *name, size_t length,
+                                       bool check_for_path_chars)
 {
   // name length in symbols
   size_t name_length= 0;
   const char *end= name+length;
   if (!length || length > NAME_LEN)
-    return 1;
+    return IDENT_NAME_WRONG;
 #if defined(USE_MB) && defined(USE_MB_IDENT)
   bool last_char_is_space= FALSE;
 #else
   if (name[length-1]==' ')
-    return 1;
+    return IDENT_NAME_WRONG;
 #endif
 
   while (name != end)
@@ -2998,15 +3020,17 @@ bool check_table_name(const char *name,
 #endif
     if (check_for_path_chars &&
         (*name == '/' || *name == '\\' || *name == '~' || *name == FN_EXTCHAR))
-      return 1;
+      return IDENT_NAME_WRONG;
     name++;
     name_length++;
   }
 #if defined(USE_MB) && defined(USE_MB_IDENT)
-  return last_char_is_space || (name_length > NAME_CHAR_LEN);
-#else
-  return FALSE;
+  if (last_char_is_space)
+   return IDENT_NAME_WRONG;
+  else if (name_length > NAME_CHAR_LEN)
+   return IDENT_NAME_TOO_LONG;
 #endif
+  return IDENT_NAME_OK;
 }
 
 

=== modified file 'sql/table.h'
--- a/sql/table.h	2012-04-27 11:57:38 +0000
+++ b/sql/table.h	2012-04-30 07:13:31 +0000
@@ -84,6 +84,16 @@ enum enum_table_ref_type
   TABLE_REF_TMP_TABLE
 };
 
+/**
+ Enumerate possible status of a identifier name while determining
+ its validity
+*/
+enum enum_ident_name_check
+{
+  IDENT_NAME_OK,
+  IDENT_NAME_WRONG,
+  IDENT_NAME_TOO_LONG
+};
 
 /*************************************************************************/
 
@@ -2203,9 +2213,11 @@ void free_table_share(TABLE_SHARE *share
 int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags);
 void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg);
 void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form);
-bool check_and_convert_db_name(LEX_STRING *db, bool preserve_lettercase);
+enum_ident_name_check check_and_convert_db_name(LEX_STRING *db,
+                                                bool preserve_lettercase);
 bool check_column_name(const char *name);
-bool check_table_name(const char *name, size_t length, bool check_for_path_chars);
+enum_ident_name_check check_table_name(const char *name, size_t length,
+                                       bool check_for_path_chars);
 int rename_file_ext(const char * from,const char * to,const char * ext);
 char *get_field(MEM_ROOT *mem, Field *field);
 bool get_field(MEM_ROOT *mem, Field *field, class String *res);

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (raghav.kapoor:3750 to 3751) Bug#11746295Raghav Kapoor30 Apr