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= m_handler->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,
                             &m_name->m_name,
                             &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;

    /*
      Disable slow log for the above call(), if calls are disabled.
      Instead we will log the executed statements to the slow log.
    */
    if (thd->variables.log_slow_disabled_statements & LOG_SLOW_DISABLE_CALL)
      thd->enable_slow_log= 0;
  }
  return false;
}
bool Sql_cmd_call::execute(THD *thd)
{
  TABLE_LIST *all_tables= thd->lex->query_tables;
  sp_head *sp;
   
  if (check_table_access(thd, SELECT_ACL, all_tables, FALSE,
                         UINT_MAX, FALSE) ||
      open_and_lock_tables(thd, all_tables, TRUE, 0))
   return true;

   
  if (!(sp= m_handler->sp_find_routine(thd, m_name, true)))
  {
     
    if (check_routine_access(thd, EXECUTE_ACL, &m_name->m_db,
                             &m_name->m_name,
                             &sp_handler_procedure,
                             false))
      return true;
     
    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;
     
    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;

     
    if (thd->variables.log_slow_disabled_statements & LOG_SLOW_DISABLE_CALL)
      thd->enable_slow_log= 0;
  }
  return false;
}