summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorbell@sanja.is.com.ua <>2005-07-05 13:39:20 +0300
committerbell@sanja.is.com.ua <>2005-07-05 13:39:20 +0300
commit5eb8404c57b15e7be5f47b3e2e365d27bab57993 (patch)
tree8e7f0ec25ca929fa336d5a214d73fee0974f0ccc /sql
parentbfbd0e241b8ece9f212310116a69af20692790a0 (diff)
parentcee0f3f60823ab82ce6ae8981f6deeb776884eb7 (diff)
downloadmariadb-git-5eb8404c57b15e7be5f47b3e2e365d27bab57993.tar.gz
Merge sanja.is.com.ua:/home/bell/mysql/bk/work-bug5-5.0
into sanja.is.com.ua:/home/bell/mysql/bk/work-bug4-5.0
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_lex.cc39
-rw-r--r--sql/sql_lex.h11
-rw-r--r--sql/sql_table.cc36
3 files changed, 73 insertions, 13 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 08f0c3badf7..1067ce0f6e2 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1916,6 +1916,45 @@ void st_lex::link_first_table_back(TABLE_LIST *first,
}
+
+/*
+ cleanup lex for case when we open table by table for processing
+
+ SYNOPSIS
+ st_lex::cleanup_after_one_table_open()
+*/
+
+void st_lex::cleanup_after_one_table_open()
+{
+ /*
+ thd->lex->derived_tables & additional units may be set if we open
+ a view. It is necessary to clear thd->lex->derived_tables flag
+ to prevent processing of derived tables during next open_and_lock_tables
+ if next table is a real table and cleanup & remove underlying units
+ NOTE: all units will be connected to thd->lex->select_lex, because we
+ have not UNION on most upper level.
+ */
+ if (all_selects_list != &select_lex)
+ {
+ derived_tables= 0;
+ /* cleunup underlying units (units of VIEW) */
+ for (SELECT_LEX_UNIT *un= select_lex.first_inner_unit();
+ un;
+ un= un->next_unit())
+ un->cleanup();
+ /* reduce all selects list to default state */
+ all_selects_list= &select_lex;
+ /* remove underlying units (units of VIEW) subtree */
+ select_lex.cut_subtree();
+ }
+ time_zone_tables_used= 0;
+ if (spfuns.records)
+ my_hash_reset(&spfuns);
+ if (spprocs.records)
+ my_hash_reset(&spprocs);
+}
+
+
/*
fix some structures at the end of preparation
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index a9bfb6da926..ffe3a5ba833 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -371,7 +371,6 @@ typedef class st_select_lex_node SELECT_LEX_NODE;
SELECT_LEX_UNIT - unit of selects (UNION, INTERSECT, ...) group
SELECT_LEXs
*/
-struct st_lex;
class THD;
class select_result;
class JOIN;
@@ -627,7 +626,13 @@ public:
order_list.first= 0;
order_list.next= (byte**) &order_list.first;
}
-
+ /*
+ This method created for reiniting LEX in mysql_admin_table() and can be
+ used only if you are going remove all SELECT_LEX & units except belonger
+ to LEX (LEX::unit & LEX::select, for other purposes there are
+ SELECT_LEX_UNIT::exclude_level & SELECT_LEX_UNIT::exclude_tree
+ */
+ void cut_subtree() { slave= 0; }
bool test_limit();
friend void lex_start(THD *thd, uchar *buf, uint length);
@@ -912,7 +917,7 @@ typedef struct st_lex
{
return ( query_tables_own_last ? *query_tables_own_last : 0);
}
-
+ void cleanup_after_one_table_open();
} LEX;
struct st_lex_local: public st_lex
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 121a89555ce..4f8c14a666e 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2103,6 +2103,7 @@ end:
}
+
/*
RETURN VALUES
FALSE Message sent to net (admin operation went ok)
@@ -2122,10 +2123,12 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
HA_CHECK_OPT *),
int (view_operator_func)(THD *, TABLE_LIST*))
{
- TABLE_LIST *table, *next_global_table;
+ TABLE_LIST *table, *save_next_global, *save_next_local;
+ SELECT_LEX *select= &thd->lex->select_lex;
List<Item> field_list;
Item *item;
Protocol *protocol= thd->protocol;
+ LEX *lex= thd->lex;
int result_code;
DBUG_ENTER("mysql_admin_table");
@@ -2152,12 +2155,25 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
thd->open_options|= extra_open_options;
table->lock_type= lock_type;
/* open only one table from local list of command */
- next_global_table= table->next_global;
+ save_next_global= table->next_global;
table->next_global= 0;
+ save_next_local= table->next_local;
+ table->next_local= 0;
+ select->table_list.first= (byte*)table;
+ /*
+ Time zone tables and SP tables can be add to lex->query_tables list,
+ so it have to be prepared.
+ TODO: Investigate if we can put extra tables into argument instead of
+ using lex->query_tables
+ */
+ lex->query_tables= table;
+ lex->query_tables_last= &table->next_global;
+ lex->query_tables_own_last= 0;;
thd->no_warnings_for_error= no_warnings_for_error;
open_and_lock_tables(thd, table);
thd->no_warnings_for_error= 0;
- table->next_global= next_global_table;
+ table->next_global= save_next_global;
+ table->next_local= save_next_local;
/* if view are unsupported */
if (table->view && view_operator_func == NULL)
{
@@ -2205,7 +2221,13 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
err_msg= (const char *)buf;
}
protocol->store(err_msg, system_charset_info);
+ lex->cleanup_after_one_table_open();
thd->clear_error();
+ /*
+ View opening can be interrupted in the middle of process so some
+ tables can be left opening
+ */
+ close_thread_tables(thd);
if (protocol->write())
goto err;
continue;
@@ -2274,6 +2296,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
send_result:
+ lex->cleanup_after_one_table_open();
thd->clear_error(); // these errors shouldn't get client
protocol->prepare_for_resend();
protocol->store(table_name, system_charset_info);
@@ -2401,13 +2424,6 @@ send_result_message:
}
close_thread_tables(thd);
table->table=0; // For query cache
- /*
- thd->lex->derived_tables may be set to non zero value if we open
- a view. It is necessary to clear thd->lex->derived_tables flag
- to prevent processing of derived tables during next open_and_lock_tables
- if next table is a real table.
- */
- thd->lex->derived_tables= 0;
if (protocol->write())
goto err;
}