summaryrefslogtreecommitdiff
path: root/sql/sql_base.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r--sql/sql_base.cc43
1 files changed, 35 insertions, 8 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index b79748c18e2..5ff5e580f81 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -391,6 +391,8 @@ static void mark_used_tables_as_free_for_reuse(THD *thd, TABLE *table)
LOCK_open
skip_derived Set to 1 (0 = default) if we should not free derived
tables.
+ stopper When closing tables from thd->open_tables(->next)*,
+ don't close/remove tables starting from stopper.
IMPLEMENTATION
Unlocks tables and frees derived tables.
@@ -474,6 +476,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived,
We are in prelocked mode, so we have to leave it now with doing
implicit UNLOCK TABLES if need.
*/
+ DBUG_PRINT("info",("thd->prelocked_mode= NON_PRELOCKED"));
thd->prelocked_mode= NON_PRELOCKED;
if (prelocked_mode == PRELOCKED_UNDER_LOCK_TABLES)
@@ -1792,6 +1795,7 @@ err:
DBUG_RETURN(1);
}
+
/*
Open all tables in list
@@ -1843,10 +1847,6 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter)
statement for which table list for prelocking is already built, let
us cache routines and try to build such table list.
- NOTE: If we want queries with functions to work under explicit
- LOCK TABLES we have to additionaly lock mysql.proc table in it.
- At least until Monty will fix SP loading :)
-
NOTE: We can't delay prelocking until we will met some sub-statement
which really uses tables, since this will imply that we have to restore
its table list to be able execute it in some other context.
@@ -1860,16 +1860,23 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter)
mode we will have some locked tables, because queries which use only
derived/information schema tables and views possible. Thus "counter"
may be still zero for prelocked statement...
+
+ NOTE: The above notes may be out of date. Please wait for psergey to
+ document new prelocked behavior.
*/
- if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
- thd->lex->sroutines.records)
+
+ if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
+ thd->lex->sroutines_list.elements)
{
+ bool first_no_prelocking, need_prelocking;
TABLE_LIST **save_query_tables_last= thd->lex->query_tables_last;
DBUG_ASSERT(thd->lex->query_tables == *start);
+ sp_get_prelocking_info(thd, &need_prelocking, &first_no_prelocking);
- if (sp_cache_routines_and_add_tables(thd, thd->lex) ||
- *start)
+ if ((sp_cache_routines_and_add_tables(thd, thd->lex,
+ first_no_prelocking) ||
+ *start) && need_prelocking)
{
query_tables_last_own= save_query_tables_last;
*start= thd->lex->query_tables;
@@ -1891,14 +1898,32 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter)
DBUG_RETURN(-1);
}
(*counter)++;
+
if (!tables->table &&
!(tables->table= open_table(thd, tables, &new_frm_mem, &refresh, 0)))
{
free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC));
+
if (tables->view)
{
/* VIEW placeholder */
(*counter)--;
+
+ /*
+ tables->next_global list consists of two parts:
+ 1) Query tables and underlying tables of views.
+ 2) Tables used by all stored routines that this statement invokes on
+ execution.
+ We need to know where the bound between these two parts is. If we've
+ just opened a view, which was the last table in part #1, and it
+ has added its base tables after itself, adjust the boundary pointer
+ accordingly.
+ */
+ if (query_tables_last_own &&
+ 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.
@@ -2323,6 +2348,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count)
and was marked as occupied during open_tables() as free for reuse.
*/
mark_real_tables_as_free_for_reuse(first_not_own);
+ DBUG_PRINT("info",("prelocked_mode= PRELOCKED"));
thd->prelocked_mode= PRELOCKED;
}
}
@@ -2346,6 +2372,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count)
if (thd->lex->requires_prelocking())
{
mark_real_tables_as_free_for_reuse(first_not_own);
+ DBUG_PRINT("info", ("thd->prelocked_mode= PRELOCKED_UNDER_LOCK_TABLES"));
thd->prelocked_mode= PRELOCKED_UNDER_LOCK_TABLES;
}
}