diff options
author | unknown <sergefp@mysql.com> | 2005-07-30 08:19:57 +0000 |
---|---|---|
committer | unknown <sergefp@mysql.com> | 2005-07-30 08:19:57 +0000 |
commit | 11abe15eab3f444b600200e965cf18539af55392 (patch) | |
tree | c86ed0f51c03242ad2f553a26b62cff6613ac535 /sql/sp_head.cc | |
parent | 482cf550f9cb1bf060aba73ef64d85edee791118 (diff) | |
download | mariadb-git-11abe15eab3f444b600200e965cf18539af55392.tar.gz |
Added Non-prelocked SP execution: Now a PROCEDURE doesn't enter/leave prelocked mode for
its body, but lets each statement to get/release its own locks. This allows a broader set
of statements to be executed inside PROCEDUREs (but breaks replication)
This patch should fix BUG#8072, BUG#8766, BUG#9563, BUG#11126
mysql-test/r/sp-security.result:
Drop tables this test attempts to create
mysql-test/r/sp-threads.result:
Update test results
mysql-test/r/sp.result:
Disabled a test that triggers BUG#11986, cleanup used tables when tests start.
mysql-test/r/view.result:
Enabled a test case that now works with prelocking-free SPs
mysql-test/t/sp-security.test:
Drop tables this test attempts to create
mysql-test/t/sp.test:
Disabled a test that triggers BUG#11986, cleanup used tables when tests start.
mysql-test/t/view.test:
Enabled a test case that now works with prelocking-free SPs
sql/handler.cc:
Rename: thd->transaction.in_sub_stmt -> thd->in_sub_stmt
sql/item_func.cc:
Rename: thd->transaction.in_sub_stmt -> thd->in_sub_stmt
sql/sp.cc:
Non-prelocked SP execution: Added support for skipping prelocking of procedure body for
"CALL proc(...)" statements.
sql/sp.h:
Non-prelocked SP execution: Added support for skipping prelocking of procedure body for
"CALL proc(...)" statements.
sql/sp_cache.h:
Added comments
sql/sp_head.cc:
Non-prelocked SP execution:
* Try to unlock tables after PROCEDURE arguments have been evaluated.
* Make sp_lex_keeper be able to execute in 2 modes: A) when already in prelocked mode
B) when its statement enters/leaves prelocked mode itself.
sql/sp_head.h:
Non-prelocked SP execution: Make sp_lex_keeper to additionally keep list of tables it
needs to prelock when its statement enters/leaves prelocked mode on its own.
sql/sql_base.cc:
Non-prelocked SP execution: Make open_tables() to
* detect 'CALL proc(...)' and not to do prelocking for procedure body statements.
* Make lex->query_tables_last to point precisely to a boundary in lex->query_tables
list where 'own' tables and views' tables end and added-for-prelocking tables begin.
(it was not true before - view's tables could end up after query_tables_own_last)
sql/sql_class.cc:
Rename: thd->transaction.in_sub_stmt -> thd->in_sub_stmt
sql/sql_class.h:
Rename: thd->transaction.in_sub_stmt -> thd->in_sub_stmt
sql/sql_lex.cc:
Non-prelocked SP execution: More rigourous cleanup in st_lex::cleanup_after_one_table_open()
sql/sql_parse.cc:
Rename: thd->transaction.in_sub_stmt -> thd->in_sub_stmt, remove outdated comments
sql/sql_trigger.h:
Rename: thd->transaction.in_sub_stmt -> thd->in_sub_stmt
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r-- | sql/sp_head.cc | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 02c006d01ee..8d56e2a0b38 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -879,7 +879,10 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) octx= new sp_rcontext(csize, hmax, cmax); tmp_octx= TRUE; } + + /* Evaluate SP arguments (i.e. get the values passed as parameters) */ // QQ: Should do type checking? + DBUG_PRINT("info",(" %.*s: eval args", m_name.length, m_name.str)); for (i = 0 ; (it= li++) && i < params ; i++) { sp_pvar_t *pvar= m_pcont->find_pvar(i); @@ -916,6 +919,14 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) } } + /* + Okay, got values for all arguments. Close tables that might be used by + arguments evaluation. + */ + if (!thd->in_sub_stmt) + close_thread_tables(thd, 0, 0, 0); + + DBUG_PRINT("info",(" %.*s: eval args done", m_name.length, m_name.str)); // The rest of the frame are local variables which are all IN. // Default all variables to null (those with default clauses will // be set by an set instruction). @@ -1480,8 +1491,37 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, implemented at the same time as ability not to store LEX for instruction if it is not really used. */ - reinit_stmt_before_use(thd, m_lex); + bool collect_prelocking_tail= FALSE; + + if (thd->prelocked_mode == NON_PRELOCKED) + { + /* + This statement will enter/leave prelocked mode on its own. + Entering prelocked mode changes table list and related members + of LEX, so we'll need to restore them. + */ + if (lex_query_tables_own_last) + { + /* + We've already entered/left prelocked mode with this statement. + Attach the list of tables that need to be prelocked and mark m_lex + as having such list attached. + */ + *lex_query_tables_own_last= prelocking_tables; + m_lex->mark_as_requiring_prelocking(lex_query_tables_own_last); + } + else + { + /* + Let open_tables_calculate list of tables that this statement needs + to have prelocked. + */ + collect_prelocking_tail= TRUE; + } + } + + reinit_stmt_before_use(thd, m_lex); /* If requested check whenever we have access to tables in LEX's table list and open and lock them before executing instructtions core function. @@ -1499,6 +1539,35 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, thd->proc_info="closing tables"; close_thread_tables(thd); + if (thd->prelocked_mode == NON_PRELOCKED) + { + if (!lex_query_tables_own_last) + lex_query_tables_own_last= thd->lex->query_tables_own_last; + + if (lex_query_tables_own_last) + { + if (collect_prelocking_tail) + { + /* + This is the first time this statement has entered/left prelocked + mode on its own. open_tables() has calculated the set of tables this + statement needs to have prelocked and added them to the end of + m_lex->query_tables(->next_global)*. + Save this "tail" for subsequent calls (and restore original list + below) + */ + lex_query_tables_own_last= m_lex->query_tables_own_last; + prelocking_tables= *lex_query_tables_own_last; + } + /* + The table list now has list of tables that need to be prelocked + when this statement executes, chop it off, and mark this statement + as not requiring prelocking. + */ + *lex_query_tables_own_last= NULL; + m_lex->mark_as_requiring_prelocking(NULL); + } + } thd->rollback_item_tree_changes(); /* |