summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/ps.result18
-rw-r--r--mysql-test/t/ps.test21
-rw-r--r--sql/sql_lex.h5
-rw-r--r--sql/sql_show.cc5
4 files changed, 44 insertions, 5 deletions
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 5b638fd58ab..94972ea8721 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -524,3 +524,21 @@ execute stmt using @a, @b, @c;
a b c a b c
deallocate prepare stmt;
drop table t1,t2;
+SET @aux= "SELECT COUNT(*)
+ FROM INFORMATION_SCHEMA.COLUMNS A,
+ INFORMATION_SCHEMA.COLUMNS B
+ WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA
+ AND A.TABLE_NAME = B.TABLE_NAME
+ AND A.COLUMN_NAME = B.COLUMN_NAME AND
+ A.TABLE_NAME = 'user'";
+prepare my_stmt from @aux;
+execute my_stmt;
+COUNT(*)
+37
+execute my_stmt;
+COUNT(*)
+37
+execute my_stmt;
+COUNT(*)
+37
+deallocate prepare my_stmt;
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 1af84119b79..271d553e221 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -540,3 +540,24 @@ deallocate prepare stmt;
drop table t1,t2;
+
+#
+# Bug#9383: INFORMATION_SCHEMA.COLUMNS, JOIN, Crash, prepared statement
+#
+
+eval SET @aux= "SELECT COUNT(*)
+ FROM INFORMATION_SCHEMA.COLUMNS A,
+ INFORMATION_SCHEMA.COLUMNS B
+ WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA
+ AND A.TABLE_NAME = B.TABLE_NAME
+ AND A.COLUMN_NAME = B.COLUMN_NAME AND
+ A.TABLE_NAME = 'user'";
+
+let $exec_loop_count= 3;
+eval prepare my_stmt from @aux;
+while ($exec_loop_count)
+{
+ eval execute my_stmt;
+ dec $exec_loop_count;
+}
+deallocate prepare my_stmt;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 8aba3be7607..32a62173059 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -701,8 +701,9 @@ typedef struct st_lex
TABLE_LIST *query_tables; /* global list of all tables in this query */
/*
last element next_global of previous list (used only for list building
- during parsing and VIEW processing. This pointer is not valid in
- mysql_execute_command
+ during parsing and VIEW processing. This pointer could be invalid during
+ processing of information schema tables(see get_schema_tables_result
+ function)
*/
TABLE_LIST **query_tables_last;
TABLE_LIST *proc_table; /* refer to mysql.proc if it was opened by VIEW */
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index d92613bd633..d2cab6bf49f 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -3442,12 +3442,11 @@ bool get_schema_tables_result(JOIN *join)
TABLE_LIST *table_list= tab->table->pos_in_table_list;
if (table_list->schema_table && thd->fill_derived_tables())
{
- TABLE_LIST *save_next_global= table_list->next_global;
TABLE_LIST **query_tables_last= lex->query_tables_last;
TABLE *old_derived_tables= thd->derived_tables;
MYSQL_LOCK *sql_lock= thd->lock;
lex->sql_command= SQLCOM_SHOW_FIELDS;
-
+ DBUG_ASSERT(!*query_tables_last);
if (&lex->unit != lex->current_select->master_unit()) // is subselect
{
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
@@ -3466,8 +3465,8 @@ bool get_schema_tables_result(JOIN *join)
thd->lock= sql_lock;
lex->sql_command= SQLCOM_SELECT;
thd->derived_tables= old_derived_tables;
- table_list->next_global= save_next_global;
lex->query_tables_last= query_tables_last;
+ *query_tables_last= 0;
}
}
thd->no_warnings_for_error= 0;