diff options
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r-- | sql/sql_insert.cc | 118 |
1 files changed, 28 insertions, 90 deletions
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 7901e2b681e..2097f636dd2 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -373,48 +373,6 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list, return 0; } -/* - Prepare triggers for INSERT-like statement. - - SYNOPSIS - prepare_triggers_for_insert_stmt() - table Table to which insert will happen - - NOTE - Prepare triggers for INSERT-like statement by marking fields - used by triggers and inform handlers that batching of UPDATE/DELETE - cannot be done if there are BEFORE UPDATE/DELETE triggers. -*/ - -void prepare_triggers_for_insert_stmt(TABLE *table) -{ - if (table->triggers) - { - if (table->triggers->has_triggers(TRG_EVENT_DELETE, - TRG_ACTION_AFTER)) - { - /* - The table has AFTER DELETE triggers that might access to - subject table and therefore might need delete to be done - immediately. So we turn-off the batching. - */ - (void) table->file->extra(HA_EXTRA_DELETE_CANNOT_BATCH); - } - if (table->triggers->has_triggers(TRG_EVENT_UPDATE, - TRG_ACTION_AFTER)) - { - /* - The table has AFTER UPDATE triggers that might access to subject - table and therefore might need update to be done immediately. - So we turn-off the batching. - */ - (void) table->file->extra(HA_EXTRA_UPDATE_CANNOT_BATCH); - } - } - table->mark_columns_needed_for_insert(); -} - - /** Upgrade table-level lock of INSERT statement to TL_WRITE if a more concurrent lock is infeasible for some reason. This is @@ -902,7 +860,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, thd->abort_on_warning= !ignore && thd->is_strict_mode(); - prepare_triggers_for_insert_stmt(table); + table->prepare_triggers_for_insert_stmt_or_event(); + table->mark_columns_needed_for_insert(); if (table_list->prepare_where(thd, 0, TRUE) || @@ -3547,7 +3506,10 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) table_list->prepare_check_option(thd)); if (!res) - prepare_triggers_for_insert_stmt(table); + { + table->prepare_triggers_for_insert_stmt_or_event(); + table->mark_columns_needed_for_insert(); + } DBUG_RETURN(res); } @@ -3684,16 +3646,6 @@ void select_insert::store_values(List<Item> &values) TRG_EVENT_INSERT); } -void select_insert::send_error(uint errcode,const char *err) -{ - DBUG_ENTER("select_insert::send_error"); - - my_message(errcode, err, MYF(0)); - - DBUG_VOID_RETURN; -} - - bool select_insert::send_eof() { int error; @@ -4024,6 +3976,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, */ DBUG_ASSERT(0); } + DBUG_ASSERT(create_table->table == create_info->table); } } else @@ -4237,8 +4190,9 @@ select_create::binlog_show_create_table(TABLE **tables, uint count) result= store_create_info(thd, &tmp_table_list, &query, create_info, /* show_database */ TRUE, - MY_TEST(create_info->options & - HA_LEX_CREATE_REPLACE)); + MY_TEST(create_info->org_options & + HA_LEX_CREATE_REPLACE) || + create_info->table_was_deleted); DBUG_ASSERT(result == 0); /* store_create_info() always return 0 */ #ifdef WITH_WSREP @@ -4268,36 +4222,6 @@ void select_create::store_values(List<Item> &values) } -void select_create::send_error(uint errcode,const char *err) -{ - DBUG_ENTER("select_create::send_error"); - - DBUG_PRINT("info", - ("Current statement %s row-based", - thd->is_current_stmt_binlog_format_row() ? "is" : "is NOT")); - DBUG_PRINT("info", - ("Current table (at 0x%lu) %s a temporary (or non-existant) table", - (ulong) table, - table && !table->s->tmp_table ? "is NOT" : "is")); - /* - This will execute any rollbacks that are necessary before writing - the transcation cache. - - We disable the binary log since nothing should be written to the - binary log. This disabling is important, since we potentially do - a "roll back" of non-transactional tables by removing the table, - and the actual rollback might generate events that should not be - written to the binary log. - - */ - tmp_disable_binlog(thd); - select_insert::send_error(errcode, err); - reenable_binlog(thd); - - DBUG_VOID_RETURN; -} - - bool select_create::send_eof() { if (select_insert::send_eof()) @@ -4390,13 +4314,12 @@ void select_create::abort_result_set() of the table succeeded or not, since we need to reset the binary log state. - However if there was an orignal table that was deleted, as part of + However if there was an original table that was deleted, as part of create or replace table, then we must log the statement. */ save_option_bits= thd->variables.option_bits; - if (!(thd->log_current_statement)) - thd->variables.option_bits&= ~OPTION_BIN_LOG; + thd->variables.option_bits&= ~OPTION_BIN_LOG; select_insert::abort_result_set(); thd->transaction.stmt.modified_non_trans_table= FALSE; thd->variables.option_bits= save_option_bits; @@ -4404,6 +4327,12 @@ void select_create::abort_result_set() /* possible error of writing binary log is ignored deliberately */ (void) thd->binlog_flush_pending_rows_event(TRUE, TRUE); + if (create_info->table_was_deleted) + { + /* Unlock locked table that was dropped by CREATE */ + thd->locked_tables_list.unlock_locked_table(thd, + create_info->mdl_ticket); + } if (m_plock) { mysql_unlock_tables(thd, *m_plock); @@ -4413,12 +4342,21 @@ void select_create::abort_result_set() if (table) { + bool tmp_table= table->s->tmp_table; table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); table->auto_increment_field_not_null= FALSE; drop_open_table(thd, table, create_table->db, create_table->table_name); table=0; // Safety + if (thd->log_current_statement && mysql_bin_log.is_open()) + { + /* Remove logging of drop, create + insert rows */ + binlog_reset_cache(thd); + /* Original table was deleted. We have to log it */ + log_drop_table(thd, create_table->db, create_table->db_length, + create_table->table_name, create_table->table_name_length, + tmp_table); + } } DBUG_VOID_RETURN; } - |