diff options
author | unknown <pekka@mysql.com> | 2006-05-30 22:54:06 +0200 |
---|---|---|
committer | unknown <pekka@mysql.com> | 2006-05-30 22:54:06 +0200 |
commit | f90f2c58d3bf366d28d76b63399e21e12c0b12cb (patch) | |
tree | 9463ea754946d7d52715828c856838a7e6f9d8c7 | |
parent | 63da222ae0f484ed11bf3dad6f1f54dc4ae46096 (diff) | |
parent | 8a5ca696ec572c7583ab5f73a726ce04fe72c413 (diff) | |
download | mariadb-git-f90f2c58d3bf366d28d76b63399e21e12c0b12cb.tar.gz |
Merge pnousiainen@bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/space/pekka/ndb/version/my50
-rw-r--r-- | client/mysqlbinlog.cc | 17 | ||||
-rw-r--r-- | mysql-test/r/information_schema_db.result | 57 | ||||
-rw-r--r-- | mysql-test/t/information_schema_db.test | 60 | ||||
-rw-r--r-- | mysql-test/t/rpl_insert_id.test | 2 | ||||
-rw-r--r-- | server-tools/instance-manager/guardian.cc | 22 | ||||
-rw-r--r-- | server-tools/instance-manager/manager.cc | 46 | ||||
-rw-r--r-- | sql/sql_lex.cc | 108 | ||||
-rw-r--r-- | sql/sql_lex.h | 151 | ||||
-rw-r--r-- | sql/sql_show.cc | 17 | ||||
-rw-r--r-- | sql/sql_table.cc | 2 |
10 files changed, 365 insertions, 117 deletions
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 60b54a2ed99..518ab7cf832 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -71,6 +71,7 @@ static int port= 0; static const char* sock= 0; static const char* user = 0; static char* pass = 0; +static char *charset= 0; static ulonglong start_position, stop_position; #define start_position_mot ((my_off_t)start_position) @@ -707,6 +708,9 @@ static struct my_option my_long_options[] = "Used to reserve file descriptors for usage by this program", (gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG, REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0}, + {"set-charset", OPT_SET_CHARSET, + "Add 'SET NAMES character_set' to the output.", (gptr*) &charset, + (gptr*) &charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"short-form", 's', "Just show the queries, no extra info.", (gptr*) &short_form, (gptr*) &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -1430,6 +1434,13 @@ int main(int argc, char** argv) "/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE," "COMPLETION_TYPE=0*/;\n"); + if (charset) + fprintf(result_file, + "\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;" + "\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;" + "\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;" + "\n/*!40101 SET NAMES %s */;\n", charset); + for (save_stop_position= stop_position, stop_position= ~(my_off_t)0 ; (--argc >= 0) && !stop_passed ; ) { @@ -1454,6 +1465,12 @@ int main(int argc, char** argv) if (disable_log_bin) fprintf(result_file, "/*!32316 SET SQL_LOG_BIN=@OLD_SQL_LOG_BIN*/;\n"); + if (charset) + fprintf(result_file, + "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n" + "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n" + "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n"); + if (tmpdir.list) free_tmpdir(&tmpdir); if (result_file != stdout) diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result index 6295bac34a0..61a10c5f72c 100644 --- a/mysql-test/r/information_schema_db.result +++ b/mysql-test/r/information_schema_db.result @@ -1,3 +1,7 @@ +drop table if exists t1,t2; +drop view if exists v1,v2; +drop function if exists f1; +drop function if exists f2; use INFORMATION_SCHEMA; show tables; Tables_in_information_schema @@ -24,10 +28,12 @@ TABLE_CONSTRAINTS TABLE_PRIVILEGES TRIGGERS create database `inf%`; +create database mbase; use `inf%`; show tables; Tables_in_inf% grant all privileges on `inf%`.* to 'mysqltest_1'@'localhost'; +grant all privileges on `mbase`.* to 'mysqltest_1'@'localhost'; create table t1 (f1 int); create function func1(curr_int int) returns int begin @@ -36,9 +42,58 @@ select max(f1) from t1 into ret_val; return ret_val; end| create view v1 as select f1 from t1 where f1 = func1(f1); +create function func2() returns int return 1; +use mbase; +create procedure p1 () +begin +select table_name from information_schema.key_column_usage +order by table_name; +end| +create table t1 +(f1 int(10) unsigned not null, +f2 varchar(100) not null, +primary key (f1), unique key (f2)); select * from information_schema.tables; +call mbase.p1(); +call mbase.p1(); +call mbase.p1(); +use `inf%`; drop user mysqltest_1@localhost; +drop table t1; +select table_name, table_type, table_comment from information_schema.tables +where table_schema='inf%' and func2(); +table_name table_type table_comment +v1 VIEW View 'inf%.v1' references invalid table(s) or column(s) or function(s) or define +select table_name, table_type, table_comment from information_schema.tables +where table_schema='inf%' and func2(); +table_name table_type table_comment +v1 VIEW View 'inf%.v1' references invalid table(s) or column(s) or function(s) or define drop view v1; drop function func1; -drop table t1; +drop function func2; drop database `inf%`; +drop procedure mbase.p1; +drop database mbase; +use test; +create table t1 (i int); +create function f1 () returns int return (select max(i) from t1); +create view v1 as select f1(); +create table t2 (id int); +create function f2 () returns int return (select max(i) from t2); +create view v2 as select f2(); +drop table t2; +select table_name, table_type, table_comment from information_schema.tables +where table_schema='test'; +table_name table_type table_comment +t1 BASE TABLE +v1 VIEW VIEW +v2 VIEW View 'test.v2' references invalid table(s) or column(s) or function(s) or define +drop table t1; +select table_name, table_type, table_comment from information_schema.tables +where table_schema='test'; +table_name table_type table_comment +v1 VIEW View 'test.v1' references invalid table(s) or column(s) or function(s) or define +v2 VIEW View 'test.v2' references invalid table(s) or column(s) or function(s) or define +drop function f1; +drop function f2; +drop view v1, v2; diff --git a/mysql-test/t/information_schema_db.test b/mysql-test/t/information_schema_db.test index b65135a621d..2cfa766d799 100644 --- a/mysql-test/t/information_schema_db.test +++ b/mysql-test/t/information_schema_db.test @@ -1,16 +1,25 @@ -- source include/testdb_only.inc +--disable_warnings +drop table if exists t1,t2; +drop view if exists v1,v2; +drop function if exists f1; +drop function if exists f2; +--enable_warnings + use INFORMATION_SCHEMA; --replace_result Tables_in_INFORMATION_SCHEMA Tables_in_information_schema show tables; --replace_result 'Tables_in_INFORMATION_SCHEMA (T%)' 'Tables_in_information_schema (T%)' show tables from INFORMATION_SCHEMA like 'T%'; create database `inf%`; +create database mbase; use `inf%`; show tables; # # Bug#18113 SELECT * FROM information_schema.xxx crashes server +# Bug#17204 second CALL to procedure crashes Server # Crash happened when one selected data from one of INFORMATION_SCHEMA # tables and in order to build its contents server had to open view which # used stored function and table or view on which one had not global or @@ -18,6 +27,7 @@ show tables; # privileges at all). # grant all privileges on `inf%`.* to 'mysqltest_1'@'localhost'; +grant all privileges on `mbase`.* to 'mysqltest_1'@'localhost'; create table t1 (f1 int); delimiter |; create function func1(curr_int int) returns int @@ -28,15 +38,63 @@ begin end| delimiter ;| create view v1 as select f1 from t1 where f1 = func1(f1); +create function func2() returns int return 1; + +use mbase; +delimiter |; +create procedure p1 () +begin +select table_name from information_schema.key_column_usage +order by table_name; +end| +delimiter ;| + +create table t1 +(f1 int(10) unsigned not null, + f2 varchar(100) not null, + primary key (f1), unique key (f2)); + connect (user1,localhost,mysqltest_1,,); connection user1; --disable_result_log select * from information_schema.tables; +call mbase.p1(); +call mbase.p1(); +call mbase.p1(); --enable_result_log + connection default; +use `inf%`; drop user mysqltest_1@localhost; +drop table t1; +select table_name, table_type, table_comment from information_schema.tables +where table_schema='inf%' and func2(); +select table_name, table_type, table_comment from information_schema.tables +where table_schema='inf%' and func2(); drop view v1; drop function func1; -drop table t1; +drop function func2; drop database `inf%`; +drop procedure mbase.p1; +drop database mbase; + +# +# Bug#18282 INFORMATION_SCHEMA.TABLES provides inconsistent info about invalid views +# +use test; +create table t1 (i int); +create function f1 () returns int return (select max(i) from t1); +create view v1 as select f1(); +create table t2 (id int); +create function f2 () returns int return (select max(i) from t2); +create view v2 as select f2(); +drop table t2; +select table_name, table_type, table_comment from information_schema.tables +where table_schema='test'; +drop table t1; +select table_name, table_type, table_comment from information_schema.tables +where table_schema='test'; +drop function f1; +drop function f2; +drop view v1, v2; diff --git a/mysql-test/t/rpl_insert_id.test b/mysql-test/t/rpl_insert_id.test index ccd80dce388..e038829760d 100644 --- a/mysql-test/t/rpl_insert_id.test +++ b/mysql-test/t/rpl_insert_id.test @@ -148,3 +148,5 @@ drop function bug15728_insert; drop table t1, t2; # End of 5.0 tests + +sync_slave_with_master; diff --git a/server-tools/instance-manager/guardian.cc b/server-tools/instance-manager/guardian.cc index 7a532263846..fa9d877fde6 100644 --- a/server-tools/instance-manager/guardian.cc +++ b/server-tools/instance-manager/guardian.cc @@ -139,9 +139,12 @@ void Guardian_thread::process_instance(Instance *instance, case JUST_CRASHED: if (current_time - current_node->crash_moment <= 2) { - instance->start(); - log_info("guardian: starting instance %s", - instance->options.instance_name); + if (instance->is_crashed()) + { + instance->start(); + log_info("guardian: starting instance %s", + instance->options.instance_name); + } } else current_node->state= CRASHED; @@ -152,11 +155,14 @@ void Guardian_thread::process_instance(Instance *instance, { if ((current_node->restart_counter < restart_retry)) { - instance->start(); - current_node->last_checked= current_time; - current_node->restart_counter++; - log_info("guardian: restarting instance %s", - instance->options.instance_name); + if (instance->is_crashed()) + { + instance->start(); + current_node->last_checked= current_time; + current_node->restart_counter++; + log_info("guardian: restarting instance %s", + instance->options.instance_name); + } } else current_node->state= CRASHED_AND_ABANDONED; diff --git a/server-tools/instance-manager/manager.cc b/server-tools/instance-manager/manager.cc index 90d9d04cd36..00ef50a84e1 100644 --- a/server-tools/instance-manager/manager.cc +++ b/server-tools/instance-manager/manager.cc @@ -147,28 +147,6 @@ void manager(const Options &options) if (create_pid_file(options.pid_file_name, manager_pid)) return; - sigset_t mask; - set_signals(&mask); - - /* create the listener */ - { - pthread_t listener_thd_id; - pthread_attr_t listener_thd_attr; - int rc; - - pthread_attr_init(&listener_thd_attr); - pthread_attr_setdetachstate(&listener_thd_attr, PTHREAD_CREATE_DETACHED); - rc= set_stacksize_n_create_thread(&listener_thd_id, &listener_thd_attr, - listener, &listener_args); - pthread_attr_destroy(&listener_thd_attr); - if (rc) - { - log_error("manager(): set_stacksize_n_create_thread(listener) failed"); - goto err; - } - - } - /* create guardian thread */ { pthread_t guardian_thd_id; @@ -211,6 +189,30 @@ void manager(const Options &options) return; } + /* Initialize signals and alarm-infrastructure. */ + + sigset_t mask; + set_signals(&mask); + + /* create the listener */ + { + pthread_t listener_thd_id; + pthread_attr_t listener_thd_attr; + int rc; + + pthread_attr_init(&listener_thd_attr); + pthread_attr_setdetachstate(&listener_thd_attr, PTHREAD_CREATE_DETACHED); + rc= set_stacksize_n_create_thread(&listener_thd_id, &listener_thd_attr, + listener, &listener_args); + pthread_attr_destroy(&listener_thd_attr); + if (rc) + { + log_error("manager(): set_stacksize_n_create_thread(listener) failed"); + goto err; + } + + } + /* After the list of guarded instances have been initialized, Guardian should start them. diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index c4c72910265..d2699b88aa4 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -151,8 +151,7 @@ void lex_start(THD *thd, uchar *buf,uint length) lex->found_semicolon= 0; lex->safe_to_cache_query= 1; lex->time_zone_tables_used= 0; - lex->leaf_tables_insert= lex->query_tables= 0; - lex->query_tables_last= &lex->query_tables; + lex->leaf_tables_insert= 0; lex->variables_used= 0; lex->empty_field_list_on_rset= 0; lex->select_lex.select_number= 1; @@ -175,14 +174,9 @@ void lex_start(THD *thd, uchar *buf,uint length) lex->sphead= NULL; lex->spcont= NULL; lex->proc_list.first= 0; - lex->query_tables_own_last= 0; lex->escape_used= FALSE; + lex->reset_query_tables_list(FALSE); - if (lex->sroutines.records) - my_hash_reset(&lex->sroutines); - lex->sroutines_list.empty(); - lex->sroutines_list_own_last= lex->sroutines_list.next; - lex->sroutines_list_own_elements= 0; lex->nest_level=0 ; lex->allow_sum_func= 0; lex->in_sum_func= NULL; @@ -1615,6 +1609,52 @@ void st_select_lex::print_limit(THD *thd, String *str) /* + Initialize (or reset) Query_tables_list object. + + SYNOPSIS + reset_query_tables_list() + init TRUE - we should perform full initialization of object with + allocating needed memory + FALSE - object is already initialized so we should only reset + its state so it can be used for parsing/processing + of new statement + + DESCRIPTION + This method initializes Query_tables_list so it can be used as part + of LEX object for parsing/processing of statement. One can also use + this method to reset state of already initialized Query_tables_list + so it can be used for processing of new statement. +*/ + +void Query_tables_list::reset_query_tables_list(bool init) +{ + query_tables= 0; + query_tables_last= &query_tables; + query_tables_own_last= 0; + if (init) + hash_init(&sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0); + else if (sroutines.records) + my_hash_reset(&sroutines); + sroutines_list.empty(); + sroutines_list_own_last= sroutines_list.next; + sroutines_list_own_elements= 0; +} + + +/* + Destroy Query_tables_list object with freeing all resources used by it. + + SYNOPSIS + destroy_query_tables_list() +*/ + +void Query_tables_list::destroy_query_tables_list() +{ + hash_free(&sroutines); +} + + +/* Initialize LEX object. SYNOPSIS @@ -1630,12 +1670,9 @@ void st_select_lex::print_limit(THD *thd, String *str) st_lex::st_lex() :result(0), yacc_yyss(0), yacc_yyvs(0), - sql_command(SQLCOM_END), query_tables_own_last(0) + sql_command(SQLCOM_END) { - hash_init(&sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0); - sroutines_list.empty(); - sroutines_list_own_last= sroutines_list.next; - sroutines_list_own_elements= 0; + reset_query_tables_list(TRUE); } @@ -2019,6 +2056,11 @@ void st_lex::link_first_table_back(TABLE_LIST *first, SYNOPSIS st_lex::cleanup_after_one_table_open() + + NOTE + This method is mostly responsible for cleaning up of selects lists and + derived tables state. To rollback changes in Query_tables_list one has + to call Query_tables_list::reset_query_tables_list(FALSE). */ void st_lex::cleanup_after_one_table_open() @@ -2045,11 +2087,41 @@ void st_lex::cleanup_after_one_table_open() select_lex.cut_subtree(); } time_zone_tables_used= 0; - if (sroutines.records) - my_hash_reset(&sroutines); - sroutines_list.empty(); - sroutines_list_own_last= sroutines_list.next; - sroutines_list_own_elements= 0; +} + + +/* + Save current state of Query_tables_list for this LEX, and prepare it + for processing of new statemnt. + + SYNOPSIS + reset_n_backup_query_tables_list() + backup Pointer to Query_tables_list instance to be used for backup +*/ + +void st_lex::reset_n_backup_query_tables_list(Query_tables_list *backup) +{ + backup->set_query_tables_list(this); + /* + We have to perform full initialization here since otherwise we + will damage backed up state. + */ + this->reset_query_tables_list(TRUE); +} + + +/* + Restore state of Query_tables_list for this LEX from backup. + + SYNOPSIS + restore_backup_query_tables_list() + backup Pointer to Query_tables_list instance used for backup +*/ + +void st_lex::restore_backup_query_tables_list(Query_tables_list *backup) +{ + this->destroy_query_tables_list(); + this->set_query_tables_list(backup); } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 34e7ee969b6..6b5c6ddca60 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -702,9 +702,95 @@ extern sys_var_long_ptr trg_new_row_fake_var; enum xa_option_words {XA_NONE, XA_JOIN, XA_RESUME, XA_ONE_PHASE, XA_SUSPEND, XA_FOR_MIGRATE}; + +/* + Class representing list of all tables used by statement. + It also contains information about stored functions used by statement + since during its execution we may have to add all tables used by its + stored functions/triggers to this list in order to pre-open and lock + them. + + Also used by st_lex::reset_n_backup/restore_backup_query_tables_list() + methods to save and restore this information. +*/ + +class Query_tables_list +{ +public: + /* Global list of all tables used by this statement */ + TABLE_LIST *query_tables; + /* Pointer to next_global member of last element in the previous list. */ + TABLE_LIST **query_tables_last; + /* + If non-0 then indicates that query requires prelocking and points to + next_global member of last own element in query table list (i.e. last + table which was not added to it as part of preparation to prelocking). + 0 - indicates that this query does not need prelocking. + */ + TABLE_LIST **query_tables_own_last; + /* Set of stored routines called by statement. */ + HASH sroutines; + /* + List linking elements of 'sroutines' set. Allows you to add new elements + to this set as you iterate through the list of existing elements. + 'sroutines_list_own_last' is pointer to ::next member of last element of + this list which represents routine which is explicitly used by query. + 'sroutines_list_own_elements' number of explicitly used routines. + We use these two members for restoring of 'sroutines_list' to the state + in which it was right after query parsing. + */ + SQL_LIST sroutines_list; + byte **sroutines_list_own_last; + uint sroutines_list_own_elements; + + /* + These constructor and destructor serve for creation/destruction + of Query_tables_list instances which are used as backup storage. + */ + Query_tables_list() {} + ~Query_tables_list() {} + + /* Initializes (or resets) Query_tables_list object for "real" use. */ + void reset_query_tables_list(bool init); + void destroy_query_tables_list(); + void set_query_tables_list(Query_tables_list *state) + { + *this= *state; + } + + void add_to_query_tables(TABLE_LIST *table) + { + *(table->prev_global= query_tables_last)= table; + query_tables_last= &table->next_global; + } + bool requires_prelocking() + { + return test(query_tables_own_last); + } + void mark_as_requiring_prelocking(TABLE_LIST **tables_own_last) + { + query_tables_own_last= tables_own_last; + } + /* Return pointer to first not-own table in query-tables or 0 */ + TABLE_LIST* first_not_own_table() + { + return ( query_tables_own_last ? *query_tables_own_last : 0); + } + void chop_off_not_own_tables() + { + if (query_tables_own_last) + { + *query_tables_own_last= 0; + query_tables_last= query_tables_own_last; + query_tables_own_last= 0; + } + } +}; + + /* The state of the lex parsing. This is saved in the THD struct */ -typedef struct st_lex +typedef struct st_lex : public Query_tables_list { uint yylineno,yytoklen; /* Simulate lex */ LEX_YYSTYPE yylval; @@ -736,14 +822,6 @@ typedef struct st_lex gptr yacc_yyss,yacc_yyvs; THD *thd; CHARSET_INFO *charset; - 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 could be invalid during - processing of information schema tables(see get_schema_tables_result - function) - */ - TABLE_LIST **query_tables_last; /* store original leaf_tables for INSERT SELECT and PS/SP */ TABLE_LIST *leaf_tables_insert; /* Position (first character index) of SELECT of CREATE VIEW statement */ @@ -876,20 +954,6 @@ typedef struct st_lex bool sp_lex_in_use; /* Keep track on lex usage in SPs for error handling */ bool all_privileges; sp_pcontext *spcont; - /* Set of stored routines called by statement. */ - HASH sroutines; - /* - List linking elements of 'sroutines' set. Allows you to add new elements - to this set as you iterate through the list of existing elements. - 'sroutines_list_own_last' is pointer to ::next member of last element of - this list which represents routine which is explicitly used by query. - 'sroutines_list_own_elements' number of explicitly used routines. - We use these two members for restoring of 'sroutines_list' to the state - in which it was right after query parsing. - */ - SQL_LIST sroutines_list; - byte **sroutines_list_own_last; - uint sroutines_list_own_elements; st_sp_chistics sp_chistics; bool only_view; /* used for SHOW CREATE TABLE/VIEW */ @@ -926,14 +990,6 @@ typedef struct st_lex const char *stmt_definition_begin; /* - If non-0 then indicates that query requires prelocking and points to - next_global member of last own element in query table list (i.e. last - table which was not added to it as part of preparation to prelocking). - 0 - indicates that this query does not need prelocking. - */ - TABLE_LIST **query_tables_own_last; - - /* Pointers to part of LOAD DATA statement that should be rewritten during replication ("LOCAL 'filename' REPLACE INTO" part). */ @@ -945,7 +1001,7 @@ typedef struct st_lex virtual ~st_lex() { - hash_free(&sroutines); + destroy_query_tables_list(); } inline void uncacheable(uint8 cause) @@ -970,11 +1026,6 @@ typedef struct st_lex TABLE_LIST *unlink_first_table(bool *link_to_local); void link_first_table_back(TABLE_LIST *first, bool link_to_local); void first_lists_tables_same(); - inline void add_to_query_tables(TABLE_LIST *table) - { - *(table->prev_global= query_tables_last)= table; - query_tables_last= &table->next_global; - } bool add_time_zone_tables_to_query_tables(THD *thd); bool can_be_merged(); @@ -1006,28 +1057,7 @@ typedef struct st_lex return FALSE; } } - inline bool requires_prelocking() - { - return test(query_tables_own_last); - } - inline void mark_as_requiring_prelocking(TABLE_LIST **tables_own_last) - { - query_tables_own_last= tables_own_last; - } - /* Return pointer to first not-own table in query-tables or 0 */ - TABLE_LIST* first_not_own_table() - { - return ( query_tables_own_last ? *query_tables_own_last : 0); - } - void chop_off_not_own_tables() - { - if (query_tables_own_last) - { - *query_tables_own_last= 0; - query_tables_last= query_tables_own_last; - query_tables_own_last= 0; - } - } + void cleanup_after_one_table_open(); bool push_context(Name_resolution_context *context) @@ -1044,6 +1074,9 @@ typedef struct st_lex { return context_stack.head(); } + + void reset_n_backup_query_tables_list(Query_tables_list *backup); + void restore_backup_query_tables_list(Query_tables_list *backup); } LEX; struct st_lex_local: public st_lex diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 9018b364ec9..246da4dfeec 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2065,7 +2065,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) TABLE *table= tables->table; SELECT_LEX *select_lex= &lex->select_lex; SELECT_LEX *old_all_select_lex= lex->all_selects_list; - TABLE_LIST **save_query_tables_last= lex->query_tables_last; enum_sql_command save_sql_command= lex->sql_command; SELECT_LEX *lsel= tables->schema_select_lex; ST_SCHEMA_TABLE *schema_table= tables->schema_table; @@ -2084,6 +2083,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) db_type not_used; Open_tables_state open_tables_state_backup; bool save_view_prepare_mode= lex->view_prepare_mode; + Query_tables_list query_tables_list_backup; lex->view_prepare_mode= TRUE; DBUG_ENTER("get_all_tables"); @@ -2096,6 +2096,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) */ lex->sql_command= SQLCOM_SHOW_FIELDS; + lex->reset_n_backup_query_tables_list(&query_tables_list_backup); + /* We should not introduce deadlocks even if we already have some tables open and locked, since we won't lock tables which we will @@ -2136,8 +2138,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) show_table_list->db), show_table_list->alias)); thd->temporary_tables= 0; - close_thread_tables(thd); - show_table_list->table= 0; + close_tables_for_reopen(thd, &show_table_list); goto err; } @@ -2248,9 +2249,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) in this case. */ res= schema_table->process_table(thd, show_table_list, table, - res, base_name, - show_table_list->alias); - close_thread_tables(thd); + res, base_name, + show_table_list->alias); + close_tables_for_reopen(thd, &show_table_list); + DBUG_ASSERT(!lex->query_tables_own_last); if (res) goto err; } @@ -2267,11 +2269,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) error= 0; err: thd->restore_backup_open_tables_state(&open_tables_state_backup); + lex->restore_backup_query_tables_list(&query_tables_list_backup); lex->derived_tables= derived_tables; lex->all_selects_list= old_all_select_lex; - lex->query_tables_last= save_query_tables_last; lex->view_prepare_mode= save_view_prepare_mode; - *save_query_tables_last= 0; lex->sql_command= save_sql_command; DBUG_RETURN(error); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 476d5536581..9ec8e8db1fb 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2240,6 +2240,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, tables can be left opening */ close_thread_tables(thd); + lex->reset_query_tables_list(FALSE); if (protocol->write()) goto err; continue; @@ -2487,6 +2488,7 @@ send_result_message: } } close_thread_tables(thd); + lex->reset_query_tables_list(FALSE); table->table=0; // For query cache if (protocol->write()) goto err; |