summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <pekka@mysql.com>2006-05-30 22:54:06 +0200
committerunknown <pekka@mysql.com>2006-05-30 22:54:06 +0200
commitf90f2c58d3bf366d28d76b63399e21e12c0b12cb (patch)
tree9463ea754946d7d52715828c856838a7e6f9d8c7
parent63da222ae0f484ed11bf3dad6f1f54dc4ae46096 (diff)
parent8a5ca696ec572c7583ab5f73a726ce04fe72c413 (diff)
downloadmariadb-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.cc17
-rw-r--r--mysql-test/r/information_schema_db.result57
-rw-r--r--mysql-test/t/information_schema_db.test60
-rw-r--r--mysql-test/t/rpl_insert_id.test2
-rw-r--r--server-tools/instance-manager/guardian.cc22
-rw-r--r--server-tools/instance-manager/manager.cc46
-rw-r--r--sql/sql_lex.cc108
-rw-r--r--sql/sql_lex.h151
-rw-r--r--sql/sql_show.cc17
-rw-r--r--sql/sql_table.cc2
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;