diff --git a/sql/handler.cc b/sql/handler.cc index 76037f81ffb..c24d18e1dba 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1420,15 +1420,14 @@ int ha_commit_trans(THD *thd, bool all) { handlerton *ht= hi->ht(); if ((ht->flags & HTON_NATIVE_SYS_VERSIONING) && - thd->lex->sql_command == SQLCOM_ALTER_TABLE ? + (thd->lex->sql_command == SQLCOM_ALTER_TABLE ? hi->is_trx_tmp_read_write() : - hi->is_trx_read_write()) + hi->is_trx_read_write())) { TR_table trt(thd, true); - bool updated; - if (trt.update(updated)) + if (trt.update()) goto err; - if (updated && all) + if (all) trans_commit_stmt(thd); break; } @@ -4301,14 +4300,6 @@ bool handler::ha_commit_inplace_alter_table(TABLE *altered_table, MDL_EXCLUSIVE) || !commit); - if (commit && native_versioned()) - { - TR_table trt(ha_thd(), true); - bool updated; - if (trt.update(updated)) - return true; - } - return commit_inplace_alter_table(altered_table, ha_alter_info, commit); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3d0d93d2abd..028ee4bbfdb 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -7428,11 +7428,22 @@ static bool mysql_inplace_alter_table(THD *thd, DEBUG_SYNC(thd, "alter_table_inplace_before_commit"); THD_STAGE_INFO(thd, stage_alter_inplace_commit); - if (table->file->ha_commit_inplace_alter_table(altered_table, - ha_alter_info, - true)) { - goto rollback; + TR_table trt(thd, true); + if (table->file->native_versioned()) + { + if (trt.update()) + return true; + } + + if (table->file->ha_commit_inplace_alter_table(altered_table, + ha_alter_info, + true)) + { + goto rollback; + } + + thd->drop_temporary_table(altered_table, NULL, false); } close_all_tables_for_name(thd, table->s, @@ -7442,8 +7453,6 @@ static bool mysql_inplace_alter_table(THD *thd, NULL); table_list->table= table= NULL; - thd->drop_temporary_table(altered_table, NULL, false); - /* Replace the old .FRM with the new .FRM, but keep the old name for now. Rename to the new name (if needed) will be handled separately below. diff --git a/sql/table.cc b/sql/table.cc index c6df927f15c..e1ed9cf7a44 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -8484,22 +8484,38 @@ LEX_CSTRING *fk_option_name(enum_fk_option opt) return names + opt; } -TR_table::TR_table(THD* _thd, bool rw) : thd(_thd) +TR_table::TR_table(THD* _thd, bool rw) : + thd(_thd), open_tables_backup(NULL) { init_one_table(LEX_STRING_WITH_LEN(MYSQL_SCHEMA_NAME), LEX_STRING_WITH_LEN(TRANSACTION_REG_NAME), TRANSACTION_REG_NAME.str, rw ? TL_WRITE : TL_READ); +} + +bool TR_table::open() +{ + DBUG_ASSERT(!table); open_tables_backup= new Open_tables_backup; - if (open_tables_backup) - open_log_table(thd, this, open_tables_backup); - else + if (!open_tables_backup) + { my_error(ER_OUT_OF_RESOURCES, MYF(0)); + return true; + } + + All_tmp_tables_list *temporary_tables= thd->temporary_tables; + bool error= !open_log_table(thd, this, open_tables_backup); + thd->temporary_tables= temporary_tables; + + return error; } TR_table::~TR_table() { if (table) + { + thd->temporary_tables= NULL; close_log_table(thd, open_tables_backup); + } delete open_tables_backup; } @@ -8532,9 +8548,9 @@ enum_tx_isolation TR_table::iso_level() const return res; } -bool TR_table::update(bool &updated) +bool TR_table::update() { - if (!table) + if (!table && open()) return true; DBUG_ASSERT(table->s); @@ -8542,6 +8558,7 @@ bool TR_table::update(bool &updated) DBUG_ASSERT(hton); DBUG_ASSERT(hton->flags & HTON_NATIVE_SYS_VERSIONING); + bool updated; if ((updated= hton->vers_get_trt_data(*this))) { int error= table->file->ha_write_row(table->record[0]); @@ -8557,7 +8574,7 @@ bool TR_table::update(bool &updated) #define newx new (thd->mem_root) bool TR_table::query(ulonglong trx_id) { - if (!table) + if (!table && open()) return false; SQL_SELECT_auto select; READ_RECORD info; @@ -8587,7 +8604,7 @@ bool TR_table::query(ulonglong trx_id) bool TR_table::query(MYSQL_TIME &commit_time, bool backwards) { - if (!table) + if (!table && open()) return false; SQL_SELECT_auto select; READ_RECORD info; @@ -8684,13 +8701,13 @@ bool TR_table::query_sees(bool &result, ulonglong trx_id1, ulonglong trx_id0, return false; } -bool TR_table::check() const +bool TR_table::check() { // InnoDB may not be loaded if (!ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB)) return false; - if (!table) + if (open()) return true; if (table->file->ht->db_type != DB_TYPE_INNODB) diff --git a/sql/table.h b/sql/table.h index 58b656b68ad..a7cd29c1bd3 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2946,12 +2946,13 @@ public: FIELD_COUNT }; TR_table(THD *_thd, bool rw= false); + bool open(); ~TR_table(); THD *get_thd() const { return thd; } void store(uint field_id, ulonglong val); void store(uint field_id, timeval ts); void store_data(ulonglong trx_id, ulonglong commit_id, timeval commit_ts); - bool update(bool &updated); + bool update(); // return true if found; false if not found or error bool query(ulonglong trx_id); bool query(MYSQL_TIME &commit_time, bool backwards); @@ -2979,7 +2980,7 @@ public: DBUG_ASSERT(iso_level <= ISO_SERIALIZABLE); store(FLD_ISO_LEVEL, iso_level + 1); } - bool check() const; + bool check(); }; #endif /* MYSQL_CLIENT */ diff --git a/sql/vtmd.cc b/sql/vtmd.cc index c7a449b61cd..2a77ea93a57 100644 --- a/sql/vtmd.cc +++ b/sql/vtmd.cc @@ -258,7 +258,7 @@ quit: if (!result) { TR_table trt(thd, true); - result= trt.update(result); + result= trt.update(); } close_log_table(thd, &open_tables_backup);