mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Fix for sp.test failure in --ps-protocol mode (2nd attempt).
Now we should call open_and_lock_tables() even if table list is empty - to cache stored routines used by query and open and lock tables required for their execution.
This commit is contained in:
@ -217,9 +217,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
}
|
}
|
||||||
if ((table= delayed_get_table(thd,table_list)) && !thd->is_fatal_error)
|
if ((table= delayed_get_table(thd,table_list)) && !thd->is_fatal_error)
|
||||||
{
|
{
|
||||||
res= 0;
|
/*
|
||||||
if (table_list->next_global) /* if sub select */
|
Open tables used for sub-selects or in stored functions, will also
|
||||||
res= open_and_lock_tables(thd, table_list->next_global);
|
cache these functions.
|
||||||
|
*/
|
||||||
|
res= open_and_lock_tables(thd, table_list->next_global);
|
||||||
/*
|
/*
|
||||||
First is not processed by open_and_lock_tables() => we need set
|
First is not processed by open_and_lock_tables() => we need set
|
||||||
updateability flags "by hands".
|
updateability flags "by hands".
|
||||||
|
@ -1230,7 +1230,7 @@ static bool mysql_test_do_fields(Prepared_statement *stmt,
|
|||||||
if (tables && check_table_access(thd, SELECT_ACL, tables, 0))
|
if (tables && check_table_access(thd, SELECT_ACL, tables, 0))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
if (tables && open_and_lock_tables(thd, tables))
|
if (open_and_lock_tables(thd, tables))
|
||||||
{
|
{
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
@ -1261,12 +1261,12 @@ static bool mysql_test_set_fields(Prepared_statement *stmt,
|
|||||||
List_iterator_fast<set_var_base> it(*var_list);
|
List_iterator_fast<set_var_base> it(*var_list);
|
||||||
THD *thd= stmt->thd;
|
THD *thd= stmt->thd;
|
||||||
set_var_base *var;
|
set_var_base *var;
|
||||||
bool res= 0;
|
bool res;
|
||||||
|
|
||||||
if (tables && check_table_access(thd, SELECT_ACL, tables, 0))
|
if (tables && check_table_access(thd, SELECT_ACL, tables, 0))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
if (tables && (res= open_and_lock_tables(thd, tables)))
|
if ((res= open_and_lock_tables(thd, tables)))
|
||||||
goto error;
|
goto error;
|
||||||
while ((var= it++))
|
while ((var= it++))
|
||||||
{
|
{
|
||||||
@ -1287,30 +1287,30 @@ error:
|
|||||||
Check internal SELECT of the prepared command
|
Check internal SELECT of the prepared command
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
select_like_statement_test()
|
select_like_stmt_test()
|
||||||
stmt - prepared table handler
|
stmt - prepared statement handler
|
||||||
tables - global list of tables
|
specific_prepare - function of command specific prepare
|
||||||
specific_prepare - function of command specific prepare
|
setup_tables_done_option - options to be passed to LEX::unit.prepare()
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
This function won't directly open tables used in select. They should
|
||||||
|
be opened either by calling function (and in this case you probably
|
||||||
|
should use select_like_stmt_test_with_open_n_lock()) or by
|
||||||
|
"specific_prepare" call (like this happens in case of multi-update).
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
FALSE success
|
FALSE success
|
||||||
TRUE error
|
TRUE error
|
||||||
*/
|
*/
|
||||||
static bool select_like_statement_test(Prepared_statement *stmt,
|
|
||||||
TABLE_LIST *tables,
|
static bool select_like_stmt_test(Prepared_statement *stmt,
|
||||||
bool (*specific_prepare)(THD *thd),
|
bool (*specific_prepare)(THD *thd),
|
||||||
ulong setup_tables_done_option)
|
ulong setup_tables_done_option)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("select_like_statement_test");
|
DBUG_ENTER("select_like_stmt_test");
|
||||||
THD *thd= stmt->thd;
|
THD *thd= stmt->thd;
|
||||||
LEX *lex= stmt->lex;
|
LEX *lex= stmt->lex;
|
||||||
bool res= 0;
|
bool res= FALSE;
|
||||||
|
|
||||||
/* check that tables was not opened during conversion from usual update */
|
|
||||||
if (tables &&
|
|
||||||
(!tables->table && !tables->view) &&
|
|
||||||
(res= open_and_lock_tables(thd, tables)))
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
if (specific_prepare && (res= (*specific_prepare)(thd)))
|
if (specific_prepare && (res= (*specific_prepare)(thd)))
|
||||||
goto end;
|
goto end;
|
||||||
@ -1328,6 +1328,44 @@ end:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check internal SELECT of the prepared command (with opening and
|
||||||
|
locking tables used).
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
select_like_stmt_test_with_open_n_lock()
|
||||||
|
stmt - prepared statement handler
|
||||||
|
tables - list of tables to be opened and locked
|
||||||
|
before calling specific_prepare function
|
||||||
|
specific_prepare - function of command specific prepare
|
||||||
|
setup_tables_done_option - options to be passed to LEX::unit.prepare()
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
FALSE success
|
||||||
|
TRUE error
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool
|
||||||
|
select_like_stmt_test_with_open_n_lock(Prepared_statement *stmt,
|
||||||
|
TABLE_LIST *tables,
|
||||||
|
bool (*specific_prepare)(THD *thd),
|
||||||
|
ulong setup_tables_done_option)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("select_like_stmt_test_with_open_n_lock");
|
||||||
|
|
||||||
|
/*
|
||||||
|
We should not call LEX::unit.cleanup() after this open_and_lock_tables()
|
||||||
|
call because we don't allow prepared EXPLAIN yet so derived tables will
|
||||||
|
clean up after themself.
|
||||||
|
*/
|
||||||
|
if (open_and_lock_tables(stmt->thd, tables))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
|
DBUG_RETURN(select_like_stmt_test(stmt, specific_prepare,
|
||||||
|
setup_tables_done_option));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Validate and prepare for execution CREATE TABLE statement
|
Validate and prepare for execution CREATE TABLE statement
|
||||||
|
|
||||||
@ -1358,7 +1396,7 @@ static int mysql_test_create_table(Prepared_statement *stmt)
|
|||||||
select_lex->item_list.elements)
|
select_lex->item_list.elements)
|
||||||
{
|
{
|
||||||
select_lex->resolve_mode= SELECT_LEX::SELECT_MODE;
|
select_lex->resolve_mode= SELECT_LEX::SELECT_MODE;
|
||||||
res= select_like_statement_test(stmt, tables, 0, 0);
|
res= select_like_stmt_test_with_open_n_lock(stmt, tables, 0, 0);
|
||||||
select_lex->resolve_mode= SELECT_LEX::NOMATTER_MODE;
|
select_lex->resolve_mode= SELECT_LEX::NOMATTER_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1389,12 +1427,9 @@ static bool mysql_test_multiupdate(Prepared_statement *stmt,
|
|||||||
/* if we switched from normal update, rights are checked */
|
/* if we switched from normal update, rights are checked */
|
||||||
if (!converted && multi_update_precheck(stmt->thd, tables))
|
if (!converted && multi_update_precheck(stmt->thd, tables))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
/*
|
|
||||||
here we do not pass tables for opening, tables will be opened and locked
|
return select_like_stmt_test(stmt, &mysql_multi_update_prepare,
|
||||||
by mysql_multi_update_prepare
|
OPTION_SETUP_TABLES_DONE);
|
||||||
*/
|
|
||||||
return select_like_statement_test(stmt, 0, &mysql_multi_update_prepare,
|
|
||||||
OPTION_SETUP_TABLES_DONE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1422,9 +1457,9 @@ static int mysql_test_multidelete(Prepared_statement *stmt,
|
|||||||
uint fake_counter;
|
uint fake_counter;
|
||||||
if ((res= multi_delete_precheck(stmt->thd, tables, &fake_counter)))
|
if ((res= multi_delete_precheck(stmt->thd, tables, &fake_counter)))
|
||||||
return res;
|
return res;
|
||||||
if ((res= select_like_statement_test(stmt, tables,
|
if ((res= select_like_stmt_test_with_open_n_lock(stmt, tables,
|
||||||
&mysql_multi_delete_prepare,
|
&mysql_multi_delete_prepare,
|
||||||
OPTION_SETUP_TABLES_DONE)))
|
OPTION_SETUP_TABLES_DONE)))
|
||||||
return res;
|
return res;
|
||||||
if (!tables->table)
|
if (!tables->table)
|
||||||
{
|
{
|
||||||
@ -1500,9 +1535,9 @@ static int mysql_test_insert_select(Prepared_statement *stmt,
|
|||||||
first_local_table= (TABLE_LIST *)lex->select_lex.table_list.first;
|
first_local_table= (TABLE_LIST *)lex->select_lex.table_list.first;
|
||||||
DBUG_ASSERT(first_local_table != 0);
|
DBUG_ASSERT(first_local_table != 0);
|
||||||
|
|
||||||
res= select_like_statement_test(stmt, tables,
|
res= select_like_stmt_test_with_open_n_lock(stmt, tables,
|
||||||
&mysql_insert_select_prepare_tester,
|
&mysql_insert_select_prepare_tester,
|
||||||
OPTION_SETUP_TABLES_DONE);
|
OPTION_SETUP_TABLES_DONE);
|
||||||
/* revert changes made by mysql_insert_select_prepare_tester */
|
/* revert changes made by mysql_insert_select_prepare_tester */
|
||||||
lex->select_lex.table_list.first= (byte*) first_local_table;
|
lex->select_lex.table_list.first= (byte*) first_local_table;
|
||||||
lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
|
lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
|
||||||
|
Reference in New Issue
Block a user