summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/include/have_not_innodb_plugin.inc4
-rw-r--r--mysql-test/r/not_true.require2
-rw-r--r--mysql-test/r/partition_innodb_builtin.result39
-rw-r--r--mysql-test/r/partition_innodb_plugin.result50
-rw-r--r--mysql-test/t/disabled.def2
-rw-r--r--mysql-test/t/partition_innodb_builtin.test67
-rw-r--r--mysql-test/t/partition_innodb_plugin.test75
-rw-r--r--sql/mysql_priv.h5
-rw-r--r--sql/sql_table.cc58
9 files changed, 271 insertions, 31 deletions
diff --git a/mysql-test/include/have_not_innodb_plugin.inc b/mysql-test/include/have_not_innodb_plugin.inc
new file mode 100644
index 00000000000..aaefbaf661c
--- /dev/null
+++ b/mysql-test/include/have_not_innodb_plugin.inc
@@ -0,0 +1,4 @@
+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;
diff --git a/mysql-test/r/not_true.require b/mysql-test/r/not_true.require
new file mode 100644
index 00000000000..0032832f3d1
--- /dev/null
+++ b/mysql-test/r/not_true.require
@@ -0,0 +1,2 @@
+TRUE
+NULL
diff --git a/mysql-test/r/partition_innodb_builtin.result b/mysql-test/r/partition_innodb_builtin.result
new file mode 100644
index 00000000000..384ce0790a4
--- /dev/null
+++ b/mysql-test/r/partition_innodb_builtin.result
@@ -0,0 +1,39 @@
+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;
diff --git a/mysql-test/r/partition_innodb_plugin.result b/mysql-test/r/partition_innodb_plugin.result
new file mode 100644
index 00000000000..dd91eee316a
--- /dev/null
+++ b/mysql-test/r/partition_innodb_plugin.result
@@ -0,0 +1,50 @@
+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;
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 6d8f0af0c28..6f0b1716d38 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -12,3 +12,5 @@
kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild.
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
+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
diff --git a/mysql-test/t/partition_innodb_builtin.test b/mysql-test/t/partition_innodb_builtin.test
new file mode 100644
index 00000000000..a9be41c7455
--- /dev/null
+++ b/mysql-test/t/partition_innodb_builtin.test
@@ -0,0 +1,67 @@
+--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;
diff --git a/mysql-test/t/partition_innodb_plugin.test b/mysql-test/t/partition_innodb_plugin.test
new file mode 100644
index 00000000000..fed8c96424a
--- /dev/null
+++ b/mysql-test/t/partition_innodb_plugin.test
@@ -0,0 +1,75 @@
+--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;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 381a0313add..6fde16d3049 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -2277,10 +2277,9 @@ enum enum_explain_filename_mode
{
EXPLAIN_ALL_VERBOSE= 0,
EXPLAIN_PARTITIONS_VERBOSE,
- EXPLAIN_PARTITIONS_AS_COMMENT,
- EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING
+ EXPLAIN_PARTITIONS_AS_COMMENT
};
-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);
uint filename_to_tablename(const char *from, char *to, uint to_length);
uint tablename_to_filename(const char *from, char *to, uint to_length);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 6dba2f02071..1d147c54059 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -70,15 +70,21 @@ static void wait_for_kill_signal(THD *thd)
/**
@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,
- const char* name, uint name_len, bool add_quotes)
+static char* add_identifier(THD* thd, char *to_p, const char * end_p,
+ const char* name, uint name_len)
{
uint res;
uint errors;
const char *conv_name;
char tmp_name[FN_REFLEN];
char conv_string[FN_REFLEN];
+ int quote;
DBUG_ENTER("add_identifier");
if (!name[name_len])
@@ -102,19 +108,21 @@ static char* add_identifier(char *to_p, const char * end_p,
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)
{
uint length= my_mbcharlen(system_charset_info, *conv_name);
if (!length)
length= 1;
- if (length == 1 && *conv_name == '`')
+ if (length == 1 && *conv_name == (char) quote)
{
if ((end_p - to_p) < 3)
break;
- *(to_p++)= '`';
+ *(to_p++)= (char) quote;
*(to_p++)= *(conv_name++);
}
else if (((long) length) < (end_p - to_p))
@@ -125,7 +133,11 @@ static char* add_identifier(char *to_p, const char * end_p,
else
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
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,
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.
+ @param thd Thread handle
@param from Path name in my_charset_filename
Null terminated in my_charset_filename, normalized
to use '/' as directory separation character.
@@ -161,13 +174,12 @@ static char* add_identifier(char *to_p, const char * end_p,
[,[ Temporary| Renamed] Partition `p`
[, Subpartition `sp`]] *|
(| 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
*/
-uint explain_filename(const char *from,
+uint explain_filename(THD* thd,
+ const char *from,
char *to,
uint to_length,
enum_explain_filename_mode explain_mode)
@@ -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++)= ' ';
- 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);
}
else
{
- to_p= add_identifier(to_p, end_p, db_name, db_name_len,
- (explain_mode !=
- EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
+ to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
to_p= strnmov(to_p, ".", end_p - to_p);
}
}
@@ -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++)= ' ';
- 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
- to_p= add_identifier(to_p, end_p, table_name, table_name_len,
- (explain_mode !=
- EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
+ to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
if (part_name)
{
- if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT ||
- explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING)
+ if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT)
to_p= strnmov(to_p, " /* ", end_p - to_p);
else if (explain_mode == EXPLAIN_PARTITIONS_VERBOSE)
to_p= strnmov(to_p, " ", end_p - to_p);
@@ -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++)= ' ';
- to_p= add_identifier(to_p, end_p, part_name, part_name_len,
- (explain_mode !=
- EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
+ to_p= add_identifier(thd, to_p, end_p, part_name, part_name_len);
if (subpart_name)
{
to_p= strnmov(to_p, ", ", end_p - to_p);
to_p= strnmov(to_p, ER(ER_SUBPARTITION_NAME), end_p - to_p);
*(to_p++)= ' ';
- to_p= add_identifier(to_p, end_p, subpart_name, subpart_name_len,
- (explain_mode !=
- EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING));
+ to_p= add_identifier(thd, to_p, end_p, subpart_name, subpart_name_len);
}
- if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT ||
- explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT_NO_QUOTING)
+ if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT)
to_p= strnmov(to_p, " */", end_p - to_p);
}
DBUG_PRINT("exit", ("to '%s'", to));