diff options
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r-- | sql/sp_head.cc | 50 |
1 files changed, 36 insertions, 14 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc index a9056553080..e892cc81a92 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -368,6 +368,7 @@ Item *THD::sp_prepare_func_item(Item **it_addr, uint cols) /** Fix an Item for evaluation for SP. */ + Item *THD::sp_fix_func_item(Item **it_addr) { DBUG_ENTER("THD::sp_fix_func_item"); @@ -593,6 +594,7 @@ sp_package::~sp_package() /* Test if two routines have equal specifications */ + bool sp_head::eq_routine_spec(const sp_head *sp) const { // TODO: Add tests for equal return data types (in case of FUNCTION) @@ -835,7 +837,7 @@ sp_head::~sp_head() thd->lex->sphead= NULL; lex_end(thd->lex); delete thd->lex; - thd->lex= thd->stmt_lex= lex; + thd->lex= lex; } my_hash_free(&m_sptabs); @@ -904,8 +906,13 @@ sp_head::create_result_field(uint field_max_length, const LEX_CSTRING *field_nam Perhaps we should refactor prepare_create_field() to set Create_field::length to maximum octet length for BLOBs, instead of packed length). + + Note, for integer data types, field_max_length can be bigger + than the user specified length, e.g. a field of the INT(1) data type + is translated to the item with max_length=11. */ DBUG_ASSERT(field_max_length <= m_return_field_def.length || + m_return_field_def.type_handler()->cmp_type() == INT_RESULT || (current_thd->stmt_arena->is_stmt_execute() && m_return_field_def.length == 8 && (m_return_field_def.pack_flag & @@ -1147,7 +1154,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) backup_arena; query_id_t old_query_id; TABLE *old_derived_tables; - LEX *old_lex, *old_stmt_lex; + LEX *old_lex; Item_change_list old_change_list; String old_packet; uint old_server_status; @@ -1254,7 +1261,6 @@ sp_head::execute(THD *thd, bool merge_da_on_success) do it in each instruction */ old_lex= thd->lex; - old_stmt_lex= thd->stmt_lex; /* We should also save Item tree change list to avoid rollback something too early in the calling query. @@ -1371,7 +1377,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success) errors are not catchable by SQL handlers) or the connection has been killed during execution. */ - if (!thd->is_fatal_error && !thd->killed_errno() && + if (likely(!thd->is_fatal_error) && likely(!thd->killed_errno()) && ctx->handle_sql_condition(thd, &ip, i)) { err_status= FALSE; @@ -1380,7 +1386,8 @@ sp_head::execute(THD *thd, bool merge_da_on_success) /* Reset sp_rcontext::end_partial_result_set flag. */ ctx->end_partial_result_set= FALSE; - } while (!err_status && !thd->killed && !thd->is_fatal_error && + } while (!err_status && likely(!thd->killed) && + likely(!thd->is_fatal_error) && !thd->spcont->pause_state); #if defined(ENABLED_PROFILING) @@ -1410,7 +1417,6 @@ sp_head::execute(THD *thd, bool merge_da_on_success) DBUG_ASSERT(thd->Item_change_list::is_empty()); old_change_list.move_elements_to(thd); thd->lex= old_lex; - thd->stmt_lex= old_stmt_lex; thd->set_query_id(old_query_id); DBUG_ASSERT(!thd->derived_tables); thd->derived_tables= old_derived_tables; @@ -1600,6 +1606,7 @@ bool sp_head::check_execute_access(THD *thd) const @retval NULL - error (access denided or EOM) @retval !NULL - success (the invoker has rights to all %TYPE tables) */ + sp_rcontext *sp_head::rcontext_create(THD *thd, Field *ret_value, Row_definition_list *defs, bool switch_security_ctx) @@ -1777,6 +1784,7 @@ err_with_cleanup: /* Execute the package initialization section. */ + bool sp_package::instantiate_if_needed(THD *thd) { List<Item> args; @@ -2452,6 +2460,7 @@ sp_head::merge_lex(THD *thd, LEX *oldlex, LEX *sublex) /** Put the instruction on the backpatch list, associated with the label. */ + int sp_head::push_backpatch(THD *thd, sp_instr *i, sp_label *lab, List<bp_t> *list, backpatch_instr_type itype) @@ -2507,6 +2516,7 @@ sp_head::push_backpatch_goto(THD *thd, sp_pcontext *ctx, sp_label *lab) Update all instruction with this label in the backpatch list to the current position. */ + void sp_head::backpatch(sp_label *lab) { @@ -3034,6 +3044,7 @@ bool sp_head::add_instr_preturn(THD *thd, sp_pcontext *spcont) QQ: Perhaps we need a dedicated sp_instr_nop for this purpose. */ + bool sp_head::replace_instr_to_nop(THD *thd, uint ip) { sp_instr *instr= get_instr(ip); @@ -3158,6 +3169,7 @@ sp_head::opt_mark() @return 0 if ok, !=0 on error. */ + int sp_head::show_routine_code(THD *thd) { @@ -3265,7 +3277,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, We should not save old value since it is saved/restored in sp_head::execute() when we are entering/leaving routine. */ - thd->lex= thd->stmt_lex= m_lex; + thd->lex= m_lex; thd->set_query_id(next_query_id()); @@ -3305,7 +3317,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, if (open_tables) res= instr->exec_open_and_lock_tables(thd, m_lex->query_tables); - if (!res) + if (likely(!res)) { res= instr->exec_core(thd, nextp); DBUG_PRINT("info",("exec_core returned: %d", res)); @@ -3365,7 +3377,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, Update the state of the active arena if no errors on open_tables stage. */ - if (!res || !thd->is_error() || + if (likely(!res) || likely(!thd->is_error()) || (thd->get_stmt_da()->sql_errno() != ER_CANT_REOPEN_TABLE && thd->get_stmt_da()->sql_errno() != ER_NO_SUCH_TABLE && thd->get_stmt_da()->sql_errno() != ER_NO_SUCH_TABLE_IN_ENGINE && @@ -3536,7 +3548,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) thd->set_query(query_backup); thd->query_name_consts= 0; - if (!thd->is_error()) + if (likely(!thd->is_error())) { res= 0; thd->get_stmt_da()->reset_diagnostics_area(); @@ -4402,7 +4414,7 @@ sp_instr_cfetch::print(String *str) int sp_instr_agg_cfetch::execute(THD *thd, uint *nextp) { - DBUG_ENTER("sp_instr_cfetch::execute"); + DBUG_ENTER("sp_instr_agg_cfetch::execute"); int res= 0; if (!thd->spcont->instr_ptr) { @@ -4427,7 +4439,16 @@ sp_instr_agg_cfetch::execute(THD *thd, uint *nextp) DBUG_RETURN(res); } +void +sp_instr_agg_cfetch::print(String *str) +{ + + uint rsrv= SP_INSTR_UINT_MAXLEN+11; + if (str->reserve(rsrv)) + return; + str->qs_append(STRING_WITH_LEN("agg_cfetch")); +} /* sp_instr_cursor_copy_struct class functions @@ -4441,6 +4462,7 @@ sp_instr_agg_cfetch::execute(THD *thd, uint *nextp) - opens the cursor without copying data (materialization). - copies the cursor structure to the associated %ROWTYPE variable. */ + int sp_instr_cursor_copy_struct::exec_core(THD *thd, uint *nextp) { @@ -4917,6 +4939,7 @@ sp_head::set_local_variable(THD *thd, sp_pcontext *spcont, /** Similar to set_local_variable(), but for ROW variable fields. */ + bool sp_head::set_local_variable_row_field(THD *thd, sp_pcontext *spcont, const Sp_rcontext_handler *rh, @@ -5111,6 +5134,7 @@ bool sp_head::spvar_fill_table_rowtype_reference(THD *thd, END p1; Check that the first p1 and the last p1 match. */ + bool sp_head::check_package_routine_end_name(const LEX_CSTRING &end_name) const { LEX_CSTRING non_qualified_name= m_name; @@ -5137,7 +5161,5 @@ err: ulong sp_head::sp_cache_version() const { - return m_parent ? m_parent->sp_cache_version() : - m_sp_cache_version; - + return m_parent ? m_parent->sp_cache_version() : m_sp_cache_version; } |