List:Commits« Previous MessageNext Message »
From:marko.makela Date:May 14 2010 1:11pm
Subject:bzr push into mysql-5.1-innodb branch (marko.makela:3464 to 3467) Bug#48024
Bug#53644
View as plain text  
 3467 Marko Mäkelä	2010-05-14
      Document Bug #48024 and Bug #53644 in the ChangeLog

    modified:
      storage/innodb_plugin/ChangeLog
 3466 Marko Mäkelä	2010-05-14
      Make the InnoDB FOREIGN KEY parser understand multi-statements. (Bug #48024)
      Also make InnoDB thinks that /*/ only starts a comment. (Bug #53644).
      
      This fixes the bugs in the InnoDB Plugin.
      
      ha_innodb.h: Use trx_query_string() instead of trx_query() when
      available (MySQL 5.1.42 or later).
      
      innobase_get_stmt(): New function, to retrieve the currently running
      SQL statement.
      
      struct trx_struct: Remove mysql_query_str. Use innobase_get_stmt() instead.
      
      dict_strip_comments(): Add and observe the parameter sql_length. Treat
      /*/ as the start of a comment.
      
      dict_create_foreign_constraints(), row_table_add_foreign_constraints():
      Add the parameter sql_length.

    added:
      mysql-test/suite/innodb_plugin/r/innodb_bug48024.result
      mysql-test/suite/innodb_plugin/t/innodb_bug48024.test
    modified:
      storage/innodb_plugin/dict/dict0dict.c
      storage/innodb_plugin/handler/ha_innodb.cc
      storage/innodb_plugin/handler/ha_innodb.h
      storage/innodb_plugin/include/dict0dict.h
      storage/innodb_plugin/include/ha_prototypes.h
      storage/innodb_plugin/include/row0mysql.h
      storage/innodb_plugin/include/trx0trx.h
      storage/innodb_plugin/row/row0mysql.c
      storage/innodb_plugin/trx/trx0i_s.c
      storage/innodb_plugin/trx/trx0trx.c
 3465 Marko Mäkelä	2010-05-14
      Make the InnoDB FOREIGN KEY parser understand multi-statements. (Bug #48024)
      Also make InnoDB thinks that /*/ only starts a comment. (Bug #53644).
      
      struct trx_struct: Add mysql_query_len.
      
      ha_innodb.cc: Use trx_query_string() instead of trx_query() and
      initialize trx->mysql_query_len.
      
      INNOBASE_COPY_STMT(thd, trx): New macro, to initialize
      trx->mysql_query_str and trx->mysql_query_len.
      
      dict_strip_comments(): Add and observe the parameter sql_length. Treat
      /*/ as the start of a comment.
      
      dict_create_foreign_constraints(), row_table_add_foreign_constraints():
      Add the parameter sql_length.

    added:
      mysql-test/suite/innodb/r/innodb_bug48024.result
      mysql-test/suite/innodb/t/innodb_bug48024.test
    modified:
      storage/innobase/dict/dict0dict.c
      storage/innobase/handler/ha_innodb.cc
      storage/innobase/handler/ha_innodb.h
      storage/innobase/include/dict0dict.h
      storage/innobase/include/row0mysql.h
      storage/innobase/include/trx0trx.h
      storage/innobase/row/row0mysql.c
      storage/innobase/trx/trx0trx.c
 3464 Marko Mäkelä	2010-05-14
      Remove unused code.

    modified:
      storage/innobase/srv/srv0start.c
=== added file 'mysql-test/suite/innodb/r/innodb_bug48024.result'
--- a/mysql-test/suite/innodb/r/innodb_bug48024.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/r/innodb_bug48024.result	revid:marko.makela@oracle.com-20100514131050-mkhlvlui1u52irob
@@ -0,0 +1,10 @@
+CREATE TABLE bug48024(a int PRIMARY KEY,b int NOT NULL,KEY(b)) ENGINE=InnoDB;
+CREATE TABLE bug48024_b(b int PRIMARY KEY) ENGINE=InnoDB;
+ALTER TABLE bug48024 /*/ADD CONSTRAINT FOREIGN KEY(c) REFERENCES(a),/*/
+ADD CONSTRAINT FOREIGN KEY(b) REFERENCES bug48024_b(b);
+DROP TABLE bug48024,bug48024_b;
+CREATE TABLE bug48024(a int PRIMARY KEY,b int NOT NULL,KEY(b)) ENGINE=InnoDB;
+CREATE TABLE bug48024_b(b int PRIMARY KEY) ENGINE=InnoDB;
+ALTER TABLE bug48024 /*/ADD CONSTRAINT FOREIGN KEY(c) REFERENCES(a),/*/
+ADD CONSTRAINT FOREIGN KEY(b) REFERENCES bug48024_b(b)|
+DROP TABLE bug48024,bug48024_b;

=== added file 'mysql-test/suite/innodb/t/innodb_bug48024.test'
--- a/mysql-test/suite/innodb/t/innodb_bug48024.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb_bug48024.test	revid:marko.makela@strippedrob
@@ -0,0 +1,20 @@
+# Bug #48024 Innodb doesn't work with multi-statements
+
+--source include/have_innodb.inc
+
+CREATE TABLE bug48024(a int PRIMARY KEY,b int NOT NULL,KEY(b)) ENGINE=InnoDB;
+CREATE TABLE bug48024_b(b int PRIMARY KEY) ENGINE=InnoDB;
+# Bug #53644 InnoDB thinks that /*/ starts and ends a comment
+ALTER TABLE bug48024 /*/ADD CONSTRAINT FOREIGN KEY(c) REFERENCES(a),/*/
+ADD CONSTRAINT FOREIGN KEY(b) REFERENCES bug48024_b(b);
+
+DROP TABLE bug48024,bug48024_b;
+
+delimiter |;
+CREATE TABLE bug48024(a int PRIMARY KEY,b int NOT NULL,KEY(b)) ENGINE=InnoDB;
+CREATE TABLE bug48024_b(b int PRIMARY KEY) ENGINE=InnoDB;
+ALTER TABLE bug48024 /*/ADD CONSTRAINT FOREIGN KEY(c) REFERENCES(a),/*/
+ADD CONSTRAINT FOREIGN KEY(b) REFERENCES bug48024_b(b)|
+delimiter ;|
+
+DROP TABLE bug48024,bug48024_b;

=== added file 'mysql-test/suite/innodb_plugin/r/innodb_bug48024.result'
--- a/mysql-test/suite/innodb_plugin/r/innodb_bug48024.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb_plugin/r/innodb_bug48024.result	revid:marko.makela@strippedmkhlvlui1u52irob
@@ -0,0 +1,10 @@
+CREATE TABLE bug48024(a int PRIMARY KEY,b int NOT NULL,KEY(b)) ENGINE=InnoDB;
+CREATE TABLE bug48024_b(b int PRIMARY KEY) ENGINE=InnoDB;
+ALTER TABLE bug48024 /*/ADD CONSTRAINT FOREIGN KEY(c) REFERENCES(a),/*/
+ADD CONSTRAINT FOREIGN KEY(b) REFERENCES bug48024_b(b);
+DROP TABLE bug48024,bug48024_b;
+CREATE TABLE bug48024(a int PRIMARY KEY,b int NOT NULL,KEY(b)) ENGINE=InnoDB;
+CREATE TABLE bug48024_b(b int PRIMARY KEY) ENGINE=InnoDB;
+ALTER TABLE bug48024 /*/ADD CONSTRAINT FOREIGN KEY(c) REFERENCES(a),/*/
+ADD CONSTRAINT FOREIGN KEY(b) REFERENCES bug48024_b(b)|
+DROP TABLE bug48024,bug48024_b;

=== added file 'mysql-test/suite/innodb_plugin/t/innodb_bug48024.test'
--- a/mysql-test/suite/innodb_plugin/t/innodb_bug48024.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb_plugin/t/innodb_bug48024.test	revid:marko.makela@strippedrob
@@ -0,0 +1,20 @@
+# Bug #48024 Innodb doesn't work with multi-statements
+
+--source include/have_innodb_plugin.inc
+
+CREATE TABLE bug48024(a int PRIMARY KEY,b int NOT NULL,KEY(b)) ENGINE=InnoDB;
+CREATE TABLE bug48024_b(b int PRIMARY KEY) ENGINE=InnoDB;
+# Bug #53644 InnoDB thinks that /*/ starts and ends a comment
+ALTER TABLE bug48024 /*/ADD CONSTRAINT FOREIGN KEY(c) REFERENCES(a),/*/
+ADD CONSTRAINT FOREIGN KEY(b) REFERENCES bug48024_b(b);
+
+DROP TABLE bug48024,bug48024_b;
+
+delimiter |;
+CREATE TABLE bug48024(a int PRIMARY KEY,b int NOT NULL,KEY(b)) ENGINE=InnoDB;
+CREATE TABLE bug48024_b(b int PRIMARY KEY) ENGINE=InnoDB;
+ALTER TABLE bug48024 /*/ADD CONSTRAINT FOREIGN KEY(c) REFERENCES(a),/*/
+ADD CONSTRAINT FOREIGN KEY(b) REFERENCES bug48024_b(b)|
+delimiter ;|
+
+DROP TABLE bug48024,bug48024_b;

=== modified file 'storage/innobase/dict/dict0dict.c'
--- a/storage/innobase/dict/dict0dict.c	revid:marko.makela@strippedy9cay7jx
+++ b/storage/innobase/dict/dict0dict.c	revid:marko.makela@stripped
@@ -2586,25 +2586,28 @@ dict_strip_comments(
 					/* out, own: SQL string stripped from
 					comments; the caller must free this
 					with mem_free()! */
-	const char*	sql_string)	/* in: SQL string */
+	const char*	sql_string,	/* in: SQL string */
+	size_t		sql_length)	/* in: length of sql_string */
 {
 	char*		str;
 	const char*	sptr;
+	const char*	eptr	= sql_string + sql_length;
 	char*		ptr;
 	/* unclosed quote character (0 if none) */
 	char		quote	= 0;
 
-	str = mem_alloc(strlen(sql_string) + 1);
+	str = mem_alloc(sql_length + 1);
 
 	sptr = sql_string;
 	ptr = str;
 
 	for (;;) {
 scan_more:
-		if (*sptr == '\0') {
+		if (sptr >= eptr || *sptr == '\0') {
+end_of_string:
 			*ptr = '\0';
 
-			ut_a(ptr <= str + strlen(sql_string));
+			ut_a(ptr <= str + sql_length);
 
 			return(str);
 		}
@@ -2623,30 +2626,35 @@ scan_more:
 			   || (sptr[0] == '-' && sptr[1] == '-'
 			       && sptr[2] == ' ')) {
 			for (;;) {
+				if (++sptr >= eptr) {
+					goto end_of_string;
+				}
+
 				/* In Unix a newline is 0x0A while in Windows
 				it is 0x0D followed by 0x0A */
 
-				if (*sptr == (char)0x0A
-				    || *sptr == (char)0x0D
-				    || *sptr == '\0') {
-
+				switch (*sptr) {
+				case (char) 0X0A:
+				case (char) 0x0D:
+				case '\0':
 					goto scan_more;
 				}
-
-				sptr++;
 			}
 		} else if (!quote && *sptr == '/' && *(sptr + 1) == '*') {
+			sptr += 2;
 			for (;;) {
-				if (*sptr == '*' && *(sptr + 1) == '/') {
-
-					sptr += 2;
-
-					goto scan_more;
+				if (sptr >= eptr) {
+					goto end_of_string;
 				}
 
-				if (*sptr == '\0') {
-
+				switch (*sptr) {
+				case '\0':
 					goto scan_more;
+				case '*':
+					if (sptr[1] == '/') {
+						sptr += 2;
+						goto scan_more;
+					}
 				}
 
 				sptr++;
@@ -3348,6 +3356,7 @@ dict_create_foreign_constraints(
 					name before it: test.table2; the
 					default database id the database of
 					parameter name */
+	size_t		sql_length,	/* in: length of sql_string */
 	const char*	name,		/* in: table full name in the
 					normalized form
 					database_name/table_name */
@@ -3362,7 +3371,7 @@ dict_create_foreign_constraints(
 	ut_a(trx);
 	ut_a(trx->mysql_thd);
 
-	str = dict_strip_comments(sql_string);
+	str = dict_strip_comments(sql_string, sql_length);
 	heap = mem_heap_create(10000);
 
 	err = dict_create_foreign_constraints_low(
@@ -3411,7 +3420,8 @@ dict_foreign_parse_drop_constraints(
 
 	*constraints_to_drop = mem_heap_alloc(heap, 1000 * sizeof(char*));
 
-	str = dict_strip_comments(*(trx->mysql_query_str));
+	str = dict_strip_comments(*trx->mysql_query_str,
+				  *trx->mysql_query_len);
 	ptr = str;
 
 	ut_ad(mutex_own(&(dict_sys->mutex)));

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc	revid:marko.makela@oracle.com-20100514105126-f145hl19y9cay7jx
+++ b/storage/innobase/handler/ha_innodb.cc	revid:marko.makela@stripped00514131050-mkhlvlui1u52irob
@@ -1140,6 +1140,15 @@ innobase_next_autoinc(
 	return(next_value);
 }
 
+/** Copy the current SQL statement.
+* @param[in] thd	MySQL client connection
+* @param[in/out] trx	InnoDB transaction */
+#define INNOBASE_COPY_STMT(thd, trx) do {		\
+	LEX_STRING* stmt = thd_query_string(thd);	\
+	(trx)->mysql_query_str = &stmt->str;		\
+	(trx)->mysql_query_len = &stmt->length;		\
+} while (0)
+
 /*************************************************************************
 Gets the InnoDB transaction handle for a MySQL handler object, creates
 an InnoDB transaction struct if the corresponding MySQL thread struct still
@@ -1160,7 +1169,7 @@ check_trx_exists(
 		trx = trx_allocate_for_mysql();
 
 		trx->mysql_thd = thd;
-		trx->mysql_query_str = thd_query(thd);
+		INNOBASE_COPY_STMT(thd, trx);
 
 		/* Update the info whether we should skip XA steps that eat
 		CPU time */
@@ -5578,7 +5587,7 @@ ha_innobase::create(
 	trx = trx_allocate_for_mysql();
 
 	trx->mysql_thd = thd;
-	trx->mysql_query_str = thd_query(thd);
+	INNOBASE_COPY_STMT(thd, trx);
 
 	if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
 		trx->check_foreigns = FALSE;
@@ -5674,8 +5683,10 @@ ha_innobase::create(
 	}
 
 	if (*trx->mysql_query_str) {
-		error = row_table_add_foreign_constraints(trx,
-			*trx->mysql_query_str, norm_name,
+		error = row_table_add_foreign_constraints(
+			trx,
+			*trx->mysql_query_str, *trx->mysql_query_len,
+			norm_name,
 			create_info->options & HA_LEX_CREATE_TMP_TABLE);
 
 		error = convert_error_code_to_mysql(error, NULL);
@@ -5866,7 +5877,7 @@ ha_innobase::delete_table(
 	trx = trx_allocate_for_mysql();
 
 	trx->mysql_thd = thd;
-	trx->mysql_query_str = thd_query(thd);
+	INNOBASE_COPY_STMT(thd, trx);
 
 	if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
 		trx->check_foreigns = FALSE;
@@ -5955,7 +5966,7 @@ innobase_drop_database(
 #endif
 	trx = trx_allocate_for_mysql();
 	trx->mysql_thd = thd;
-	trx->mysql_query_str = thd_query(thd);
+	INNOBASE_COPY_STMT(thd, trx);
 
 	if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
 		trx->check_foreigns = FALSE;
@@ -6025,7 +6036,7 @@ ha_innobase::rename_table(
 
 	trx = trx_allocate_for_mysql();
 	trx->mysql_thd = thd;
-	trx->mysql_query_str = thd_query(thd);
+	INNOBASE_COPY_STMT(thd, trx);
 
 	if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
 		trx->check_foreigns = FALSE;

=== modified file 'storage/innobase/handler/ha_innodb.h'
--- a/storage/innobase/handler/ha_innodb.h	revid:marko.makela@stripped
+++ b/storage/innobase/handler/ha_innodb.h	revid:marko.makela@stripped
@@ -210,7 +210,7 @@ the definitions are bracketed with #ifde
 
 extern "C" {
 struct charset_info_st *thd_charset(MYSQL_THD thd);
-char **thd_query(MYSQL_THD thd);
+LEX_STRING *thd_query_string(MYSQL_THD thd);
 
 /** Get the file name of the MySQL binlog.
  * @return the name of the binlog file

=== modified file 'storage/innobase/include/dict0dict.h'
--- a/storage/innobase/include/dict0dict.h	revid:marko.makela@stripped
+++ b/storage/innobase/include/dict0dict.h	revid:marko.makela@oracle.com-20100514131050-mkhlvlui1u52irob
@@ -309,6 +309,7 @@ dict_create_foreign_constraints(
 					name before it: test.table2; the
 					default database id the database of
 					parameter name */
+	size_t		sql_length,	/* in: length of sql_string */
 	const char*	name,		/* in: table full name in the
 					normalized form
 					database_name/table_name */

=== modified file 'storage/innobase/include/row0mysql.h'
--- a/storage/innobase/include/row0mysql.h	revid:marko.makela@stripped19y9cay7jx
+++ b/storage/innobase/include/row0mysql.h	revid:marko.makela@strippedb
@@ -366,6 +366,7 @@ row_table_add_foreign_constraints(
 				FOREIGN KEY (a, b) REFERENCES table2(c, d),
 					table2 can be written also with the
 					database name before it: test.table2 */
+	size_t		sql_length,	/* in: length of sql_string */
 	const char*	name,		/* in: table full name in the
 					normalized form
 					database_name/table_name */

=== modified file 'storage/innobase/include/trx0trx.h'
--- a/storage/innobase/include/trx0trx.h	revid:marko.makela@stripped
+++ b/storage/innobase/include/trx0trx.h	revid:marko.makela@stripped
@@ -444,6 +444,8 @@ struct trx_struct{
 	char**		mysql_query_str;/* pointer to the field in mysqld_thd
 					which contains the pointer to the
 					current SQL query string */
+	size_t*		mysql_query_len;/* pointer to the length of the
+					current SQL query string */
 	const char*	mysql_log_file_name;
 					/* if MySQL binlog is used, this field
 					contains a pointer to the latest file

=== modified file 'storage/innobase/row/row0mysql.c'
--- a/storage/innobase/row/row0mysql.c	revid:marko.makela@stripped4105126-f145hl19y9cay7jx
+++ b/storage/innobase/row/row0mysql.c	revid:marko.makela@strippedlui1u52irob
@@ -2103,6 +2103,7 @@ row_table_add_foreign_constraints(
 				FOREIGN KEY (a, b) REFERENCES table2(c, d),
 					table2 can be written also with the
 					database name before it: test.table2 */
+	size_t		sql_length,	/* in: length of sql_string */
 	const char*	name,		/* in: table full name in the
 					normalized form
 					database_name/table_name */
@@ -2124,8 +2125,8 @@ row_table_add_foreign_constraints(
 
 	trx->dict_operation = TRUE;
 
-	err = dict_create_foreign_constraints(trx, sql_string, name,
-					      reject_fks);
+	err = dict_create_foreign_constraints(trx, sql_string, sql_length,
+					      name, reject_fks);
 
 	if (err == DB_SUCCESS) {
 		/* Check that also referencing constraints are ok */

=== modified file 'storage/innobase/trx/trx0trx.c'
--- a/storage/innobase/trx/trx0trx.c	revid:marko.makela@stripped14105126-f145hl19y9cay7jx
+++ b/storage/innobase/trx/trx0trx.c	revid:marko.makela@strippedui1u52irob
@@ -131,6 +131,8 @@ trx_create(
 
 	trx->mysql_thd = NULL;
 	trx->mysql_query_str = NULL;
+	trx->mysql_query_len = NULL;
+
 	trx->active_trans = 0;
 	trx->duplicates = 0;
 
@@ -936,6 +938,7 @@ trx_commit_off_kernel(
 	trx->undo_no = ut_dulint_zero;
 	trx->last_sql_stat_start.least_undo_no = ut_dulint_zero;
 	trx->mysql_query_str = NULL;
+	trx->mysql_query_len = NULL;
 
 	ut_ad(UT_LIST_GET_LEN(trx->wait_thrs) == 0);
 	ut_ad(UT_LIST_GET_LEN(trx->trx_locks) == 0);

=== modified file 'storage/innodb_plugin/ChangeLog'
--- a/storage/innodb_plugin/ChangeLog	revid:marko.makela@strippedjx
+++ b/storage/innodb_plugin/ChangeLog	revid:marko.makela@stripped
@@ -1,3 +1,11 @@
+2010-05-14	The InnoDB Team
+	* mysql-test/innodb_bug48024.test, mysql-test/innodb_bug48024.result,
+	dict/dict0dict.c, handler/ha_innodb.cc, handler/ha_innodb.h,
+	include/dict0dict.h, include/ha_prototypes.h, include/row0mysql.h,
+	include/trx0trx.h, row/row0mysql.c, trx/trx0i_s.c, trx/trx0trx.c:
+	Fix Bug#48024 Innodb doesn't work with multi-statements
+	Fix Bug#53644 InnoDB thinks that /*/ starts and ends a comment
+
 2010-05-12	The InnoDB Team
 
 	* handler/handler0alter.cc:

=== modified file 'storage/innodb_plugin/dict/dict0dict.c'
--- a/storage/innodb_plugin/dict/dict0dict.c	revid:marko.makela@stripped0100514105126-f145hl19y9cay7jx
+++ b/storage/innodb_plugin/dict/dict0dict.c	revid:marko.makela@stripped131050-mkhlvlui1u52irob
@@ -3008,25 +3008,28 @@ static
 char*
 dict_strip_comments(
 /*================*/
-	const char*	sql_string)	/*!< in: SQL string */
+	const char*	sql_string,	/*!< in: SQL string */
+	size_t		sql_length)	/*!< in: length of sql_string */
 {
 	char*		str;
 	const char*	sptr;
+	const char*	eptr	= sql_string + sql_length;
 	char*		ptr;
 	/* unclosed quote character (0 if none) */
 	char		quote	= 0;
 
-	str = mem_alloc(strlen(sql_string) + 1);
+	str = mem_alloc(sql_length + 1);
 
 	sptr = sql_string;
 	ptr = str;
 
 	for (;;) {
 scan_more:
-		if (*sptr == '\0') {
+		if (sptr >= eptr || *sptr == '\0') {
+end_of_string:
 			*ptr = '\0';
 
-			ut_a(ptr <= str + strlen(sql_string));
+			ut_a(ptr <= str + sql_length);
 
 			return(str);
 		}
@@ -3045,30 +3048,35 @@ scan_more:
 			   || (sptr[0] == '-' && sptr[1] == '-'
 			       && sptr[2] == ' ')) {
 			for (;;) {
+				if (++sptr >= eptr) {
+					goto end_of_string;
+				}
+
 				/* In Unix a newline is 0x0A while in Windows
 				it is 0x0D followed by 0x0A */
 
-				if (*sptr == (char)0x0A
-				    || *sptr == (char)0x0D
-				    || *sptr == '\0') {
-
+				switch (*sptr) {
+				case (char) 0X0A:
+				case (char) 0x0D:
+				case '\0':
 					goto scan_more;
 				}
-
-				sptr++;
 			}
 		} else if (!quote && *sptr == '/' && *(sptr + 1) == '*') {
+			sptr += 2;
 			for (;;) {
-				if (*sptr == '*' && *(sptr + 1) == '/') {
-
-					sptr += 2;
-
-					goto scan_more;
+				if (sptr >= eptr) {
+					goto end_of_string;
 				}
 
-				if (*sptr == '\0') {
-
+				switch (*sptr) {
+				case '\0':
 					goto scan_more;
+				case '*':
+					if (sptr[1] == '/') {
+						sptr += 2;
+						goto scan_more;
+					}
 				}
 
 				sptr++;
@@ -3749,6 +3757,7 @@ dict_create_foreign_constraints(
 					name before it: test.table2; the
 					default database id the database of
 					parameter name */
+	size_t		sql_length,	/*!< in: length of sql_string */
 	const char*	name,		/*!< in: table full name in the
 					normalized form
 					database_name/table_name */
@@ -3763,7 +3772,7 @@ dict_create_foreign_constraints(
 	ut_a(trx);
 	ut_a(trx->mysql_thd);
 
-	str = dict_strip_comments(sql_string);
+	str = dict_strip_comments(sql_string, sql_length);
 	heap = mem_heap_create(10000);
 
 	err = dict_create_foreign_constraints_low(
@@ -3796,6 +3805,7 @@ dict_foreign_parse_drop_constraints(
 	dict_foreign_t*		foreign;
 	ibool			success;
 	char*			str;
+	size_t			len;
 	const char*		ptr;
 	const char*		id;
 	FILE*			ef	= dict_foreign_err_file;
@@ -3810,7 +3820,10 @@ dict_foreign_parse_drop_constraints(
 
 	*constraints_to_drop = mem_heap_alloc(heap, 1000 * sizeof(char*));
 
-	str = dict_strip_comments(*(trx->mysql_query_str));
+	ptr = innobase_get_stmt(trx->mysql_thd, &len);
+
+	str = dict_strip_comments(ptr, len);
+
 	ptr = str;
 
 	ut_ad(mutex_own(&(dict_sys->mutex)));

=== modified file 'storage/innodb_plugin/handler/ha_innodb.cc'
--- a/storage/innodb_plugin/handler/ha_innodb.cc	revid:marko.makela@strippeday7jx
+++ b/storage/innodb_plugin/handler/ha_innodb.cc	revid:marko.makela@strippedob
@@ -1004,6 +1004,29 @@ innobase_get_charset(
 	return(thd_charset((THD*) mysql_thd));
 }
 
+/**********************************************************************//**
+Determines the current SQL statement.
+@return	SQL statement string */
+extern "C" UNIV_INTERN
+const char*
+innobase_get_stmt(
+/*==============*/
+	void*	mysql_thd,	/*!< in: MySQL thread handle */
+	size_t*	length)		/*!< out: length of the SQL statement */
+{
+#if MYSQL_VERSION_ID >= 50142
+	LEX_STRING* stmt;
+
+	stmt = thd_query_string((THD*) mysql_thd);
+	*length = stmt->length;
+	return(stmt->str);
+#else
+	const char*	stmt_str = thd_query((THD*) mysql_thd);
+	*length = strlen(stmt_str);
+	return(stmt_str);
+#endif
+}
+
 #if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
 extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list;
 /*******************************************************************//**
@@ -1314,7 +1337,6 @@ innobase_trx_allocate(
 	trx = trx_allocate_for_mysql();
 
 	trx->mysql_thd = thd;
-	trx->mysql_query_str = thd_query(thd);
 
 	innobase_trx_init(thd, trx);
 
@@ -6433,6 +6455,8 @@ ha_innobase::create(
 	/* Cache the value of innodb_file_format, in case it is
 	modified by another thread while the table is being created. */
 	const ulint	file_format = srv_file_format;
+	const char*	stmt;
+	size_t		stmt_len;
 
 	DBUG_ENTER("ha_innobase::create");
 
@@ -6709,9 +6733,11 @@ ha_innobase::create(
 		}
 	}
 
-	if (*trx->mysql_query_str) {
-		error = row_table_add_foreign_constraints(trx,
-			*trx->mysql_query_str, norm_name,
+	stmt = innobase_get_stmt(thd, &stmt_len);
+
+	if (stmt) {
+		error = row_table_add_foreign_constraints(
+			trx, stmt, stmt_len, norm_name,
 			create_info->options & HA_LEX_CREATE_TMP_TABLE);
 
 		error = convert_error_code_to_mysql(error, flags, NULL);
@@ -6996,7 +7022,6 @@ innobase_drop_database(
 	/* In the Windows plugin, thd = current_thd is always NULL */
 	trx = trx_allocate_for_mysql();
 	trx->mysql_thd = NULL;
-	trx->mysql_query_str = NULL;
 #else
 	trx = innobase_trx_allocate(thd);
 #endif

=== modified file 'storage/innodb_plugin/handler/ha_innodb.h'
--- a/storage/innodb_plugin/handler/ha_innodb.h	revid:marko.makela@stripped
+++ b/storage/innodb_plugin/handler/ha_innodb.h	revid:marko.makela@stripped
@@ -231,7 +231,11 @@ the definitions are bracketed with #ifde
 
 extern "C" {
 struct charset_info_st *thd_charset(MYSQL_THD thd);
+#if MYSQL_VERSION_ID >= 50142
+LEX_STRING *thd_query_string(MYSQL_THD thd);
+#else
 char **thd_query(MYSQL_THD thd);
+#endif
 
 /** Get the file name of the MySQL binlog.
  * @return the name of the binlog file

=== modified file 'storage/innodb_plugin/include/dict0dict.h'
--- a/storage/innodb_plugin/include/dict0dict.h	revid:marko.makela@stripped
+++ b/storage/innodb_plugin/include/dict0dict.h	revid:marko.makela@stripped
@@ -352,6 +352,7 @@ dict_create_foreign_constraints(
 					name before it: test.table2; the
 					default database id the database of
 					parameter name */
+	size_t		sql_length,	/*!< in: length of sql_string */
 	const char*	name,		/*!< in: table full name in the
 					normalized form
 					database_name/table_name */

=== modified file 'storage/innodb_plugin/include/ha_prototypes.h'
--- a/storage/innodb_plugin/include/ha_prototypes.h	revid:marko.makela@oracle.com-20100514105126-f145hl19y9cay7jx
+++ b/storage/innodb_plugin/include/ha_prototypes.h	revid:marko.makela@oracle.com-20100514131050-mkhlvlui1u52irob
@@ -215,11 +215,21 @@ innobase_casedn_str(
 /**********************************************************************//**
 Determines the connection character set.
 @return	connection character set */
+UNIV_INTERN
 struct charset_info_st*
 innobase_get_charset(
 /*=================*/
 	void*	mysql_thd);	/*!< in: MySQL thread handle */
-
+/**********************************************************************//**
+Determines the current SQL statement.
+@return	SQL statement string */
+UNIV_INTERN
+const char*
+innobase_get_stmt(
+/*==============*/
+	void*	mysql_thd,	/*!< in: MySQL thread handle */
+	size_t*	length)		/*!< out: length of the SQL statement */
+	__attribute__((nonnull));
 /******************************************************************//**
 This function is used to find the storage length in bytes of the first n
 characters for prefix indexes using a multibyte character set. The function

=== modified file 'storage/innodb_plugin/include/row0mysql.h'
--- a/storage/innodb_plugin/include/row0mysql.h	revid:marko.makela@oracle.com-20100514105126-f145hl19y9cay7jx
+++ b/storage/innodb_plugin/include/row0mysql.h	revid:marko.makela@oracle.com-20100514131050-mkhlvlui1u52irob
@@ -403,6 +403,7 @@ row_table_add_foreign_constraints(
 				FOREIGN KEY (a, b) REFERENCES table2(c, d),
 					table2 can be written also with the
 					database name before it: test.table2 */
+	size_t		sql_length,	/*!< in: length of sql_string */
 	const char*	name,		/*!< in: table full name in the
 					normalized form
 					database_name/table_name */

=== modified file 'storage/innodb_plugin/include/trx0trx.h'
--- a/storage/innodb_plugin/include/trx0trx.h	revid:marko.makela@stripped
+++ b/storage/innodb_plugin/include/trx0trx.h	revid:marko.makela@stripped
@@ -560,9 +560,6 @@ struct trx_struct{
 	/*------------------------------*/
 	void*		mysql_thd;	/*!< MySQL thread handle corresponding
 					to this trx, or NULL */
-	char**		mysql_query_str;/* pointer to the field in mysqld_thd
-					which contains the pointer to the
-					current SQL query string */
 	const char*	mysql_log_file_name;
 					/* if MySQL binlog is used, this field
 					contains a pointer to the latest file

=== modified file 'storage/innodb_plugin/row/row0mysql.c'
--- a/storage/innodb_plugin/row/row0mysql.c	revid:marko.makela@stripped19y9cay7jx
+++ b/storage/innodb_plugin/row/row0mysql.c	revid:marko.makela@strippedob
@@ -2059,6 +2059,7 @@ row_table_add_foreign_constraints(
 				FOREIGN KEY (a, b) REFERENCES table2(c, d),
 					table2 can be written also with the
 					database name before it: test.table2 */
+	size_t		sql_length,	/*!< in: length of sql_string */
 	const char*	name,		/*!< in: table full name in the
 					normalized form
 					database_name/table_name */
@@ -2080,8 +2081,8 @@ row_table_add_foreign_constraints(
 
 	trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
 
-	err = dict_create_foreign_constraints(trx, sql_string, name,
-					      reject_fks);
+	err = dict_create_foreign_constraints(trx, sql_string, sql_length,
+					      name, reject_fks);
 	if (err == DB_SUCCESS) {
 		/* Check that also referencing constraints are ok */
 		err = dict_load_foreigns(name, TRUE);

=== modified file 'storage/innodb_plugin/trx/trx0i_s.c'
--- a/storage/innodb_plugin/trx/trx0i_s.c	revid:marko.makela@stripped-20100514105126-f145hl19y9cay7jx
+++ b/storage/innodb_plugin/trx/trx0i_s.c	revid:marko.makela@stripped31050-mkhlvlui1u52irob
@@ -429,6 +429,9 @@ fill_trx_row(
 						which to copy volatile
 						strings */
 {
+	const char*	stmt;
+	size_t		stmt_len;
+
 	row->trx_id = trx_get_id(trx);
 	row->trx_started = (ib_time_t) trx->start_time;
 	row->trx_state = trx_get_que_state_str(trx);
@@ -449,38 +452,33 @@ fill_trx_row(
 
 	row->trx_weight = (ullint) ut_conv_dulint_to_longlong(TRX_WEIGHT(trx));
 
-	if (trx->mysql_thd != NULL) {
-		row->trx_mysql_thread_id
-			= thd_get_thread_id(trx->mysql_thd);
-	} else {
+	if (trx->mysql_thd == NULL) {
 		/* For internal transactions e.g., purge and transactions
 		being recovered at startup there is no associated MySQL
 		thread data structure. */
 		row->trx_mysql_thread_id = 0;
+		row->trx_query = NULL;
+		return(TRUE);
 	}
 
-	if (trx->mysql_query_str != NULL && *trx->mysql_query_str != NULL) {
+	row->trx_mysql_thread_id = thd_get_thread_id(trx->mysql_thd);
+	stmt = innobase_get_stmt(trx->mysql_thd, &stmt_len);
 
-		if (strlen(*trx->mysql_query_str)
-		    > TRX_I_S_TRX_QUERY_MAX_LEN) {
+	if (stmt != NULL) {
 
-			char	query[TRX_I_S_TRX_QUERY_MAX_LEN + 1];
+		char	query[TRX_I_S_TRX_QUERY_MAX_LEN + 1];
 
-			memcpy(query, *trx->mysql_query_str,
-			       TRX_I_S_TRX_QUERY_MAX_LEN);
-			query[TRX_I_S_TRX_QUERY_MAX_LEN] = '\0';
-
-			row->trx_query = ha_storage_put_memlim(
-				cache->storage, query,
-				TRX_I_S_TRX_QUERY_MAX_LEN + 1,
-				MAX_ALLOWED_FOR_STORAGE(cache));
-		} else {
-
-			row->trx_query = ha_storage_put_str_memlim(
-				cache->storage, *trx->mysql_query_str,
-				MAX_ALLOWED_FOR_STORAGE(cache));
+		if (stmt_len > TRX_I_S_TRX_QUERY_MAX_LEN) {
+			stmt_len = TRX_I_S_TRX_QUERY_MAX_LEN;
 		}
 
+		memcpy(query, stmt, stmt_len);
+		query[stmt_len] = '\0';
+
+		row->trx_query = ha_storage_put_memlim(
+			cache->storage, stmt, stmt_len + 1,
+			MAX_ALLOWED_FOR_STORAGE(cache));
+
 		if (row->trx_query == NULL) {
 
 			return(FALSE);

=== modified file 'storage/innodb_plugin/trx/trx0trx.c'
--- a/storage/innodb_plugin/trx/trx0trx.c	revid:marko.makela@stripped145hl19y9cay7jx
+++ b/storage/innodb_plugin/trx/trx0trx.c	revid:marko.makela@stripped2irob
@@ -119,7 +119,6 @@ trx_create(
 	trx->table_id = ut_dulint_zero;
 
 	trx->mysql_thd = NULL;
-	trx->mysql_query_str = NULL;
 	trx->active_trans = 0;
 	trx->duplicates = 0;
 
@@ -940,7 +939,6 @@ trx_commit_off_kernel(
 	trx->rseg = NULL;
 	trx->undo_no = ut_dulint_zero;
 	trx->last_sql_stat_start.least_undo_no = ut_dulint_zero;
-	trx->mysql_query_str = NULL;
 
 	ut_ad(UT_LIST_GET_LEN(trx->wait_thrs) == 0);
 	ut_ad(UT_LIST_GET_LEN(trx->trx_locks) == 0);

Attachment: [text/bzr-bundle] bzr/marko.makela@oracle.com-20100514131050-mkhlvlui1u52irob.bundle
Thread
bzr push into mysql-5.1-innodb branch (marko.makela:3464 to 3467) Bug#48024Bug#53644marko.makela14 May