diff options
author | Alexander Nozdrin <alik@sun.com> | 2009-12-11 12:39:38 +0300 |
---|---|---|
committer | Alexander Nozdrin <alik@sun.com> | 2009-12-11 12:39:38 +0300 |
commit | 567671368723c704d60902b4d0ccff951b414552 (patch) | |
tree | 965519a5b0af3f33624c7e16fd61b58d15f42372 /sql/sp_head.cc | |
parent | efee0608316e4cc034a3e62d05980eef8530843d (diff) | |
parent | ceefe7bb50b17b72e88851e3b98642e89a4cddae (diff) | |
download | mariadb-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.cc | 98 |
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; |