Commit 43e6919d authored by Mattias Jonsson's avatar Mattias Jonsson

Bug#32430: 'show innodb status' causes errors

Invalid (old?) table or database name in logs

Problem was still not completely fixed, due to
qouting.

This is the server side only fix (in explain_filename),
the change from filename_to_tablename to use explain_filename
in the InnoDB code must be done before the bug is
fixed.


mysql-test/include/have_not_innodb_plugin.inc:
  Bug#32430: 'show innodb status' causes errors
  Invalid (old?) table or database name in logs
  
  Added include file to allow test for only the
  'old' built-in innodb engine
mysql-test/r/not_true.require:
  Bug#32430: 'show innodb status' causes errors
  Invalid (old?) table or database name in logs
  
  Added require to match 'not' TRUE
mysql-test/r/partition_innodb_builtin.result:
  Bug#32430: 'show innodb status' causes errors
  Invalid (old?) table or database name in logs
  
  New result file for partitioning specific to
  the 'old' built-in innodb engine
mysql-test/r/partition_innodb_plugin.result:
  Bug#32430: 'show innodb status' causes errors
  Invalid (old?) table or database name in logs
  
  New result file for partitioning specific to
  the new plugin innodb engine
mysql-test/t/disabled.def:
  Bug#32430: 'show innodb status' causes errors
  Invalid (old?) table or database name in logs
  
  Disabling the new test until the fix is
  included in the InnoDB source too.
mysql-test/t/partition_innodb_builtin.test:
  Bug#32430: 'show innodb status' causes errors
  Invalid (old?) table or database name in logs
  
  New test file for partitioning specific to
  the 'old' built-in innodb engine
mysql-test/t/partition_innodb_plugin.test:
  Bug#32430: 'show innodb status' causes errors
  Invalid (old?) table or database name in logs
  
  New test file for partitioning specific to
  the new plugin innodb engine
sql/mysql_priv.h:
  Bug#32430: 'show innodb status' causes errors
  Invalid (old?) table or database name in logs
  
  Added thd as a parameter to explain_filename
  to be able to use the correct quote character
sql/sql_table.cc:
  Bug#32430: 'show innodb status' causes errors
  Invalid (old?) table or database name in logs
  
  Changed explain_filename, so that it does qouting
  correctly according to the sessions qoute char.
parent 63a81c09
disable_query_log;
--require r/not_true.require
select (PLUGIN_LIBRARY LIKE 'ha_innodb_plugin%') as `TRUE` from information_schema.plugins where PLUGIN_NAME='InnoDB';
enable_query_log;
SET NAMES utf8;
CREATE TABLE `t``\""e` (a INT, PRIMARY KEY (a))
ENGINE=InnoDB
PARTITION BY RANGE (a)
SUBPARTITION BY HASH (a)
(PARTITION `p0``\""e` VALUES LESS THAN (100)
(SUBPARTITION `sp0``\""e`,
SUBPARTITION `sp1``\""e`),
PARTITION `p1``\""e` VALUES LESS THAN (MAXVALUE)
(SUBPARTITION `sp2``\""e`,
SUBPARTITION `sp3``\""e`));
INSERT INTO `t``\""e` VALUES (0), (2), (6), (10), (14), (18), (22);
START TRANSACTION;
# con1
SET NAMES utf8;
START TRANSACTION;
# default connection
UPDATE `t``\""e` SET a = 16 WHERE a = 0;
# con1
UPDATE `t``\""e` SET a = 8 WHERE a = 22;
UPDATE `t``\""e` SET a = 12 WHERE a = 0;
# default connection
UPDATE `t``\""e` SET a = 4 WHERE a = 22;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
# First table reported in 'SHOW ENGINE InnoDB STATUS'
SHOW ENGINE InnoDB STATUS;
Type Name Status
InnoDB index `PRIMARY` of table `test`.`t``\""e` /* Partition `p0``\""e`, Subpartition `sp0``\""e` */
set @old_sql_mode = @@sql_mode;
set sql_mode = 'ANSI_QUOTES';
SHOW ENGINE InnoDB STATUS;
Type Name Status
InnoDB index `PRIMARY` of table `test`.`t``\""e` /* Partition `p0``\""e`, Subpartition `sp0``\""e` */
set @@sql_mode = @old_sql_mode;
# con1
ROLLBACK;
# default connection
DROP TABLE `t``\""e`;
SET NAMES DEFAULT;
SET NAMES utf8;
CREATE TABLE `t``\""e` (a INT, PRIMARY KEY (a))
ENGINE=InnoDB
PARTITION BY RANGE (a)
SUBPARTITION BY HASH (a)
(PARTITION `p0``\""e` VALUES LESS THAN (100)
(SUBPARTITION `sp0``\""e`,
SUBPARTITION `sp1``\""e`),
PARTITION `p1``\""e` VALUES LESS THAN (MAXVALUE)
(SUBPARTITION `sp2``\""e`,
SUBPARTITION `sp3``\""e`));
INSERT INTO `t``\""e` VALUES (0), (2), (6), (10), (14), (18), (22);
START TRANSACTION;
# con1
SET NAMES utf8;
START TRANSACTION;
# default connection
UPDATE `t``\""e` SET a = 16 WHERE a = 0;
# con1
UPDATE `t``\""e` SET a = 8 WHERE a = 22;
UPDATE `t``\""e` SET a = 12 WHERE a = 0;
# default connection
SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS
GROUP BY lock_table;
lock_table COUNT(*)
`test`.`t``\""e` /* Partition `p0``\""e`, Subpartition `sp0``\""e` */ 2
set @old_sql_mode = @@sql_mode;
set sql_mode = 'ANSI_QUOTES';
SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS
GROUP BY lock_table;
lock_table COUNT(*)
"test"."t`\""""e" /* Partition "p0`\""""e", Subpartition "sp0`\""""e" */ 2
set @@sql_mode = @old_sql_mode;
UPDATE `t``\""e` SET a = 4 WHERE a = 22;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
# First table reported in 'SHOW ENGINE InnoDB STATUS'
SHOW ENGINE InnoDB STATUS;
Type Name Status
InnoDB index `PRIMARY` of table `test`.`t``\""e` /* Partition `p0``\""e`, Subpartition `sp0``\""e` */
set @old_sql_mode = @@sql_mode;
set sql_mode = 'ANSI_QUOTES';
SHOW ENGINE InnoDB STATUS;
Type Name Status
InnoDB index `PRIMARY` of table `test`.`t``\""e` /* Partition `p0``\""e`, Subpartition `sp0``\""e` */
set @@sql_mode = @old_sql_mode;
# con1
ROLLBACK;
# default connection
DROP TABLE `t``\""e`;
SET NAMES DEFAULT;
...@@ -13,4 +13,5 @@ kill : Bug#37780 2008-12-03 HHunger need some changes to be ...@@ -13,4 +13,5 @@ kill : Bug#37780 2008-12-03 HHunger need some changes to be
innodb_bug39438 : Bug#42383 2009-01-28 lsoares "This fails in embedded and on windows. Note that this test is not run on windows and on embedded in PB for main trees currently" innodb_bug39438 : Bug#42383 2009-01-28 lsoares "This fails in embedded and on windows. Note that this test is not run on windows and on embedded in PB for main trees currently"
query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
init_connect : Bug#44920 2009-07-06 pcrews MTR not processing master.opt input properly on Windows. *Must be done this way due to the nature of the bug* init_connect : Bug#44920 2009-07-06 pcrews MTR not processing master.opt input properly on Windows. *Must be done this way due to the nature of the bug*
partition_innodb_builtin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
partition_innodb_plugin : Bug#32430 2009-09-25 mattiasj Waiting for push of Innodb changes
--source include/have_partition.inc
--source include/have_innodb.inc
--source include/have_not_innodb_plugin.inc
#
# Bug#32430 - show engine innodb status causes errors
#
SET NAMES utf8;
CREATE TABLE `t``\""e` (a INT, PRIMARY KEY (a))
ENGINE=InnoDB
PARTITION BY RANGE (a)
SUBPARTITION BY HASH (a)
(PARTITION `p0``\""e` VALUES LESS THAN (100)
(SUBPARTITION `sp0``\""e`,
SUBPARTITION `sp1``\""e`),
PARTITION `p1``\""e` VALUES LESS THAN (MAXVALUE)
(SUBPARTITION `sp2``\""e`,
SUBPARTITION `sp3``\""e`));
INSERT INTO `t``\""e` VALUES (0), (2), (6), (10), (14), (18), (22);
START TRANSACTION;
--echo # con1
connect(con1,localhost,root,,);
SET NAMES utf8;
START TRANSACTION;
--echo # default connection
connection default;
UPDATE `t``\""e` SET a = 16 WHERE a = 0;
--echo # con1
connection con1;
UPDATE `t``\""e` SET a = 8 WHERE a = 22;
let $id_1= `SELECT CONNECTION_ID()`;
SEND;
UPDATE `t``\""e` SET a = 12 WHERE a = 0;
--echo # default connection
connection default;
let $wait_timeout= 2;
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE ID = $id_1 AND STATE = 'Searching rows for update';
--source include/wait_condition.inc
#--echo # tested wait condition $wait_condition_reps times
--error ER_LOCK_DEADLOCK
UPDATE `t``\""e` SET a = 4 WHERE a = 22;
--echo # First table reported in 'SHOW ENGINE InnoDB STATUS'
# RECORD LOCKS space id 0 page no 50 n bits 80 index `PRIMARY` in \
# Database `test`, Table `t1`, Partition `p0`, Subpartition `sp0` \
# trx id 0 775
# NOTE: replace_regex is very slow on match copy/past '(.*)' regex's
# on big texts, removing a lot of text before + after makes it much faster.
#/.*in (.*) trx.*/\1/
--replace_regex /.*RECORD LOCKS space id [0-9]* page no [0-9]* n bits [0-9]* // / trx id .*// /.*index .* in //
SHOW ENGINE InnoDB STATUS;
set @old_sql_mode = @@sql_mode;
set sql_mode = 'ANSI_QUOTES';
# INNODB_LOCKS only exists in innodb_plugin
#SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
--replace_regex /.*RECORD LOCKS space id [0-9]* page no [0-9]* n bits [0-9]* // / trx id .*// /.*index .* in //
SHOW ENGINE InnoDB STATUS;
set @@sql_mode = @old_sql_mode;
--echo # con1
connection con1;
REAP;
ROLLBACK;
disconnect con1;
--echo # default connection
connection default;
DROP TABLE `t``\""e`;
SET NAMES DEFAULT;
--source include/have_partition.inc
--source include/have_innodb.inc
--source suite/innodb/include/have_innodb_plugin.inc
#
# Bug#32430 - show engine innodb status causes errors
#
SET NAMES utf8;
CREATE TABLE `t``\""e` (a INT, PRIMARY KEY (a))
ENGINE=InnoDB
PARTITION BY RANGE (a)
SUBPARTITION BY HASH (a)
(PARTITION `p0``\""e` VALUES LESS THAN (100)
(SUBPARTITION `sp0``\""e`,
SUBPARTITION `sp1``\""e`),
PARTITION `p1``\""e` VALUES LESS THAN (MAXVALUE)
(SUBPARTITION `sp2``\""e`,
SUBPARTITION `sp3``\""e`));
INSERT INTO `t``\""e` VALUES (0), (2), (6), (10), (14), (18), (22);
START TRANSACTION;
--echo # con1
connect(con1,localhost,root,,);
SET NAMES utf8;
START TRANSACTION;
--echo # default connection
connection default;
UPDATE `t``\""e` SET a = 16 WHERE a = 0;
--echo # con1
connection con1;
UPDATE `t``\""e` SET a = 8 WHERE a = 22;
let $id_1= `SELECT CONNECTION_ID()`;
SEND;
UPDATE `t``\""e` SET a = 12 WHERE a = 0;
--echo # default connection
connection default;
let $wait_timeout= 2;
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE ID = $id_1 AND STATE = 'Searching rows for update';
--source include/wait_condition.inc
#--echo # tested wait condition $wait_condition_reps times
# INNODB_LOCKS only exists in innodb_plugin
--sorted_result
SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS
GROUP BY lock_table;
set @old_sql_mode = @@sql_mode;
set sql_mode = 'ANSI_QUOTES';
--sorted_result
SELECT lock_table, COUNT(*) FROM INFORMATION_SCHEMA.INNODB_LOCKS
GROUP BY lock_table;
set @@sql_mode = @old_sql_mode;
--error ER_LOCK_DEADLOCK
UPDATE `t``\""e` SET a = 4 WHERE a = 22;
--echo # First table reported in 'SHOW ENGINE InnoDB STATUS'
# RECORD LOCKS space id 0 page no 50 n bits 80 index `PRIMARY` in \
# Database `test`, Table `t1`, Partition `p0`, Subpartition `sp0` \
# trx id 0 775
# NOTE: replace_regex is very slow on match copy/past '(.*)' regex's
# on big texts, removing a lot of text before + after makes it much faster.
#/.*in (.*) trx.*/\1/
--replace_regex /.*RECORD LOCKS space id [0-9]* page no [0-9]* n bits [0-9]* // / trx id .*// /.*index .* in //
SHOW ENGINE InnoDB STATUS;
set @old_sql_mode = @@sql_mode;
set sql_mode = 'ANSI_QUOTES';
--replace_regex /.*RECORD LOCKS space id [0-9]* page no [0-9]* n bits [0-9]* // / trx id .*// /.*index .* in //
SHOW ENGINE InnoDB STATUS;
set @@sql_mode = @old_sql_mode;
--echo # con1
connection con1;
REAP;
ROLLBACK;
disconnect con1;
--echo # default connection
connection default;
DROP TABLE `t``\""e`;
SET NAMES DEFAULT;
...@@ -2277,10 +2277,9 @@ enum enum_explain_filename_mode ...@@ -2277,10 +2277,9 @@ enum enum_explain_filename_mode
{ {
EXPLAIN_ALL_VERBOSE= 0, EXPLAIN_ALL_VERBOSE= 0,
EXPLAIN_PARTITIONS_VERBOSE, EXPLAIN_PARTITIONS_VERBOSE,
EXPLAIN_PARTITIONS_AS_COMMENT, EXPLAIN_PARTITIONS_AS_COMMENT
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING
}; };
uint explain_filename(const char *from, char *to, uint to_length, uint explain_filename(THD* thd, const char *from, char *to, uint to_length,
enum_explain_filename_mode explain_mode); enum_explain_filename_mode explain_mode);
uint filename_to_tablename(const char *from, char *to, uint to_length); uint filename_to_tablename(const char *from, char *to, uint to_length);
uint tablename_to_filename(const char *from, char *to, uint to_length); uint tablename_to_filename(const char *from, char *to, uint to_length);
......
...@@ -70,15 +70,21 @@ static void wait_for_kill_signal(THD *thd) ...@@ -70,15 +70,21 @@ static void wait_for_kill_signal(THD *thd)
/** /**
@brief Helper function for explain_filename @brief Helper function for explain_filename
@param thd Thread handle
@param to_p Explained name in system_charset_info
@param end_p End of the to_p buffer
@param name Name to be converted
@param name_len Length of the name, in bytes
*/ */
static char* add_identifier(char *to_p, const char * end_p, static char* add_identifier(THD* thd, char *to_p, const char * end_p,
const char* name, uint name_len, bool add_quotes) const char* name, uint name_len)
{ {
uint res; uint res;
uint errors; uint errors;
const char *conv_name; const char *conv_name;
char tmp_name[FN_REFLEN]; char tmp_name[FN_REFLEN];
char conv_string[FN_REFLEN]; char conv_string[FN_REFLEN];
int quote;
DBUG_ENTER("add_identifier"); DBUG_ENTER("add_identifier");
if (!name[name_len]) if (!name[name_len])
...@@ -102,19 +108,21 @@ static char* add_identifier(char *to_p, const char * end_p, ...@@ -102,19 +108,21 @@ static char* add_identifier(char *to_p, const char * end_p,
conv_name= conv_string; conv_name= conv_string;
} }
if (add_quotes && (end_p - to_p > 2)) quote = thd ? get_quote_char_for_identifier(thd, conv_name, res - 1) : '"';
if (quote != EOF && (end_p - to_p > 2))
{ {
*(to_p++)= '`'; *(to_p++)= (char) quote;
while (*conv_name && (end_p - to_p - 1) > 0) while (*conv_name && (end_p - to_p - 1) > 0)
{ {
uint length= my_mbcharlen(system_charset_info, *conv_name); uint length= my_mbcharlen(system_charset_info, *conv_name);
if (!length) if (!length)
length= 1; length= 1;
if (length == 1 && *conv_name == '`') if (length == 1 && *conv_name == (char) quote)
{ {
if ((end_p - to_p) < 3) if ((end_p - to_p) < 3)
break; break;
*(to_p++)= '`'; *(to_p++)= (char) quote;
*(to_p++)= *(conv_name++); *(to_p++)= *(conv_name++);
} }
else if (((long) length) < (end_p - to_p)) else if (((long) length) < (end_p - to_p))
...@@ -125,7 +133,11 @@ static char* add_identifier(char *to_p, const char * end_p, ...@@ -125,7 +133,11 @@ static char* add_identifier(char *to_p, const char * end_p,
else else
break; /* string already filled */ break; /* string already filled */
} }
to_p= strnmov(to_p, "`", end_p - to_p); if (end_p > to_p) {
*(to_p++)= (char) quote;
if (end_p > to_p)
*to_p= 0; /* terminate by NUL, but do not include it in the count */
}
} }
else else
to_p= strnmov(to_p, conv_name, end_p - to_p); to_p= strnmov(to_p, conv_name, end_p - to_p);
...@@ -145,6 +157,7 @@ static char* add_identifier(char *to_p, const char * end_p, ...@@ -145,6 +157,7 @@ static char* add_identifier(char *to_p, const char * end_p,
diagnostic, error etc. when it would be useful to know what a particular diagnostic, error etc. when it would be useful to know what a particular
file [and directory] means. Such as SHOW ENGINE STATUS, error messages etc. file [and directory] means. Such as SHOW ENGINE STATUS, error messages etc.
@param thd Thread handle
@param from Path name in my_charset_filename @param from Path name in my_charset_filename
Null terminated in my_charset_filename, normalized Null terminated in my_charset_filename, normalized
to use '/' as directory separation character. to use '/' as directory separation character.
...@@ -161,13 +174,12 @@ static char* add_identifier(char *to_p, const char * end_p, ...@@ -161,13 +174,12 @@ static char* add_identifier(char *to_p, const char * end_p,
[,[ Temporary| Renamed] Partition `p` [,[ Temporary| Renamed] Partition `p`
[, Subpartition `sp`]] *| [, Subpartition `sp`]] *|
(| is really a /, and it is all in one line) (| is really a /, and it is all in one line)
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING ->
same as above but no quotes are added.
@retval Length of returned string @retval Length of returned string
*/ */
uint explain_filename(const char *from, uint explain_filename(THD* thd,
const char *from,
char *to, char *to,
uint to_length, uint to_length,
enum_explain_filename_mode explain_mode) enum_explain_filename_mode explain_mode)
...@@ -281,14 +293,12 @@ uint explain_filename(const char *from, ...@@ -281,14 +293,12 @@ uint explain_filename(const char *from,
{ {
to_p= strnmov(to_p, ER(ER_DATABASE_NAME), end_p - to_p); to_p= strnmov(to_p, ER(ER_DATABASE_NAME), end_p - to_p);
*(to_p++)= ' '; *(to_p++)= ' ';
to_p= add_identifier(to_p, end_p, db_name, db_name_len, 1); to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
to_p= strnmov(to_p, ", ", end_p - to_p); to_p= strnmov(to_p, ", ", end_p - to_p);
} }
else else
{ {
to_p= add_identifier(to_p, end_p, db_name, db_name_len, to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
(explain_mode !=
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
to_p= strnmov(to_p, ".", end_p - to_p); to_p= strnmov(to_p, ".", end_p - to_p);
} }
} }
...@@ -296,16 +306,13 @@ uint explain_filename(const char *from, ...@@ -296,16 +306,13 @@ uint explain_filename(const char *from,
{ {
to_p= strnmov(to_p, ER(ER_TABLE_NAME), end_p - to_p); to_p= strnmov(to_p, ER(ER_TABLE_NAME), end_p - to_p);
*(to_p++)= ' '; *(to_p++)= ' ';
to_p= add_identifier(to_p, end_p, table_name, table_name_len, 1); to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
} }
else else
to_p= add_identifier(to_p, end_p, table_name, table_name_len, to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
(explain_mode !=
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
if (part_name) if (part_name)
{ {
if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT || if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT)
explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING)
to_p= strnmov(to_p, " /* ", end_p - to_p); to_p= strnmov(to_p, " /* ", end_p - to_p);
else if (explain_mode == EXPLAIN_PARTITIONS_VERBOSE) else if (explain_mode == EXPLAIN_PARTITIONS_VERBOSE)
to_p= strnmov(to_p, " ", end_p - to_p); to_p= strnmov(to_p, " ", end_p - to_p);
...@@ -321,20 +328,15 @@ uint explain_filename(const char *from, ...@@ -321,20 +328,15 @@ uint explain_filename(const char *from,
} }
to_p= strnmov(to_p, ER(ER_PARTITION_NAME), end_p - to_p); to_p= strnmov(to_p, ER(ER_PARTITION_NAME), end_p - to_p);
*(to_p++)= ' '; *(to_p++)= ' ';
to_p= add_identifier(to_p, end_p, part_name, part_name_len, to_p= add_identifier(thd, to_p, end_p, part_name, part_name_len);
(explain_mode !=
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
if (subpart_name) if (subpart_name)
{ {
to_p= strnmov(to_p, ", ", end_p - to_p); to_p= strnmov(to_p, ", ", end_p - to_p);
to_p= strnmov(to_p, ER(ER_SUBPARTITION_NAME), end_p - to_p); to_p= strnmov(to_p, ER(ER_SUBPARTITION_NAME), end_p - to_p);
*(to_p++)= ' '; *(to_p++)= ' ';
to_p= add_identifier(to_p, end_p, subpart_name, subpart_name_len, to_p= add_identifier(thd, to_p, end_p, subpart_name, subpart_name_len);
(explain_mode !=
EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
} }
if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT || if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT)
explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING)
to_p= strnmov(to_p, " */", end_p - to_p); to_p= strnmov(to_p, " */", end_p - to_p);
} }
DBUG_PRINT("exit", ("to '%s'", to)); DBUG_PRINT("exit", ("to '%s'", to));
......
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