Fix for bug#9383: INFORMATION_SCHEMA.COLUMNS, JOIN, Crash, prepared statement

   restore original 'lex->query_tables' table list after
   processing of information schema table
   remove unnecessary operations
parent 9dd3e180
...@@ -524,3 +524,21 @@ execute stmt using @a, @b, @c; ...@@ -524,3 +524,21 @@ execute stmt using @a, @b, @c;
a b c a b c a b c a b c
deallocate prepare stmt; deallocate prepare stmt;
drop table t1,t2; 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;
...@@ -540,3 +540,24 @@ deallocate prepare stmt; ...@@ -540,3 +540,24 @@ deallocate prepare stmt;
drop table t1,t2; 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;
...@@ -701,8 +701,9 @@ typedef struct st_lex ...@@ -701,8 +701,9 @@ typedef struct st_lex
TABLE_LIST *query_tables; /* global list of all tables in this query */ TABLE_LIST *query_tables; /* global list of all tables in this query */
/* /*
last element next_global of previous list (used only for list building last element next_global of previous list (used only for list building
during parsing and VIEW processing. This pointer is not valid in during parsing and VIEW processing. This pointer could be invalid during
mysql_execute_command processing of information schema tables(see get_schema_tables_result
function)
*/ */
TABLE_LIST **query_tables_last; TABLE_LIST **query_tables_last;
TABLE_LIST *proc_table; /* refer to mysql.proc if it was opened by VIEW */ TABLE_LIST *proc_table; /* refer to mysql.proc if it was opened by VIEW */
......
...@@ -3442,12 +3442,11 @@ bool get_schema_tables_result(JOIN *join) ...@@ -3442,12 +3442,11 @@ bool get_schema_tables_result(JOIN *join)
TABLE_LIST *table_list= tab->table->pos_in_table_list; TABLE_LIST *table_list= tab->table->pos_in_table_list;
if (table_list->schema_table && thd->fill_derived_tables()) 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_LIST **query_tables_last= lex->query_tables_last;
TABLE *old_derived_tables= thd->derived_tables; TABLE *old_derived_tables= thd->derived_tables;
MYSQL_LOCK *sql_lock= thd->lock; MYSQL_LOCK *sql_lock= thd->lock;
lex->sql_command= SQLCOM_SHOW_FIELDS; lex->sql_command= SQLCOM_SHOW_FIELDS;
DBUG_ASSERT(!*query_tables_last);
if (&lex->unit != lex->current_select->master_unit()) // is subselect if (&lex->unit != lex->current_select->master_unit()) // is subselect
{ {
table_list->table->file->extra(HA_EXTRA_RESET_STATE); table_list->table->file->extra(HA_EXTRA_RESET_STATE);
...@@ -3466,8 +3465,8 @@ bool get_schema_tables_result(JOIN *join) ...@@ -3466,8 +3465,8 @@ bool get_schema_tables_result(JOIN *join)
thd->lock= sql_lock; thd->lock= sql_lock;
lex->sql_command= SQLCOM_SELECT; lex->sql_command= SQLCOM_SELECT;
thd->derived_tables= old_derived_tables; thd->derived_tables= old_derived_tables;
table_list->next_global= save_next_global;
lex->query_tables_last= query_tables_last; lex->query_tables_last= query_tables_last;
*query_tables_last= 0;
} }
} }
thd->no_warnings_for_error= 0; thd->no_warnings_for_error= 0;
......
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