diff options
-rw-r--r-- | mysql-test/r/ps.result | 18 | ||||
-rw-r--r-- | mysql-test/t/ps.test | 21 | ||||
-rw-r--r-- | sql/sql_lex.h | 5 | ||||
-rw-r--r-- | sql/sql_show.cc | 5 |
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; |