diff options
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r-- | sql/sql_base.cc | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 7b9ffc2e..c593035f 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -814,8 +814,10 @@ int close_thread_tables(THD *thd) { TABLE *table; int error= 0; + PSI_stage_info org_stage; DBUG_ENTER("close_thread_tables"); + thd->backup_stage(&org_stage); THD_STAGE_INFO(thd, stage_closing_tables); #ifdef EXTRA_DEBUG @@ -931,7 +933,10 @@ int close_thread_tables(THD *thd) we will exit this function a few lines below. */ if (! thd->lex->requires_prelocking()) - DBUG_RETURN(0); + { + error= 0; + goto end; + } /* We are in the top-level statement of a prelocked statement, @@ -942,7 +947,10 @@ int close_thread_tables(THD *thd) thd->locked_tables_mode= LTM_LOCK_TABLES; if (thd->locked_tables_mode == LTM_LOCK_TABLES) - DBUG_RETURN(0); + { + error= 0; + goto end; + } thd->leave_locked_tables_mode(); @@ -971,6 +979,8 @@ int close_thread_tables(THD *thd) while (thd->open_tables) (void) close_thread_table(thd, &thd->open_tables); +end: + THD_STAGE_INFO(thd, org_stage); DBUG_RETURN(error); } @@ -3770,7 +3780,7 @@ open_and_process_routine(THD *thd, Query_tables_list *prelocking_ctx, DBUG_RETURN(TRUE); /* Ensures the routine is up-to-date and cached, if exists. */ - if (rt->sp_cache_routine(thd, has_prelocking_list, &sp)) + if (rt->sp_cache_routine(thd, &sp)) DBUG_RETURN(TRUE); /* Remember the version of the routine in the parse tree. */ @@ -3811,7 +3821,7 @@ open_and_process_routine(THD *thd, Query_tables_list *prelocking_ctx, Validating routine version is unnecessary, since CALL does not affect the prepared statement prelocked list. */ - if (rt->sp_cache_routine(thd, false, &sp)) + if (rt->sp_cache_routine(thd, &sp)) DBUG_RETURN(TRUE); } } @@ -5005,6 +5015,9 @@ prepare_fk_prelocking_list(THD *thd, Query_tables_list *prelocking_ctx, Query_arena *arena, backup; TABLE *table= table_list->table; + if (!table->file->referenced_by_foreign_key()) + DBUG_RETURN(FALSE); + arena= thd->activate_stmt_arena_if_needed(&backup); table->file->get_parent_foreign_key_list(thd, &fk_list); @@ -5090,16 +5103,12 @@ bool DML_prelocking_strategy::handle_table(THD *thd, return TRUE; } - if (table->file->referenced_by_foreign_key()) - { - if (prepare_fk_prelocking_list(thd, prelocking_ctx, table_list, - need_prelocking, - table_list->trg_event_map)) - return TRUE; - } + if (prepare_fk_prelocking_list(thd, prelocking_ctx, table_list, + need_prelocking, + table_list->trg_event_map)) + return TRUE; } - else if (table_list->slave_fk_event_map && - table->file->referenced_by_foreign_key()) + else if (table_list->slave_fk_event_map) { if (prepare_fk_prelocking_list(thd, prelocking_ctx, table_list, need_prelocking, @@ -5843,13 +5852,23 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint count, uint flags) } } - DEBUG_SYNC(thd, "before_lock_tables_takes_lock"); +#ifdef ENABLED_DEBUG_SYNC + if (!tables || + !(strcmp(tables->db.str, "mysql") == 0 && + strcmp(tables->table_name.str, "proc") == 0)) + DEBUG_SYNC(thd, "before_lock_tables_takes_lock"); +#endif if (! (thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start), flags))) DBUG_RETURN(TRUE); - DEBUG_SYNC(thd, "after_lock_tables_takes_lock"); +#ifdef ENABLED_DEBUG_SYNC + if (!tables || + !(strcmp(tables->db.str, "mysql") == 0 && + strcmp(tables->table_name.str, "proc") == 0)) + DEBUG_SYNC(thd, "after_lock_tables_takes_lock"); +#endif if (thd->lex->requires_prelocking() && thd->lex->sql_command != SQLCOM_LOCK_TABLES && @@ -9212,6 +9231,9 @@ fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, @param values values to fill with @param ignore_errors TRUE if we should ignore errors @param use_value forces usage of value of the items instead of result + @param check_for_computability whether to check for ability to invoke val_*() + methods (val_int () etc) against supplied + values @details fill_record() may set table->auto_increment_field_not_null and a @@ -9225,7 +9247,7 @@ fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, bool fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values, - bool ignore_errors, bool use_value) + bool ignore_errors, bool use_value, bool check_for_computability) { List_iterator_fast<Item> v(values); List<TABLE> tbl_list; @@ -9265,6 +9287,10 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values, /* Ensure the end of the list of values is not reached */ DBUG_ASSERT(value); + if (check_for_computability && + value->check_is_evaluable_expression_or_error()) + goto err; + const bool skip_sys_field= field->vers_sys_field() && !thd->vers_insert_history_fast(table); @@ -9341,7 +9367,7 @@ fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, Field **ptr, bool result; Table_triggers_list *triggers= table->triggers; - result= fill_record(thd, table, ptr, values, ignore_errors, FALSE); + result= fill_record(thd, table, ptr, values, ignore_errors, false, false); if (!result && triggers && *ptr) result= triggers->process_triggers(thd, event, TRG_ACTION_BEFORE, TRUE) || |