diff options
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r-- | sql/sql_base.cc | 58 |
1 files changed, 28 insertions, 30 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index e5a5b51fcf6..4a417dc05b1 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1324,29 +1324,45 @@ void close_thread_tables(THD *thd) Mark all temporary tables used by this statement as free for reuse. */ mark_temp_tables_as_free_for_reuse(thd); - - if (thd->locked_tables || prelocked_mode) + /* + Let us commit transaction for statement. Since in 5.0 we only have + one statement transaction and don't allow several nested statement + transactions this call will do nothing if we are inside of stored + function or trigger (i.e. statement transaction is already active and + does not belong to statement for which we do close_thread_tables()). + TODO: This should be fixed in later releases. + */ + if (!(thd->state_flags & Open_tables_state::BACKUPS_AVAIL)) { + thd->main_da.can_overwrite_status= TRUE; + ha_autocommit_or_rollback(thd, thd->is_error()); + thd->main_da.can_overwrite_status= FALSE; + /* - Let us commit transaction for statement. Since in 5.0 we only have - one statement transaction and don't allow several nested statement - transactions this call will do nothing if we are inside of stored - function or trigger (i.e. statement transaction is already active and - does not belong to statement for which we do close_thread_tables()). - TODO: This should be fixed in later releases. + Reset transaction state, but only if we're not inside a + sub-statement of a prelocked statement. */ - ha_commit_stmt(thd); + if (! prelocked_mode || thd->lex->requires_prelocking()) + thd->transaction.stmt.reset(); + } + + if (thd->locked_tables || prelocked_mode) + { /* Ensure we are calling ha_reset() for all used tables */ mark_used_tables_as_free_for_reuse(thd, thd->open_tables); - /* We are under simple LOCK TABLES so should not do anything else. */ + /* + We are under simple LOCK TABLES or we're inside a sub-statement + of a prelocked statement, so should not do anything else. + */ if (!prelocked_mode || !thd->lex->requires_prelocking()) DBUG_VOID_RETURN; /* - We are in prelocked mode, so we have to leave it now with doing - implicit UNLOCK TABLES if need. + We are in the top-level statement of a prelocked statement, + so we have to leave the prelocked mode now with doing implicit + UNLOCK TABLES if needed. */ DBUG_PRINT("info",("thd->prelocked_mode= NON_PRELOCKED")); thd->prelocked_mode= NON_PRELOCKED; @@ -1375,19 +1391,6 @@ void close_thread_tables(THD *thd) thd->lock=0; } /* - assume handlers auto-commit (if some doesn't - transaction handling - in MySQL should be redesigned to support it; it's a big change, - and it's not worth it - better to commit explicitly only writing - transactions, read-only ones should better take care of themselves. - saves some work in 2pc too) - see also sql_parse.cc - dispatch_command() - */ - if (!(thd->state_flags & Open_tables_state::BACKUPS_AVAIL)) - bzero(&thd->transaction.stmt, sizeof(thd->transaction.stmt)); - if (!thd->active_transaction()) - thd->transaction.xid_state.xid.null(); - - /* Note that we need to hold LOCK_open while changing the open_tables list. Another thread may work on it. (See: remove_table_from_cache(), mysql_wait_completed_table()) @@ -5059,10 +5062,7 @@ int decide_logging_format(THD *thd, TABLE_LIST *tables) DBUG_PRINT("info", ("error: %d", error)); if (error) - { - ha_rollback_stmt(thd); return -1; - } /* We switch to row-based format if we are in mixed mode and one of @@ -5216,7 +5216,6 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen) table->table->query_id= thd->query_id; if (check_lock_and_start_stmt(thd, table->table, table->lock_type)) { - ha_rollback_stmt(thd); mysql_unlock_tables(thd, thd->locked_tables); thd->locked_tables= 0; thd->options&= ~(OPTION_TABLE_LOCK); @@ -5251,7 +5250,6 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen) if (!table->placeholder() && check_lock_and_start_stmt(thd, table->table, table->lock_type)) { - ha_rollback_stmt(thd); DBUG_RETURN(-1); } } |