summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorAlexander Nozdrin <alik@sun.com>2009-12-11 12:39:38 +0300
committerAlexander Nozdrin <alik@sun.com>2009-12-11 12:39:38 +0300
commit567671368723c704d60902b4d0ccff951b414552 (patch)
tree965519a5b0af3f33624c7e16fd61b58d15f42372 /sql/sp_head.cc
parentefee0608316e4cc034a3e62d05980eef8530843d (diff)
parentceefe7bb50b17b72e88851e3b98642e89a4cddae (diff)
downloadmariadb-git-567671368723c704d60902b4d0ccff951b414552.tar.gz
Manual merge from mysql-trunk.
Conflicts: - client/mysqltest.cc - mysql-test/collections/default.experimental - mysql-test/suite/rpl/t/disabled.def - sql/mysqld.cc - sql/opt_range.cc - sql/sp.cc - sql/sql_acl.cc - sql/sql_partition.cc - sql/sql_table.cc
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc98
1 files changed, 65 insertions, 33 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 78539034677..7644cc8e92d 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -14,6 +14,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysql_priv.h"
+#include "sql_prepare.h"
#include "probes_mysql.h"
#ifdef USE_PRAGMA_IMPLEMENTATION
#pragma implementation
@@ -175,9 +176,9 @@ sp_get_flags_for_command(LEX *lex)
case SQLCOM_SHOW_AUTHORS:
case SQLCOM_SHOW_BINLOGS:
case SQLCOM_SHOW_BINLOG_EVENTS:
+ case SQLCOM_SHOW_RELAYLOG_EVENTS:
case SQLCOM_SHOW_CHARSETS:
case SQLCOM_SHOW_COLLATIONS:
- case SQLCOM_SHOW_COLUMN_TYPES:
case SQLCOM_SHOW_CONTRIBUTORS:
case SQLCOM_SHOW_CREATE:
case SQLCOM_SHOW_CREATE_DB:
@@ -534,8 +535,9 @@ sp_head::sp_head()
m_backpatch.empty();
m_cont_backpatch.empty();
m_lex.empty();
- hash_init(&m_sptabs, system_charset_info, 0, 0, 0, sp_table_key, 0, 0);
- hash_init(&m_sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0);
+ my_hash_init(&m_sptabs, system_charset_info, 0, 0, 0, sp_table_key, 0, 0);
+ my_hash_init(&m_sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key,
+ 0, 0);
m_body_utf8.str= NULL;
m_body_utf8.length= 0;
@@ -784,8 +786,8 @@ sp_head::destroy()
m_thd->lex= lex;
}
- hash_free(&m_sptabs);
- hash_free(&m_sroutines);
+ my_hash_free(&m_sptabs);
+ my_hash_free(&m_sroutines);
DBUG_VOID_RETURN;
}
@@ -1086,6 +1088,7 @@ sp_head::execute(THD *thd)
Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
Object_creation_ctx *saved_creation_ctx;
+ Warning_info *saved_warning_info, warning_info(thd->warning_info->warn_id());
/* Use some extra margin for possible SP recursion and functions */
if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (uchar*)&old_packet))
@@ -1134,6 +1137,11 @@ sp_head::execute(THD *thd)
thd->is_slave_error= 0;
old_arena= thd->stmt_arena;
+ /* Push a new warning information area. */
+ warning_info.append_warning_info(thd, thd->warning_info);
+ saved_warning_info= thd->warning_info;
+ thd->warning_info= &warning_info;
+
/*
Switch query context. This has to be done early as this is sometimes
allocated trough sql_alloc
@@ -1204,7 +1212,7 @@ sp_head::execute(THD *thd)
*/
thd->spcont->callers_arena= &backup_arena;
-#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+#if defined(ENABLED_PROFILING)
/* Discard the initial part of executing routines. */
thd->profiling.discard_current_query();
#endif
@@ -1213,7 +1221,7 @@ sp_head::execute(THD *thd)
sp_instr *i;
uint hip; // Handler ip
-#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+#if defined(ENABLED_PROFILING)
/*
Treat each "instr" of a routine as discrete unit that could be profiled.
Profiling only records information for segments of code that set the
@@ -1226,7 +1234,7 @@ sp_head::execute(THD *thd)
i = get_instr(ip); // Returns NULL when we're done.
if (i == NULL)
{
-#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+#if defined(ENABLED_PROFILING)
thd->profiling.discard_current_query();
#endif
break;
@@ -1281,31 +1289,35 @@ sp_head::execute(THD *thd)
*/
if (ctx)
{
- uint hf;
+ uint handler_index;
- switch (ctx->found_handler(&hip, &hf)) {
+ switch (ctx->found_handler(& hip, & handler_index)) {
case SP_HANDLER_NONE:
break;
case SP_HANDLER_CONTINUE:
thd->restore_active_arena(&execute_arena, &backup_arena);
thd->set_n_backup_active_arena(&execute_arena, &backup_arena);
ctx->push_hstack(i->get_cont_dest());
- // Fall through
+ /* Fall through */
default:
+ if (ctx->end_partial_result_set)
+ thd->protocol->end_partial_result_set(thd);
ip= hip;
err_status= FALSE;
ctx->clear_handler();
- ctx->enter_handler(hip);
+ ctx->enter_handler(hip, handler_index);
thd->clear_error();
thd->is_fatal_error= 0;
thd->killed= THD::NOT_KILLED;
thd->mysys_var->abort= 0;
continue;
}
+
+ ctx->end_partial_result_set= FALSE;
}
- } while (!err_status && !thd->killed);
+ } while (!err_status && !thd->killed && !thd->is_fatal_error);
-#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+#if defined(ENABLED_PROFILING)
thd->profiling.finish_current_query();
thd->profiling.start_new_query("tail end of routine");
#endif
@@ -1337,6 +1349,10 @@ sp_head::execute(THD *thd)
thd->stmt_arena= old_arena;
state= EXECUTED;
+ /* Restore the caller's original warning information area. */
+ saved_warning_info->merge_with_routine_info(thd, thd->warning_info);
+ thd->warning_info= saved_warning_info;
+
done:
DBUG_PRINT("info", ("err_status: %d killed: %d is_slave_error: %d report_error: %d",
err_status, thd->killed, thd->is_slave_error,
@@ -1946,15 +1962,19 @@ 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 arguments evaluation required prelocking mode,
+ /*
+ Okay, got values for all arguments. Close tables that might be used by
+ arguments evaluation. If arguments evaluation required prelocking mode,
we'll leave it here.
*/
if (!thd->in_sub_stmt)
{
thd->lex->unit.cleanup();
- close_thread_tables(thd);
+
+ thd_proc_info(thd, "closing tables");
+ close_thread_tables(thd);
+ thd_proc_info(thd, 0);
+
thd->rollback_item_tree_changes();
}
@@ -2027,6 +2047,16 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
err_status= TRUE;
break;
}
+
+ Send_field *out_param_info= new (thd->mem_root) Send_field();
+ nctx->get_item(i)->make_field(out_param_info);
+ out_param_info->db_name= m_db.str;
+ out_param_info->table_name= m_name.str;
+ out_param_info->org_table_name= m_name.str;
+ out_param_info->col_name= spvar->name.str;
+ out_param_info->org_col_name= spvar->name.str;
+
+ srp->set_out_param_info(out_param_info);
}
}
@@ -2362,7 +2392,8 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
bzero((char*) &tables,sizeof(tables));
tables.db= (char*) "mysql";
tables.table_name= tables.alias= (char*) "proc";
- *full_access= (!check_table_access(thd, SELECT_ACL, &tables, 1, TRUE) ||
+ *full_access= (!check_table_access(thd, SELECT_ACL, &tables, FALSE,
+ 1, TRUE) ||
(!strcmp(sp->m_definer_user.str,
thd->security_ctx->priv_user) &&
!strcmp(sp->m_definer_host.str,
@@ -2445,7 +2476,7 @@ sp_head::show_create_routine(THD *thd, int type)
fields.push_back(new Item_empty_string("Database Collation",
MY_CS_NAME_SIZE));
- if (protocol->send_fields(&fields,
+ if (protocol->send_result_set_metadata(&fields,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
{
DBUG_RETURN(TRUE);
@@ -2537,7 +2568,8 @@ void sp_head::optimize()
else
{
if (src != dst)
- { // Move the instruction and update prev. jumps
+ {
+ /* Move the instruction and update prev. jumps */
sp_instr *ibp;
List_iterator_fast<sp_instr> li(bp);
@@ -2630,8 +2662,8 @@ sp_head::show_routine_code(THD *thd)
field_list.push_back(new Item_uint("Pos", 9));
// 1024 is for not to confuse old clients
field_list.push_back(new Item_empty_string("Instruction",
- max(buffer.length(), 1024)));
- if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
+ max(buffer.length(), 1024)));
+ if (protocol->send_result_set_metadata(&field_list, Protocol::SEND_NUM_ROWS |
Protocol::SEND_EOF))
DBUG_RETURN(1);
@@ -2807,7 +2839,7 @@ int sp_instr::exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables)
Check whenever we have access to tables for this statement
and open and lock them before executing instructions core function.
*/
- if (check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)
+ if (check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE)
|| open_and_lock_tables(thd, tables))
result= -1;
else
@@ -2843,7 +2875,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
query= thd->query();
query_length= thd->query_length();
-#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+#if defined(ENABLED_PROFILING)
/* This s-p instr is profilable and will be captured. */
thd->profiling.set_query_source(m_query.str, m_query.length);
#endif
@@ -2863,8 +2895,8 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
{
res= m_lex_keeper.reset_lex_and_exec_core(thd, nextp, FALSE, this);
- if (thd->main_da.is_eof())
- net_end_statement(thd);
+ if (thd->stmt_da->is_eof())
+ thd->protocol->end_statement();
query_cache_end_of_result(thd);
@@ -2877,7 +2909,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
thd->query_name_consts= 0;
if (!thd->is_error())
- thd->main_da.reset_diagnostics_area();
+ thd->stmt_da->reset_diagnostics_area();
}
DBUG_RETURN(res || thd->is_error());
}
@@ -3253,7 +3285,7 @@ sp_instr_hpush_jump::execute(THD *thd, uint *nextp)
sp_cond_type_t *p;
while ((p= li++))
- thd->spcont->push_handler(p, m_ip+1, m_type, m_frame);
+ thd->spcont->push_handler(p, m_ip+1, m_type);
*nextp= m_dest;
DBUG_RETURN(0);
@@ -3820,7 +3852,7 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
for (uint i= 0 ; i < m_sptabs.records ; i++)
{
- tab= (SP_TABLE *)hash_element(&m_sptabs, i);
+ tab= (SP_TABLE*) my_hash_element(&m_sptabs, i);
tab->query_lock_count= 0;
}
@@ -3854,8 +3886,8 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
(and therefore should not be prelocked). Otherwise we will erroneously
treat table with same name but with different alias as non-temporary.
*/
- if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname, tlen)) ||
- ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname,
+ if ((tab= (SP_TABLE*) my_hash_search(&m_sptabs, (uchar *)tname, tlen)) ||
+ ((tab= (SP_TABLE*) my_hash_search(&m_sptabs, (uchar *)tname,
tlen - alen - 1)) &&
tab->temp))
{
@@ -3941,7 +3973,7 @@ sp_head::add_used_tables_to_table_list(THD *thd,
{
char *tab_buff, *key_buff;
TABLE_LIST *table;
- SP_TABLE *stab= (SP_TABLE *)hash_element(&m_sptabs, i);
+ SP_TABLE *stab= (SP_TABLE*) my_hash_element(&m_sptabs, i);
if (stab->temp)
continue;