Below is the list of changes that have just been committed into a local
5.0 repository of dlenev. When dlenev does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.1963 05/09/15 03:57:59 dlenev@stripped +8 -0
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/home/dlenev/src/mysql-5.0-bg12704-2
sql/sql_update.cc
1.170 05/09/15 03:57:52 dlenev@stripped +0 -0
Auto merged
sql/sql_table.cc
1.273 05/09/15 03:57:52 dlenev@stripped +0 -0
Auto merged
sql/sql_prepare.cc
1.154 05/09/15 03:57:52 dlenev@stripped +0 -0
Auto merged
sql/sql_lex.h
1.197 05/09/15 03:57:52 dlenev@stripped +0 -0
Auto merged
sql/sql_base.cc
1.301 05/09/15 03:57:52 dlenev@stripped +0 -0
Auto merged
sql/sp_head.cc
1.184 05/09/15 03:57:52 dlenev@stripped +0 -0
Auto merged
sql/sp.cc
1.94 05/09/15 03:57:51 dlenev@stripped +0 -0
Auto merged
sql/mysql_priv.h
1.351 05/09/15 03:57:51 dlenev@stripped +0 -0
Auto merged
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: dlenev
# Host: brandersnatch.localdomain
# Root: /home/dlenev/src/mysql-5.0-bg12704-2/RESYNC
--- 1.350/sql/mysql_priv.h 2005-09-14 13:26:01 +04:00
+++ 1.351/sql/mysql_priv.h 2005-09-15 03:57:51 +04:00
@@ -952,7 +952,7 @@
int simple_open_n_lock_tables(THD *thd,TABLE_LIST *tables);
bool open_and_lock_tables(THD *thd,TABLE_LIST *tables);
bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags);
-int lock_tables(THD *thd, TABLE_LIST *tables, uint counter);
+int lock_tables(THD *thd, TABLE_LIST *tables, uint counter, bool *need_reopen);
TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
const char *table_name, bool link_in_list);
bool rm_temporary_table(enum db_type base, char *path);
@@ -960,6 +960,7 @@
void intern_close_table(TABLE *entry);
bool close_thread_table(THD *thd, TABLE **table_ptr);
void close_temporary_tables(THD *thd);
+void close_tables_for_reopen(THD *thd, TABLE_LIST *tables);
TABLE_LIST *find_table_in_list(TABLE_LIST *table,
uint offset_to_list,
const char *db_name,
@@ -1238,10 +1239,12 @@
extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd;
#endif /* HAVE_OPENSSL */
-MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count, uint flags);
+MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count,
+ uint flags, bool *need_reopen);
/* mysql_lock_tables() flags bits */
#define MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK 0x0001
#define MYSQL_LOCK_IGNORE_FLUSH 0x0002
+#define MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN 0x0004
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
--- 1.300/sql/sql_base.cc 2005-09-13 22:21:36 +04:00
+++ 1.301/sql/sql_base.cc 2005-09-15 03:57:52 +04:00
@@ -1399,7 +1399,6 @@
tmp.status= table->status;
tmp.keys_in_use_for_query= tmp.s->keys_in_use;
tmp.used_keys= tmp.s->keys_for_keyread;
- tmp.force_index= tmp.force_index;
/* Get state */
tmp.s->key_length= table->s->key_length;
@@ -1430,6 +1429,9 @@
for (key=0 ; key < table->s->keys ; key++)
for (part=0 ; part < table->key_info[key].usable_key_parts ; part++)
table->key_info[key].key_part[part].field->table= table;
+ if (table->triggers)
+ table->triggers->set_table(table);
+
VOID(pthread_cond_broadcast(&COND_refresh));
error=0;
@@ -1478,7 +1480,7 @@
TABLE *table,*next,**prev;
TABLE **tables,**tables_ptr; // For locks
- bool error=0;
+ bool error=0, not_used;
if (get_locks)
{
/* The ptr is checked later */
@@ -1519,7 +1521,8 @@
MYSQL_LOCK *lock;
/* We should always get these locks */
thd->some_tables_deleted=0;
- if ((lock= mysql_lock_tables(thd, tables, (uint) (tables_ptr - tables), 0)))
+ if ((lock= mysql_lock_tables(thd, tables, (uint) (tables_ptr - tables),
+ 0, ¬_used)))
{
thd->locked_tables=mysql_lock_merge(thd->locked_tables,lock);
}
@@ -1969,9 +1972,15 @@
/*
Ignore placeholders for derived tables. After derived tables
processing, link to created temporary table will be put here.
+ If this is derived table for view then we still want to process
+ routines used by this view.
*/
if (tables->derived)
+ {
+ if (tables->view)
+ goto process_view_routines;
continue;
+ }
if (tables->schema_table)
{
if (!mysql_schema_table(thd, thd->lex, tables))
@@ -2003,23 +2012,12 @@
if (query_tables_last_own == &(tables->next_global) &&
tables->view->query_tables)
query_tables_last_own= tables->view->query_tables_last;
-
/*
- Again if needed we have to get cache all routines used by this view
- and add tables used by them to table list.
+ Let us free memory used by 'sroutines' hash here since we never
+ call destructor for this LEX.
*/
- if (!thd->prelocked_mode && !thd->lex->requires_prelocking()
&&
- tables->view->sroutines.records)
- {
- /* We have at least one table in TL here */
- if (!query_tables_last_own)
- query_tables_last_own= thd->lex->query_tables_last;
- sp_cache_routines_and_add_tables_for_view(thd, thd->lex,
- tables->view);
- }
- /* Cleanup hashes because destructo for this LEX is never called */
hash_free(&tables->view->sroutines);
- continue;
+ goto process_view_routines;
}
if (refresh) // Refresh in progress
@@ -2031,11 +2029,6 @@
thd->version=refresh_version;
TABLE **prev_table= &thd->open_tables;
bool found=0;
- /*
- QQ: What we should do if we have started building of table list
- for prelocking ??? Probably throw it away ? But before we should
- mark all temporary tables as free? How about locked ?
- */
for (TABLE_LIST *tmp= *start; tmp; tmp= tmp->next_global)
{
/* Close normal (not temporary) changed tables */
@@ -2059,6 +2052,18 @@
pthread_mutex_unlock(&LOCK_open);
if (found)
VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
+ /*
+ Let us prepare for recalculation of set of prelocked tables.
+ First we pretend that we have finished calculation which we
+ were doing currently. Then we restore list of tables to be
+ opened and set of used routines to the state in which they were
+ before first open_tables() call for this statement (i.e. before
+ we have calculated current set of tables for prelocking).
+ */
+ if (query_tables_last_own)
+ thd->lex->mark_as_requiring_prelocking(query_tables_last_own);
+ thd->lex->chop_off_not_own_tables();
+ sp_remove_not_own_routines(thd->lex);
goto restart;
}
result= -1; // Fatal error
@@ -2089,6 +2094,21 @@
if (tables->lock_type != TL_UNLOCK && ! thd->locked_tables)
tables->table->reginfo.lock_type=tables->lock_type;
tables->table->grant= tables->grant;
+
+process_view_routines:
+ /*
+ Again we may need cache all routines used by this view and add
+ tables used by them to table list.
+ */
+ if (tables->view && !thd->prelocked_mode &&
+ !thd->lex->requires_prelocking() &&
+ tables->view->sroutines_list.elements)
+ {
+ /* We have at least one table in TL here. */
+ if (!query_tables_last_own)
+ query_tables_last_own= thd->lex->query_tables_last;
+ sp_cache_routines_and_add_tables_for_view(thd, thd->lex, tables->view);
+ }
}
thd->proc_info=0;
free_root(&new_frm_mem, MYF(0)); // Free pre-alloced block
@@ -2193,7 +2213,8 @@
{
DBUG_ASSERT(thd->lock == 0); // You must lock everything at once
if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
- if (! (thd->lock= mysql_lock_tables(thd, &table_list->table, 1, 0)))
+ if (! (thd->lock= mysql_lock_tables(thd, &table_list->table, 1, 0,
+ &refresh)))
table= 0;
}
}
@@ -2221,11 +2242,20 @@
int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables)
{
- DBUG_ENTER("simple_open_n_lock_tables");
uint counter;
- if (open_tables(thd, &tables, &counter, 0) ||
- lock_tables(thd, tables, counter))
- DBUG_RETURN(-1); /* purecov: inspected */
+ bool need_reopen;
+ DBUG_ENTER("simple_open_n_lock_tables");
+
+ for ( ; ; )
+ {
+ if (open_tables(thd, &tables, &counter, 0))
+ DBUG_RETURN(-1);
+ if (!lock_tables(thd, tables, counter, &need_reopen))
+ break;
+ if (!need_reopen)
+ DBUG_RETURN(-1);
+ close_tables_for_reopen(thd, tables);
+ }
DBUG_RETURN(0);
}
@@ -2250,10 +2280,20 @@
bool open_and_lock_tables(THD *thd, TABLE_LIST *tables)
{
uint counter;
+ bool need_reopen;
DBUG_ENTER("open_and_lock_tables");
- if (open_tables(thd, &tables, &counter, 0) ||
- lock_tables(thd, tables, counter) ||
- mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
+
+ for ( ; ; )
+ {
+ if (open_tables(thd, &tables, &counter, 0))
+ DBUG_RETURN(-1);
+ if (!lock_tables(thd, tables, counter, &need_reopen))
+ break;
+ if (!need_reopen)
+ DBUG_RETURN(-1);
+ close_tables_for_reopen(thd, tables);
+ }
+ if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
(thd->fill_derived_tables() &&
mysql_handle_derived(thd->lex, &mysql_derived_filling)))
DBUG_RETURN(TRUE); /* purecov: inspected */
@@ -2321,7 +2361,12 @@
lock_tables()
thd Thread handler
tables Tables to lock
- count umber of opened tables
+ count Number of opened tables
+ need_reopen Out parameter which if TRUE indicates that some
+ tables were dropped or altered during this call
+ and therefore invoker should reopen tables and
+ try to lock them once again (in this case
+ lock_tables() will also return error).
NOTES
You can't call lock_tables twice, as this would break the dead-lock-free
@@ -2337,7 +2382,7 @@
-1 Error
*/
-int lock_tables(THD *thd, TABLE_LIST *tables, uint count)
+int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
{
TABLE_LIST *table;
@@ -2353,6 +2398,8 @@
*/
DBUG_ASSERT(!thd->lex->requires_prelocking() || tables);
+ *need_reopen= FALSE;
+
if (!tables)
DBUG_RETURN(0);
@@ -2385,7 +2432,9 @@
thd->options|= OPTION_TABLE_LOCK;
}
- if (! (thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start), 0)))
+ if (! (thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start),
+ MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN,
+ need_reopen)))
{
if (thd->lex->requires_prelocking())
{
@@ -2461,6 +2510,28 @@
}
}
DBUG_RETURN(0);
+}
+
+
+/*
+ Prepare statement for reopening of tables and recalculation of set of
+ prelocked tables.
+
+ SYNOPSIS
+ close_tables_for_reopen()
+ thd Thread context
+ tables List of tables which we were trying to open and lock
+
+*/
+
+void close_tables_for_reopen(THD *thd, TABLE_LIST *tables)
+{
+ thd->lex->chop_off_not_own_tables();
+ sp_remove_not_own_routines(thd->lex);
+ for (TABLE_LIST *tmp= tables; tmp; tmp= tmp->next_global)
+ if (tmp->table && !tmp->table->s->tmp_table)
+ tmp->table= 0;
+ close_thread_tables(thd);
}
--- 1.196/sql/sql_lex.h 2005-09-14 11:53:03 +04:00
+++ 1.197/sql/sql_lex.h 2005-09-15 03:57:52 +04:00
@@ -845,8 +845,15 @@
/*
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 */
@@ -961,6 +968,15 @@
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();
--- 1.272/sql/sql_table.cc 2005-09-14 02:44:02 +04:00
+++ 1.273/sql/sql_table.cc 2005-09-15 03:57:52 +04:00
@@ -1709,6 +1709,7 @@
List_iterator_fast<Item> it(*items);
Item *item;
Field *tmp_field;
+ bool not_used;
DBUG_ENTER("create_table_from_items");
tmp_table.alias= 0;
@@ -1767,8 +1768,15 @@
DBUG_RETURN(0);
}
+ /*
+ FIXME: What happens if trigger manages to be created while we are
+ obtaining this lock ? May be it is sensible just to disable
+ trigger execution in this case ? Or will MYSQL_LOCK_IGNORE_FLUSH
+ save us from that ?
+ */
table->reginfo.lock_type=TL_WRITE;
- if (! ((*lock)= mysql_lock_tables(thd, &table, 1, MYSQL_LOCK_IGNORE_FLUSH)))
+ if (! ((*lock)= mysql_lock_tables(thd, &table, 1,
+ MYSQL_LOCK_IGNORE_FLUSH, ¬_used)))
{
VOID(pthread_mutex_lock(&LOCK_open));
hash_delete(&open_cache,(byte*) table);
--- 1.169/sql/sql_update.cc 2005-09-13 15:06:27 +04:00
+++ 1.170/sql/sql_update.cc 2005-09-15 03:57:52 +04:00
@@ -134,25 +134,33 @@
SQL_SELECT *select;
READ_RECORD info;
SELECT_LEX *select_lex= &thd->lex->select_lex;
+ bool need_reopen;
DBUG_ENTER("mysql_update");
LINT_INIT(timestamp_query_id);
- if (open_tables(thd, &table_list, &table_count, 0))
- DBUG_RETURN(1);
-
- if (table_list->multitable_view)
+ for ( ; ; )
{
- DBUG_ASSERT(table_list->view != 0);
- DBUG_PRINT("info", ("Switch to multi-update"));
- /* pass counter value */
- thd->lex->table_count= table_count;
- /* convert to multiupdate */
- return 2;
+ if (open_tables(thd, &table_list, &table_count, 0))
+ DBUG_RETURN(1);
+
+ if (table_list->multitable_view)
+ {
+ DBUG_ASSERT(table_list->view != 0);
+ DBUG_PRINT("info", ("Switch to multi-update"));
+ /* pass counter value */
+ thd->lex->table_count= table_count;
+ /* convert to multiupdate */
+ DBUG_RETURN(2);
+ }
+ if (!lock_tables(thd, table_list, table_count, &need_reopen))
+ break;
+ if (!need_reopen)
+ DBUG_RETURN(1);
+ close_tables_for_reopen(thd, table_list);
}
- if (lock_tables(thd, table_list, table_count) ||
- mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
+ if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
(thd->fill_derived_tables() &&
mysql_handle_derived(thd->lex, &mysql_derived_filling)))
DBUG_RETURN(1);
@@ -616,7 +624,6 @@
bool mysql_multi_update_prepare(THD *thd)
{
LEX *lex= thd->lex;
- ulong opened_tables;
TABLE_LIST *table_list= lex->query_tables;
TABLE_LIST *tl, *leaves;
List<Item> *fields= &lex->select_lex.item_list;
@@ -630,13 +637,16 @@
uint table_count= lex->table_count;
const bool using_lock_tables= thd->locked_tables != 0;
bool original_multiupdate= (thd->lex->sql_command == SQLCOM_UPDATE_MULTI);
+ bool need_reopen= FALSE;
DBUG_ENTER("mysql_multi_update_prepare");
/* following need for prepared statements, to run next time multi-update */
thd->lex->sql_command= SQLCOM_UPDATE_MULTI;
+reopen_tables:
+
/* open tables and create derived ones, but do not lock and fill them */
- if ((original_multiupdate &&
+ if (((original_multiupdate || need_reopen) &&
open_tables(thd, &table_list, &table_count, 0)) ||
mysql_handle_derived(lex, &mysql_derived_prepare))
DBUG_RETURN(TRUE);
@@ -742,20 +752,17 @@
}
}
- opened_tables= thd->status_var.opened_tables;
/* now lock and fill tables */
- if (lock_tables(thd, table_list, table_count))
- DBUG_RETURN(TRUE);
-
- /*
- we have to re-call fixfields for fixed items, because lock maybe
- reopened tables
- */
- if (opened_tables != thd->status_var.opened_tables)
+ if (lock_tables(thd, table_list, table_count, &need_reopen))
{
+ if (!need_reopen)
+ DBUG_RETURN(TRUE);
+
/*
- Fields items cleanup(). There are only Item_fields in the list, so we
- do not do Item tree walking
+ We have to reopen tables since some of them were altered or dropped
+ during lock_tables() or something was done with their triggers.
+ Let us do some cleanups to be able do setup_table() and setup_fields()
+ once again.
*/
List_iterator_fast<Item> it(*fields);
Item *item;
@@ -766,12 +773,8 @@
for (TABLE_LIST *tbl= table_list; tbl; tbl= tbl->next_global)
tbl->cleanup_items();
- if (setup_tables(thd, &lex->select_lex.context,
- &lex->select_lex.top_join_list,
- table_list, &lex->select_lex.where,
- &lex->select_lex.leaf_tables, FALSE) ||
- setup_fields_with_no_wrap(thd, 0, *fields, 1, 0, 0))
- DBUG_RETURN(TRUE);
+ close_tables_for_reopen(thd, table_list);
+ goto reopen_tables;
}
/*
--- 1.93/sql/sp.cc 2005-09-14 02:41:38 +04:00
+++ 1.94/sql/sp.cc 2005-09-15 03:57:51 +04:00
@@ -107,7 +107,7 @@
{
TABLE_LIST tables;
TABLE *table;
- bool refresh;
+ bool not_used;
DBUG_ENTER("open_proc_table");
/*
@@ -122,7 +122,7 @@
bzero((char*) &tables, sizeof(tables));
tables.db= (char*) "mysql";
tables.table_name= tables.alias= (char*)"proc";
- if (!(table= open_table(thd, &tables, thd->mem_root, &refresh,
+ if (!(table= open_table(thd, &tables, thd->mem_root, ¬_used,
MYSQL_LOCK_IGNORE_FLUSH)))
{
thd->restore_backup_open_tables_state(backup);
@@ -138,7 +138,7 @@
could lead to a deadlock if we have other tables opened.
*/
if (!(thd->lock= mysql_lock_tables(thd, &table, 1,
- MYSQL_LOCK_IGNORE_FLUSH)))
+ MYSQL_LOCK_IGNORE_FLUSH, ¬_used)))
{
close_proc_table(thd, backup);
DBUG_RETURN(0);
@@ -1265,7 +1265,8 @@
/*
- Add routine to the set of stored routines used by statement.
+ Add routine which is explicitly used by statement to the set of stored
+ routines used by this statement.
SYNOPSIS
sp_add_used_routine()
@@ -1276,7 +1277,8 @@
rt_type - routine type (one of TYPE_ENUM_PROCEDURE/...)
NOTES
- Will also add element to end of 'LEX::sroutines_list' list.
+ Will also add element to end of 'LEX::sroutines_list' list (and will
+ take into account that this is explicitly used routine).
To be friendly towards prepared statements one should pass
persistent arena as second argument.
@@ -1287,6 +1289,37 @@
{
rt->set_routine_type(rt_type);
(void)add_used_routine(lex, arena, &rt->m_sroutines_key);
+ lex->sroutines_list_own_last= lex->sroutines_list.next;
+ lex->sroutines_list_own_elements= lex->sroutines_list.elements;
+}
+
+
+/*
+ Remove routines which are only indirectly used by statement from
+ the set of routines used by this statement.
+
+ SYNOPSIS
+ sp_remove_not_own_routines()
+ lex LEX representing statement
+*/
+
+void sp_remove_not_own_routines(LEX *lex)
+{
+ Sroutine_hash_entry *not_own_rt, *next_rt;
+ for (not_own_rt= *(Sroutine_hash_entry **)lex->sroutines_list_own_last;
+ not_own_rt; not_own_rt= next_rt)
+ {
+ /*
+ It is safe to obtain not_own_rt->next after calling hash_delete() now
+ but we want to be more future-proof.
+ */
+ next_rt= not_own_rt->next;
+ hash_delete(&lex->sroutines, (byte *)not_own_rt);
+ }
+
+ *(Sroutine_hash_entry **)lex->sroutines_list_own_last= NULL;
+ lex->sroutines_list.next= lex->sroutines_list_own_last;
+ lex->sroutines_list.elements= lex->sroutines_list_own_elements;
}
@@ -1344,6 +1377,28 @@
/*
+ Add contents of list representing set of routines to the set of
+ routines used by statement.
+
+ SYNOPSIS
+ sp_update_stmt_used_routines()
+ thd Thread context
+ lex LEX representing statement
+ src List representing set from which routines will be added
+
+ NOTE
+ It will also add elements to end of 'LEX::sroutines_list' list.
+*/
+
+static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src)
+{
+ for (Sroutine_hash_entry *rt= (Sroutine_hash_entry *)src->first;
+ rt; rt= rt->next)
+ (void)add_used_routine(lex, thd->stmt_arena, &rt->key);
+}
+
+
+/*
Cache sub-set of routines used by statement, add tables used by these
routines to statement table list. Do the same for all routines used
by these routines.
@@ -1463,7 +1518,7 @@
{
Sroutine_hash_entry **last_cached_routine_ptr=
(Sroutine_hash_entry **)lex->sroutines_list.next;
- sp_update_stmt_used_routines(thd, lex, &aux_lex->sroutines);
+ sp_update_stmt_used_routines(thd, lex, &aux_lex->sroutines_list);
(void)sp_cache_routines_and_add_tables_aux(thd, lex,
*last_cached_routine_ptr, FALSE);
}
--- 1.183/sql/sp_head.cc 2005-09-13 14:50:11 +04:00
+++ 1.184/sql/sp_head.cc 2005-09-15 03:57:52 +04:00
@@ -1909,10 +1909,6 @@
attached it above in this function).
Now we'll save the 'tail', and detach it.
*/
- DBUG_ASSERT(!lex_query_tables_own_last ||
- lex_query_tables_own_last == m_lex->query_tables_own_last &&
- prelocking_tables == *(m_lex->query_tables_own_last));
-
lex_query_tables_own_last= m_lex->query_tables_own_last;
prelocking_tables= *lex_query_tables_own_last;
*lex_query_tables_own_last= NULL;
--- 1.153/sql/sql_prepare.cc 2005-09-14 11:11:11 +04:00
+++ 1.154/sql/sql_prepare.cc 2005-09-15 03:57:52 +04:00
@@ -1103,30 +1103,39 @@
#ifndef NO_EMBEDDED_ACCESS_CHECKS
uint want_privilege;
#endif
+ bool need_reopen;
DBUG_ENTER("mysql_test_update");
if (update_precheck(thd, table_list))
goto error;
- if (open_tables(thd, &table_list, &table_count, 0))
- goto error;
-
- if (table_list->multitable_view)
+ for ( ; ; )
{
- DBUG_ASSERT(table_list->view != 0);
- DBUG_PRINT("info", ("Switch to multi-update"));
- /* pass counter value */
- thd->lex->table_count= table_count;
- /* convert to multiupdate */
- DBUG_RETURN(2);
+ if (open_tables(thd, &table_list, &table_count, 0))
+ goto error;
+
+ if (table_list->multitable_view)
+ {
+ DBUG_ASSERT(table_list->view != 0);
+ DBUG_PRINT("info", ("Switch to multi-update"));
+ /* pass counter value */
+ thd->lex->table_count= table_count;
+ /* convert to multiupdate */
+ DBUG_RETURN(2);
+ }
+
+ if (!lock_tables(thd, table_list, table_count, &need_reopen))
+ break;
+ if (!need_reopen)
+ goto error;
+ close_tables_for_reopen(thd, table_list);
}
/*
thd->fill_derived_tables() is false here for sure (because it is
preparation of PS, so we even do not check it).
*/
- if (lock_tables(thd, table_list, table_count) ||
- mysql_handle_derived(thd->lex, &mysql_derived_prepare))
+ if (mysql_handle_derived(thd->lex, &mysql_derived_prepare))
goto error;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
| Thread |
|---|
| • bk commit into 5.0 tree (dlenev:1.1963) | dlenev | 15 Sep |