1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Revert MDEV-25292 Atomic CREATE OR REPLACE TABLE

Specifically:

Revert "MDEV-29664 Assertion `!n_mysql_tables_in_use' failed in innobase_close_connection"
This reverts commit ba875e9396.

Revert "MDEV-29620 Assertion `next_insert_id == 0' failed in handler::ha_external_lock"
This reverts commit aa08a7442a.

Revert "MDEV-29628 Memory leak after CREATE OR REPLACE with foreign key"
This reverts commit c579d66ba6.

Revert "MDEV-29609 create_not_windows test fails with different result"
This reverts commit cb583b2f1b.

Revert "MDEV-29544 SIGSEGV in HA_CREATE_INFO::finalize_locked_tables"
This reverts commit dcd66c3814.

Revert "MDEV-28933 CREATE OR REPLACE fails to recreate same constraint name"
This reverts commit cf6c517632.

Revert "MDEV-28933 Moved RENAME_CONSTRAINT_IDS to include/sql_funcs.h"
This reverts commit f1e1c1335b.

Revert "MDEV-28956 Locking is broken if CREATE OR REPLACE fails under LOCK TABLES"
This reverts commit a228ec80e3.

Revert "MDEV-25292 gcol.gcol_bugfixes --ps fix"
This reverts commit 24fff8267d.

Revert "MDEV-25292 Disable atomic replace for slave-generated or-replace"
This reverts commit 2af15914cb.

Revert "MDEV-25292 backup_log improved"
This reverts commit 34398a20b5.

Revert "MDEV-25292 Atomic CREATE OR REPLACE TABLE"
This reverts commit 93c8252f02.

Revert "MDEV-25292 Table_name class for (db, table_name, alias)"
This reverts commit d145dda9c7.

Revert "MDEV-25292 ha_table_exists() cleanup and improvement"
This reverts commit 409b8a86de.

Revert "MDEV-25292 Cleanups"
This reverts commit 595dad83ad.

Revert "MDEV-25292 Refactoring: moved select_field_count into Alter_info."
This reverts commit f02af1d229.
This commit is contained in:
Sergei Golubchik
2022-10-27 22:18:51 +02:00
parent d15260990d
commit 2bd41fc5bf
92 changed files with 1386 additions and 9510 deletions

View File

@ -3887,8 +3887,7 @@ select_insert::select_insert(THD *thd_arg, TABLE_LIST *table_list_par,
sel_result(result),
table_list(table_list_par), table(table_par), fields(fields_par),
autoinc_value_of_last_inserted_row(0),
insert_into_view(table_list_par && table_list_par->view != 0),
binary_logged(false), atomic_replace(false), create_info(NULL)
insert_into_view(table_list_par && table_list_par->view != 0)
{
bzero((char*) &info,sizeof(info));
info.handle_duplicates= duplic;
@ -3897,37 +3896,6 @@ select_insert::select_insert(THD *thd_arg, TABLE_LIST *table_list_par,
info.update_values= update_values;
info.view= (table_list_par->view ? table_list_par : 0);
info.table_list= table_list_par;
tmp_table= table ? table->s->tmp_table != NO_TMP_TABLE : false;
}
select_create::select_create(THD *thd, TABLE_LIST *table_arg,
Table_specification_st *create_info_par,
Alter_info *alter_info_arg,
List<Item> &select_fields,
enum_duplicates duplic, bool ignore,
TABLE_LIST *select_tables_arg):
select_insert(thd, table_arg, NULL, &select_fields, 0, 0, duplic,
ignore, NULL),
orig_table(table_arg),
select_tables(select_tables_arg),
alter_info(alter_info_arg),
m_plock(NULL), exit_done(0),
saved_tmp_table_share(0)
{
DBUG_ASSERT(create_info_par->default_table_charset);
bzero(&ddl_log_state_create, sizeof(ddl_log_state_create));
bzero(&ddl_log_state_rm, sizeof(ddl_log_state_rm));
create_info= create_info_par;
if (!thd->is_current_stmt_binlog_format_row() ||
!ha_check_storage_engine_flag(create_info->db_type,
HTON_NO_BINLOG_ROW_OPT))
atomic_replace= create_info->is_atomic_replace();
else
DBUG_ASSERT(!atomic_replace);
create_info->ddl_log_state_create= &ddl_log_state_create;
create_info->ddl_log_state_rm= &ddl_log_state_rm;
tmp_table= create_info->tmp_table();
}
@ -4266,10 +4234,10 @@ void select_insert::store_values(List<Item> &values)
bool select_insert::prepare_eof()
{
int error;
#ifndef DBUG_OFF
bool const trans_table= table->file->has_transactions_and_rollback();
#endif
bool changed;
bool binary_logged= 0;
killed_state killed_status= thd->killed;
DBUG_ENTER("select_insert::prepare_eof");
DBUG_PRINT("enter", ("trans_table: %d, table_type: '%s'",
@ -4287,33 +4255,12 @@ bool select_insert::prepare_eof()
error= thd->get_stmt_da()->sql_errno();
if (info.ignore || info.handle_duplicates != DUP_ERROR)
if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
table->file->ha_rnd_end();
if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
table->file->ha_rnd_end();
table->file->extra(HA_EXTRA_END_ALTER_COPY);
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
if (atomic_replace && !error)
{
DBUG_ASSERT(table->s->tmp_table);
table->file->ha_release_auto_increment();
/*
Note: InnoDB does autocommit on external unlock.
We cannot do commit twice and we must commit after binlog
(flush row events is done at commit), so we cannot do it here.
Test: rpl.create_or_replace_row
*/
ulonglong save_options_bits= thd->variables.option_bits;
thd->variables.option_bits|= OPTION_NOT_AUTOCOMMIT;
int lock_error= table->file->ha_external_lock(thd, F_UNLCK);
thd->variables.option_bits= save_options_bits;
if (lock_error)
DBUG_RETURN(true); /* purecov: inspected */
}
if (likely((changed= (info.copied || info.deleted || info.updated))))
{
/*
@ -4331,54 +4278,19 @@ bool select_insert::prepare_eof()
DBUG_ASSERT(trans_table || !changed ||
thd->transaction->stmt.modified_non_trans_table);
if (unlikely(error))
{
if ((thd->transaction->stmt.modified_non_trans_table ||
thd->log_current_statement()) && !atomic_replace)
{
if (binlog_query())
table->file->print_error(error,MYF(0));
}
else
table->file->ha_release_auto_increment();
DBUG_RETURN(true);
}
DBUG_RETURN(false);
}
bool select_insert::binlog_query()
{
/* For atomic_replace table was already closed in send_eof(). */
DBUG_ASSERT(table || atomic_replace);
const bool trans_table= table ? table->file->has_transactions_and_rollback() :
false;
killed_state killed_status= thd->killed;
DBUG_ENTER("select_insert::binlog_query");
/*
Write to binlog before commiting transaction. No statement will
be written by the binlog_query() below in RBR mode. All the
events are in the transaction cache and will be written when
ha_autocommit_or_rollback() is issued below.
*/
if ((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()))
if ((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) &&
(likely(!error) || thd->transaction->stmt.modified_non_trans_table ||
thd->log_current_statement()))
{
debug_crash_here("ddl_log_create_before_binlog");
if (create_info && !create_info->tmp_table())
{
thd->binlog_xid= thd->query_id;
/* Remember xid's for the case of row based logging */
ddl_log_update_xid(create_info->ddl_log_state_create, thd->binlog_xid);
if (create_info->ddl_log_state_rm->is_active() && !atomic_replace)
ddl_log_update_xid(create_info->ddl_log_state_rm, thd->binlog_xid);
}
int errcode= 0;
int res;
if (thd->is_error())
if (likely(!error))
thd->clear_error();
else
errcode= query_error_code(thd, killed_status == NOT_KILLED);
@ -4387,24 +4299,20 @@ bool select_insert::binlog_query()
res= thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
trans_table, FALSE, FALSE, errcode);
/*
NOTE: binlog_xid must be cleared after commit because pending row events
are written at commit phase.
*/
if (res > 0)
{
thd->binlog_xid= 0;
if (table)
table->file->ha_release_auto_increment();
table->file->ha_release_auto_increment();
DBUG_RETURN(true);
}
binary_logged= res == 0 || !tmp_table;
binary_logged= res == 0 || !table->s->tmp_table;
}
if (table)
table->s->table_creation_was_logged|= binary_logged;
table->file->ha_release_auto_increment();
if (unlikely(error))
{
/* NOTE: used in binlog_drop_table(), not needed for atomic_replace */
table->s->table_creation_was_logged|= binary_logged;
table->file->ha_release_auto_increment();
table->file->print_error(error,MYF(0));
DBUG_RETURN(true);
}
DBUG_RETURN(false);
@ -4451,8 +4359,7 @@ bool select_insert::send_eof()
{
bool res;
DBUG_ENTER("select_insert::send_eof");
res= (prepare_eof() || binlog_query() ||
(!suppress_my_ok && send_ok_packet()));
res= (prepare_eof() || (!suppress_my_ok && send_ok_packet()));
DBUG_RETURN(res);
}
@ -4517,11 +4424,7 @@ void select_insert::abort_result_set()
res= thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(),
thd->query_length(),
transactional_table, FALSE, FALSE, errcode);
/* TODO: Update binary_logged in do_postlock() for RBR? */
const bool tmp_table= create_info ? create_info->tmp_table() :
(bool) table->s->tmp_table;
binary_logged= res == 0 || !tmp_table;
binary_logged= res == 0 || !table->s->tmp_table;
}
if (changed)
query_cache_invalidate3(thd, table, 1);
@ -4594,13 +4497,11 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
TABLE tmp_table; // Used during 'Create_field()'
TABLE_SHARE share;
TABLE *table= 0;
alter_info->select_field_count= items->elements;
uint select_field_count= items->elements;
/* Add selected items to field list */
List_iterator_fast<Item> it(*items);
Item *item;
bool save_table_creation_was_logged;
int create_table_mode= C_ORDINARY_CREATE;
LEX_CUSTRING frm= {0, 0};
DBUG_ENTER("select_create::create_table_from_items");
tmp_table.s= &share;
@ -4656,7 +4557,8 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
if (create_info->check_fields(thd, alter_info,
table_list->table_name,
table_list->db))
table_list->db,
select_field_count))
DBUG_RETURN(NULL);
DEBUG_SYNC(thd,"create_table_select_before_create");
@ -4671,13 +4573,6 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
create_info->mdl_ticket= table_list->table->mdl_ticket;
}
if (atomic_replace)
{
if (create_info->make_tmp_table_list(thd, &table_list,
&create_table_mode))
DBUG_RETURN(NULL);
}
/*
Create and lock table.
@ -4695,14 +4590,11 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
open_table().
*/
if (!mysql_create_table_no_lock(thd,
&orig_table->db,
&orig_table->table_name,
if (!mysql_create_table_no_lock(thd, &ddl_log_state_create, &ddl_log_state_rm,
&table_list->db,
&table_list->table_name,
create_info, alter_info, NULL,
create_table_mode, table_list,
atomic_replace ? &frm : NULL))
select_field_count, table_list))
{
DEBUG_SYNC(thd,"create_table_select_before_open");
@ -4712,58 +4604,7 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
*/
table_list->table= 0;
if (atomic_replace)
{
char tmp_path[FN_REFLEN + 1];
build_table_filename(tmp_path, sizeof(tmp_path) - 1, table_list->db.str,
table_list->table_name.str, "", FN_IS_TMP);
table_list->table=
thd->create_and_open_tmp_table(&frm, tmp_path, orig_table->db.str,
orig_table->table_name.str, false);
/*
NOTE: if create_and_open_tmp_table() fails the table is dropped by
ddl_log_state_create
*/
if (table_list->table)
{
table_list->table->s->tmp_table= TMP_TABLE_ATOMIC_REPLACE;
/*
NOTE: Aria tables require table locking to work in transactional
mode. Since we don't lock our temporary table we get problems with
unproperly initialized transactional mode: seg-fault while accessing
uninitialized trn member (reproduced by
atomic.create_replace,aria,stmt).
This hack disables logging for Aria table (that is not needed anyway
for a temporary table).
*/
TABLE *table= table_list->table;
int error;
/* Disable logging of inserted rows */
mysql_trans_prepare_alter_copy_data(thd);
if ((DBUG_IF("atomic_replace_external_lock_fail") &&
(error= HA_ERR_LOCK_TABLE_FULL)) ||
(error= table->file->ha_external_lock(thd, F_WRLCK)))
{
table->file->print_error(error, MYF(0));
/*
Enable transaction logging. We cannot call ha_enable_transaction()
as this would write the transaction to the binary log
*/
thd->transaction->on= true;
table->file->ha_reset();
thd->drop_temporary_table(table, NULL, false);
table_list->table= 0;
goto err;
}
table_list->table->s->can_do_row_logging= 1;
}
}
else if (!create_info->tmp_table())
if (!create_info->tmp_table())
{
Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN);
TABLE_LIST::enum_open_strategy save_open_strategy;
@ -4804,18 +4645,13 @@ TABLE *select_create::create_table_from_items(THD *thd, List<Item> *items,
}
else
table_list->table= 0; // Create failed
err:
DBUG_ASSERT(!table_list->table || frm.str || !atomic_replace);
my_free(const_cast<uchar *>(frm.str));
if (unlikely(!(table= table_list->table)))
{
const bool error= thd->is_error();
/* CREATE ... IF NOT EXISTS succeed, but did nothing */
if (likely(!error))
my_ok(thd);
create_info->finalize_ddl(thd, error);
if (likely(!thd->is_error())) // CREATE ... IF NOT EXISTS
my_ok(thd); // succeed, but did nothing
ddl_log_complete(&ddl_log_state_rm);
ddl_log_complete(&ddl_log_state_create);
DBUG_RETURN(NULL);
}
@ -4834,13 +4670,9 @@ err:
mysql_lock_tables() below should never fail with request to reopen table
since it won't wait for the table lock (we have exclusive metadata lock on
the table) and thus can't get aborted.
In case of atomic_replace we have already called ha_external_lock() above
on the newly created temporary table.
*/
if ((!atomic_replace &&
unlikely(!((*lock)= mysql_lock_tables(thd, &table, 1, 0)))) ||
postlock(thd, &table))
if (unlikely(!((*lock)= mysql_lock_tables(thd, &table, 1, 0)) ||
postlock(thd, &table)))
{
/* purecov: begin tested */
/*
@ -4857,24 +4689,13 @@ err:
*lock= 0;
}
drop_open_table(thd, table, &table_list->db, &table_list->table_name);
if (atomic_replace)
create_info->finalize_ddl(thd, 1);
else
{
debug_crash_here("ddl_log_create_log_complete");
ddl_log_complete(&ddl_log_state_create);
debug_crash_here("ddl_log_create_log_complete2");
}
thd->transaction->on= true;
ddl_log_complete(&ddl_log_state_rm);
ddl_log_complete(&ddl_log_state_create);
DBUG_RETURN(NULL);
/* purecov: end */
}
DBUG_ASSERT(
create_info->tmp_table() ||
thd->mdl_context.is_lock_owner(MDL_key::TABLE, orig_table->db.str,
orig_table->table_name.str, MDL_SHARED));
table->s->table_creation_was_logged= save_table_creation_was_logged;
if (!create_info->tmp_table())
if (!table->s->tmp_table)
table->file->prepare_for_row_logging();
/*
@ -4922,10 +4743,11 @@ int select_create::postlock(THD *thd, TABLE **tables)
if (unlikely(error))
return error;
if (thd->is_current_stmt_binlog_format_row() && !create_info->tmp_table())
error= binlog_show_create_table(thd, *tables, create_info);
return error;
TABLE const *const table = *tables;
if (thd->is_current_stmt_binlog_format_row() &&
!table->s->tmp_table)
return binlog_show_create_table(thd, *tables, create_info);
return 0;
}
@ -4952,11 +4774,7 @@ select_create::prepare(List<Item> &_values, SELECT_LEX_UNIT *u)
if (!(table= create_table_from_items(thd, &values, &extra_lock)))
{
/*
TODO: Use create_info->table_was_deleted
(now binlog.binlog_stm_binlog fails).
*/
if (create_info->or_replace() && !atomic_replace)
if (create_info->or_replace())
{
/* Original table was deleted. We have to log it */
log_drop_table(thd, &table_list->db, &table_list->table_name,
@ -4970,8 +4788,6 @@ select_create::prepare(List<Item> &_values, SELECT_LEX_UNIT *u)
DBUG_RETURN(-1);
}
DBUG_ASSERT(table == table_list->table);
if (create_info->tmp_table())
{
/*
@ -4981,26 +4797,17 @@ select_create::prepare(List<Item> &_values, SELECT_LEX_UNIT *u)
list to keep them inaccessible from inner statements.
e.g. CREATE TEMPORARY TABLE `t1` AS SELECT * FROM `t1`;
*/
saved_tmp_table_share= thd->save_tmp_table_share(table);
saved_tmp_table_share= thd->save_tmp_table_share(table_list->table);
}
if (extra_lock)
{
DBUG_ASSERT(m_plock == NULL);
if (table->s->tmp_table)
{
/* Table is a temporary table, don't write table map to binary log */
if (create_info->tmp_table())
m_plock= &m_lock;
}
else
{
/*
Table is a normal table. Inform binlog_write_table_maps() that
it should write the table map for the current table.
*/
m_plock= &thd->extra_lock;
}
*m_plock= extra_lock;
}
@ -5092,14 +4899,6 @@ static int binlog_show_create_table(THD *thd, TABLE *table,
create_info, WITH_DB_NAME);
DBUG_ASSERT(result == 0); /* show_create_table() always return 0 */
/*
NOTE: why it does show_create_table() even if !mysql_bin_log.is_open()?
Because Galera needs it even if there is no binlog.
(I assume Galera will hijack the binlog information and use it itself
if there is no binlog). That is the the only thing that makes sence
looking at the if statement... Monty
*/
if (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open())
{
int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
@ -5221,12 +5020,30 @@ bool select_create::send_eof()
is in select_insert::prepare_eof(). For that reason, we
mark the flag at this point.
*/
if (create_info->tmp_table())
if (table->s->tmp_table)
thd->transaction->stmt.mark_created_temp_table();
if (thd->slave_thread)
thd->variables.binlog_annotate_row_events= 0;
debug_crash_here("ddl_log_create_before_binlog");
/*
In case of crash, we have to add DROP TABLE to the binary log as
the CREATE TABLE will already be logged if we are not using row based
replication.
*/
if (!thd->is_current_stmt_binlog_format_row())
{
if (ddl_log_state_create.is_active()) // Not temporary table
ddl_log_update_phase(&ddl_log_state_create, DDL_CREATE_TABLE_PHASE_LOG);
/*
We can ignore if we replaced an old table as ddl_log_state_create will
now handle the logging of the drop if needed.
*/
ddl_log_complete(&ddl_log_state_rm);
}
if (prepare_eof())
{
abort_result_set();
@ -5234,7 +5051,7 @@ bool select_create::send_eof()
}
debug_crash_here("ddl_log_create_after_prepare_eof");
if (create_info->tmp_table())
if (table->s->tmp_table)
{
/*
Now is good time to add the new table to THD temporary tables list.
@ -5260,11 +5077,11 @@ bool select_create::send_eof()
tables. This can fail, but we should unlock the table
nevertheless.
*/
if (!create_info->tmp_table())
if (!table->s->tmp_table)
{
#ifdef WITH_WSREP
if (WSREP(thd) &&
create_info->db_type->db_type == DB_TYPE_INNODB)
table->file->ht->db_type == DB_TYPE_INNODB)
{
if (thd->wsrep_trx_id() == WSREP_UNDEFINED_TRX_ID)
{
@ -5299,46 +5116,15 @@ bool select_create::send_eof()
thd->get_stmt_da()->set_overwrite_status(true);
}
#endif /* WITH_WSREP */
if (atomic_replace)
{
table_list= orig_table;
create_info->table= orig_table->table;
thd->transaction->on= true;
table->file->ha_reset();
/*
Remove the temporary table structures from memory but keep the table
files.
*/
thd->drop_temporary_table(table, NULL, false);
table= NULL;
if (create_info->finalize_atomic_replace(thd, orig_table))
{
abort_result_set();
DBUG_RETURN(true);
}
}
if (binlog_query())
{
abort_result_set();
DBUG_RETURN(true);
}
debug_crash_here("ddl_log_create_after_binlog");
thd->binlog_xid= thd->query_id;
/* Remember xid's for the case of row based logging */
ddl_log_update_xid(&ddl_log_state_create, thd->binlog_xid);
ddl_log_update_xid(&ddl_log_state_rm, thd->binlog_xid);
trans_commit_stmt(thd);
if (!(thd->variables.option_bits & OPTION_GTID_BEGIN))
trans_commit_implicit(thd);
thd->binlog_xid= 0;
/*
If are using statement based replication the table will be deleted here
in case of a crash as we can't use xid to check if the query was logged
(as the query was logged before commit!)
*/
create_info->finalize_ddl(thd, false);
#ifdef WITH_WSREP
if (WSREP(thd))
{
@ -5370,22 +5156,17 @@ bool select_create::send_eof()
ddl_log.org_database= table_list->db;
ddl_log.org_table= table_list->table_name;
ddl_log.org_table_id= create_info->tabledef_version;
/*
Since atomic replace doesn't do mysql_rm_table_no_locks() we have
to log DROP entry now. It was already prepared in create_table_impl().
*/
if (create_info->drop_entry.query.length)
{
DBUG_ASSERT(atomic_replace);
backup_log_ddl(&create_info->drop_entry);
}
backup_log_ddl(&ddl_log);
}
else if (binlog_query())
{
abort_result_set();
DBUG_RETURN(true);
}
/*
If are using statement based replication the table will be deleted here
in case of a crash as we can't use xid to check if the query was logged
(as the query was logged before commit!)
*/
debug_crash_here("ddl_log_create_after_binlog");
ddl_log_complete(&ddl_log_state_rm);
ddl_log_complete(&ddl_log_state_create);
debug_crash_here("ddl_log_create_log_complete");
/*
exit_done must only be set after last potential call to
@ -5393,9 +5174,10 @@ bool select_create::send_eof()
*/
exit_done= 1; // Avoid double calls
send_ok_packet();
if (m_plock)
{
DBUG_ASSERT(!atomic_replace);
MYSQL_LOCK *lock= *m_plock;
*m_plock= NULL;
m_plock= NULL;
@ -5414,21 +5196,11 @@ bool select_create::send_eof()
create_info->
pos_in_locked_tables,
table, lock))
{
send_ok_packet();
DBUG_RETURN(false); // ok
}
/* Fail. Continue without locking the table */
thd->clear_error();
}
mysql_unlock_tables(thd, lock);
}
else if (atomic_replace && create_info->pos_in_locked_tables &&
/* send_eof() is done on success, passing false here */
create_info->finalize_locked_tables(thd, false))
DBUG_RETURN(true);
send_ok_packet();
DBUG_RETURN(false);
}
@ -5466,7 +5238,6 @@ void select_create::abort_result_set()
thd->variables.option_bits&= ~OPTION_BIN_LOG;
select_insert::abort_result_set();
thd->transaction->stmt.modified_non_trans_table= FALSE;
thd->transaction->on= true;
thd->variables.option_bits= save_option_bits;
/* possible error of writing binary log is ignored deliberately */
@ -5474,7 +5245,9 @@ void select_create::abort_result_set()
if (table)
{
bool tmp_table= create_info->tmp_table();
bool tmp_table= table->s->tmp_table;
bool table_creation_was_logged= (!tmp_table ||
table->s->table_creation_was_logged);
if (tmp_table)
{
DBUG_ASSERT(saved_tmp_table_share);
@ -5496,17 +5269,7 @@ void select_create::abort_result_set()
m_plock= NULL;
}
if (atomic_replace)
{
ulonglong save_options_bits= thd->variables.option_bits;
thd->variables.option_bits|= OPTION_NOT_AUTOCOMMIT;
(void) table->file->ha_external_lock(thd, F_UNLCK);
thd->variables.option_bits= save_options_bits;
(void) thd->drop_temporary_table(table, NULL, true);
}
else
drop_open_table(thd, table, &table_list->db,
&table_list->table_name);
drop_open_table(thd, table, &table_list->db, &table_list->table_name);
table=0; // Safety
if (thd->log_current_statement())
{
@ -5514,8 +5277,23 @@ void select_create::abort_result_set()
{
/* Remove logging of drop, create + insert rows */
binlog_reset_cache(thd);
/* Original table was deleted. We have to log it */
if (table_creation_was_logged)
{
thd->binlog_xid= thd->query_id;
ddl_log_update_xid(&ddl_log_state_create, thd->binlog_xid);
ddl_log_update_xid(&ddl_log_state_rm, thd->binlog_xid);
debug_crash_here("ddl_log_create_before_binlog");
log_drop_table(thd, &table_list->db, &table_list->table_name,
&create_info->org_storage_engine_name,
create_info->db_type == partition_hton,
&create_info->tabledef_version,
tmp_table);
debug_crash_here("ddl_log_create_after_binlog");
thd->binlog_xid= 0;
}
}
else if (!tmp_table && !atomic_replace)
else if (!tmp_table)
{
backup_log_info ddl_log;
bzero(&ddl_log, sizeof(ddl_log));
@ -5530,8 +5308,8 @@ void select_create::abort_result_set()
}
}
create_info->finalize_ddl(thd, !binary_logged);
DBUG_ASSERT(!thd->binlog_xid);
ddl_log_complete(&ddl_log_state_rm);
ddl_log_complete(&ddl_log_state_create);
if (create_info->table_was_deleted)
{
@ -5539,8 +5317,6 @@ void select_create::abort_result_set()
(void) trans_rollback_stmt(thd);
thd->locked_tables_list.unlock_locked_table(thd, create_info->mdl_ticket);
}
else if (atomic_replace && create_info->pos_in_locked_tables)
/* abort_result_set() is done on error, passing true here */
(void) create_info->finalize_locked_tables(thd, true);
DBUG_VOID_RETURN;
}