summaryrefslogtreecommitdiff
path: root/sql/sql_insert.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r--sql/sql_insert.cc118
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;
}
-