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#11746295 | Raghav Kapoor | 30 Apr |