1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

MDEV-13529 Add class Sql_cmd_call

This commit is contained in:
Alexander Barkov
2017-08-15 14:13:42 +04:00
parent 966cc80299
commit 4d50594dfc
8 changed files with 120 additions and 68 deletions

View File

@ -3074,6 +3074,69 @@ static bool prepare_db_action(THD *thd, ulong want_access, LEX_CSTRING *dbname)
return check_access(thd, want_access, dbname->str, NULL, NULL, 1, 0);
}
bool Sql_cmd_call::execute(THD *thd)
{
TABLE_LIST *all_tables= thd->lex->query_tables;
sp_head *sp;
/*
This will cache all SP and SF and open and lock all tables
required for execution.
*/
if (check_table_access(thd, SELECT_ACL, all_tables, FALSE,
UINT_MAX, FALSE) ||
open_and_lock_tables(thd, all_tables, TRUE, 0))
return true;
/*
By this moment all needed SPs should be in cache so no need to look
into DB.
*/
if (!(sp= sp_handler_procedure.sp_find_routine(thd, m_name, true)))
{
/*
If the routine is not found, let's still check EXECUTE_ACL to decide
whether to return "Access denied" or "Routine does not exist".
*/
if (check_routine_access(thd, EXECUTE_ACL, m_name->m_db.str,
m_name->m_name.str,
&sp_handler_procedure,
false))
return true;
/*
sp_find_routine can have issued an ER_SP_RECURSION_LIMIT error.
Send message ER_SP_DOES_NOT_EXIST only if procedure is not found in
cache.
*/
if (!sp_cache_lookup(&thd->sp_proc_cache, m_name))
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE",
ErrConvDQName(m_name).ptr());
return true;
}
else
{
if (sp->check_execute_access(thd))
return true;
/*
Check that the stored procedure doesn't contain Dynamic SQL
and doesn't return result sets: such stored procedures can't
be called from a function or trigger.
*/
if (thd->in_sub_stmt)
{
const char *where= (thd->in_sub_stmt & SUB_STMT_TRIGGER ?
"trigger" : "function");
if (sp->is_not_allowed_in_function(where))
return true;
}
if (do_execute_sp(thd, sp))
return true;
}
return false;
}
/**
Execute command saved in thd and lex->sql_command.
@ -5748,60 +5811,6 @@ end_with_restore_list:
my_ok(thd);
break; /* break super switch */
} /* end case group bracket */
case SQLCOM_CALL:
{
sp_head *sp;
/*
This will cache all SP and SF and open and lock all tables
required for execution.
*/
if (check_table_access(thd, SELECT_ACL, all_tables, FALSE,
UINT_MAX, FALSE) ||
open_and_lock_tables(thd, all_tables, TRUE, 0))
goto error;
if (check_routine_access(thd, EXECUTE_ACL, lex->spname->m_db.str,
lex->spname->m_name.str, &sp_handler_procedure,
false))
goto error;
/*
By this moment all needed SPs should be in cache so no need to look
into DB.
*/
if (!(sp= sp_handler_procedure.sp_find_routine(thd, lex->spname, true)))
{
/*
sp_find_routine can have issued an ER_SP_RECURSION_LIMIT error.
Send message ER_SP_DOES_NOT_EXIST only if procedure is not found in
cache.
*/
if (!sp_cache_lookup(&thd->sp_proc_cache, lex->spname))
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE",
ErrConvDQName(lex->spname).ptr());
goto error;
}
else
{
/*
Check that the stored procedure doesn't contain Dynamic SQL
and doesn't return result sets: such stored procedures can't
be called from a function or trigger.
*/
if (thd->in_sub_stmt)
{
const char *where= (thd->in_sub_stmt & SUB_STMT_TRIGGER ?
"trigger" : "function");
if (sp->is_not_allowed_in_function(where))
goto error;
}
if (do_execute_sp(thd, sp))
goto error;
}
break;
}
case SQLCOM_COMPOUND:
DBUG_ASSERT(all_tables == 0);
DBUG_ASSERT(thd->in_sub_stmt == 0);
@ -6196,6 +6205,7 @@ end_with_restore_list:
case SQLCOM_SIGNAL:
case SQLCOM_RESIGNAL:
case SQLCOM_GET_DIAGNOSTICS:
case SQLCOM_CALL:
DBUG_ASSERT(lex->m_sql_cmd != NULL);
res= lex->m_sql_cmd->execute(thd);
break;