Bug #27395 OPTION_STATUS_NO_TRANS_UPDATE is not preserved at the end of SF()
thd->options' OPTION_STATUS_NO_TRANS_UPDATE bit was not restored at the end of SF() invocation, where SF() modified non-ta table. As the result of this artifact it was not possible to detect whether there were any side-effects when top-level query ends. If the top level query table was not modified and the bit is lost there would be no binlogging. Fixed with preserving the bit inside of thd->no_trans_update struct. The struct agregates two bool flags telling whether the current query and the current transaction modified any non-ta table. The flags stmt, all are dropped at the end of the query and the transaction.
This commit is contained in:
parent
0114c0a733
commit
2afa90b5c5
@ -530,3 +530,35 @@ count(*)
|
|||||||
drop table t3, t4|
|
drop table t3, t4|
|
||||||
drop procedure bug14210|
|
drop procedure bug14210|
|
||||||
set @@session.max_heap_table_size=default|
|
set @@session.max_heap_table_size=default|
|
||||||
|
drop function if exists bug23333|
|
||||||
|
drop table if exists t1,t2|
|
||||||
|
CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM|
|
||||||
|
CREATE TABLE t2 (a int NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB|
|
||||||
|
reset master|
|
||||||
|
insert into t2 values (1,1)|
|
||||||
|
create function bug23333()
|
||||||
|
RETURNS int(11)
|
||||||
|
DETERMINISTIC
|
||||||
|
begin
|
||||||
|
insert into t1 values (null);
|
||||||
|
select count(*) from t1 into @a;
|
||||||
|
return @a;
|
||||||
|
end|
|
||||||
|
insert into t2 values (bug23333(),1)|
|
||||||
|
ERROR 23000: Duplicate entry '1' for key 1
|
||||||
|
show binlog events /* must show the insert */|
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 4 Format_desc 1 98 Server ver: 5.0.40-debug-log, Binlog ver: 4
|
||||||
|
master-bin.000001 98 Query 1 90 use `test`; insert into t2 values (1,1)
|
||||||
|
master-bin.000001 188 Xid 1 215 COMMIT /* xid=1165 */
|
||||||
|
master-bin.000001 215 Query 1 446 use `test`; CREATE DEFINER=`root`@`localhost` function bug23333()
|
||||||
|
RETURNS int(11)
|
||||||
|
DETERMINISTIC
|
||||||
|
begin
|
||||||
|
insert into t1 values (null);
|
||||||
|
select count(*) from t1 into @a;
|
||||||
|
return @a;
|
||||||
|
end
|
||||||
|
select count(*),@a from t1 /* must be 1,1 */|
|
||||||
|
count(*) @a
|
||||||
|
1 1
|
||||||
|
@ -553,6 +553,36 @@ drop procedure bug14210|
|
|||||||
set @@session.max_heap_table_size=default|
|
set @@session.max_heap_table_size=default|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #13270 INSERT,UPDATE,etc that calls func with side-effect does not binlog
|
||||||
|
# Bug #23333 stored function + non-transac table + transac table =
|
||||||
|
# breaks stmt-based binlog
|
||||||
|
# Bug #27395 OPTION_STATUS_NO_TRANS_UPDATE is not preserved at the end of SF()
|
||||||
|
#
|
||||||
|
--disable_warnings
|
||||||
|
drop function if exists bug23333|
|
||||||
|
drop table if exists t1,t2|
|
||||||
|
--enable_warnings
|
||||||
|
CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM|
|
||||||
|
CREATE TABLE t2 (a int NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB|
|
||||||
|
|
||||||
|
reset master|
|
||||||
|
insert into t2 values (1,1)|
|
||||||
|
|
||||||
|
create function bug23333()
|
||||||
|
RETURNS int(11)
|
||||||
|
DETERMINISTIC
|
||||||
|
begin
|
||||||
|
insert into t1 values (null);
|
||||||
|
select count(*) from t1 into @a;
|
||||||
|
return @a;
|
||||||
|
end|
|
||||||
|
|
||||||
|
--error ER_DUP_ENTRY
|
||||||
|
insert into t2 values (bug23333(),1)|
|
||||||
|
show binlog events /* must show the insert */|
|
||||||
|
select count(*),@a from t1 /* must be 1,1 */|
|
||||||
|
|
||||||
#
|
#
|
||||||
# BUG#NNNN: New bug synopsis
|
# BUG#NNNN: New bug synopsis
|
||||||
#
|
#
|
||||||
|
@ -3636,8 +3636,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
|
|||||||
{
|
{
|
||||||
m_transaction_on= FALSE;
|
m_transaction_on= FALSE;
|
||||||
/* Would be simpler if has_transactions() didn't always say "yes" */
|
/* Would be simpler if has_transactions() didn't always say "yes" */
|
||||||
thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
|
thd->no_trans_update= {TRUE, TRUE};
|
||||||
thd->no_trans_update= TRUE;
|
|
||||||
}
|
}
|
||||||
else if (!thd->transaction.on)
|
else if (!thd->transaction.on)
|
||||||
m_transaction_on= FALSE;
|
m_transaction_on= FALSE;
|
||||||
|
@ -830,7 +830,7 @@ int ha_rollback_trans(THD *thd, bool all)
|
|||||||
the error log; but we don't want users to wonder why they have this
|
the error log; but we don't want users to wonder why they have this
|
||||||
message in the error log, so we don't send it.
|
message in the error log, so we don't send it.
|
||||||
*/
|
*/
|
||||||
if (is_real_trans && (thd->options & OPTION_STATUS_NO_TRANS_UPDATE) &&
|
if (is_real_trans && thd->no_trans_update.all &&
|
||||||
!thd->slave_thread)
|
!thd->slave_thread)
|
||||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
ER_WARNING_NOT_COMPLETE_ROLLBACK,
|
ER_WARNING_NOT_COMPLETE_ROLLBACK,
|
||||||
|
@ -162,7 +162,7 @@ static int binlog_rollback(THD *thd, bool all)
|
|||||||
table. Such cases should be rare (updating a
|
table. Such cases should be rare (updating a
|
||||||
non-transactional table inside a transaction...)
|
non-transactional table inside a transaction...)
|
||||||
*/
|
*/
|
||||||
if (unlikely(thd->options & OPTION_STATUS_NO_TRANS_UPDATE))
|
if (unlikely(thd->no_trans_update.all))
|
||||||
{
|
{
|
||||||
Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE);
|
Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE);
|
||||||
qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
|
qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
|
||||||
@ -217,7 +217,7 @@ static int binlog_savepoint_rollback(THD *thd, void *sv)
|
|||||||
non-transactional table. Otherwise, truncate the binlog cache starting
|
non-transactional table. Otherwise, truncate the binlog cache starting
|
||||||
from the SAVEPOINT command.
|
from the SAVEPOINT command.
|
||||||
*/
|
*/
|
||||||
if (unlikely(thd->options & OPTION_STATUS_NO_TRANS_UPDATE))
|
if (unlikely(thd->no_trans_update.all))
|
||||||
{
|
{
|
||||||
Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE, FALSE);
|
Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE, FALSE);
|
||||||
DBUG_RETURN(mysql_bin_log.write(&qinfo));
|
DBUG_RETURN(mysql_bin_log.write(&qinfo));
|
||||||
|
@ -2873,14 +2873,15 @@ static bool set_option_autocommit(THD *thd, set_var *var)
|
|||||||
if ((org_options & OPTION_NOT_AUTOCOMMIT))
|
if ((org_options & OPTION_NOT_AUTOCOMMIT))
|
||||||
{
|
{
|
||||||
/* We changed to auto_commit mode */
|
/* We changed to auto_commit mode */
|
||||||
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
|
thd->options&= ~(ulong) OPTION_BEGIN;
|
||||||
|
thd->no_trans_update.all= FALSE;
|
||||||
thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
|
thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
|
||||||
if (ha_commit(thd))
|
if (ha_commit(thd))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
thd->options&= ~(ulong) (OPTION_STATUS_NO_TRANS_UPDATE);
|
thd->no_trans_update.all= FALSE;
|
||||||
thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
|
thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -337,13 +337,13 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
|
|||||||
|
|
||||||
enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
|
enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
|
||||||
bool save_abort_on_warning= thd->abort_on_warning;
|
bool save_abort_on_warning= thd->abort_on_warning;
|
||||||
bool save_no_trans_update= thd->no_trans_update;
|
bool save_no_trans_update_stmt= thd->no_trans_update.stmt;
|
||||||
|
|
||||||
thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
|
thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
|
||||||
thd->abort_on_warning=
|
thd->abort_on_warning=
|
||||||
thd->variables.sql_mode &
|
thd->variables.sql_mode &
|
||||||
(MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES);
|
(MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES);
|
||||||
thd->no_trans_update= 0;
|
thd->no_trans_update.stmt= FALSE;
|
||||||
|
|
||||||
/* Save the value in the field. Convert the value if needed. */
|
/* Save the value in the field. Convert the value if needed. */
|
||||||
|
|
||||||
@ -351,7 +351,7 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
|
|||||||
|
|
||||||
thd->count_cuted_fields= save_count_cuted_fields;
|
thd->count_cuted_fields= save_count_cuted_fields;
|
||||||
thd->abort_on_warning= save_abort_on_warning;
|
thd->abort_on_warning= save_abort_on_warning;
|
||||||
thd->no_trans_update= save_no_trans_update;
|
thd->no_trans_update.stmt= save_no_trans_update_stmt;
|
||||||
|
|
||||||
if (thd->net.report_error)
|
if (thd->net.report_error)
|
||||||
{
|
{
|
||||||
|
@ -1440,7 +1440,11 @@ public:
|
|||||||
bool charset_is_system_charset, charset_is_collation_connection;
|
bool charset_is_system_charset, charset_is_collation_connection;
|
||||||
bool charset_is_character_set_filesystem;
|
bool charset_is_character_set_filesystem;
|
||||||
bool enable_slow_log; /* enable slow log for current statement */
|
bool enable_slow_log; /* enable slow log for current statement */
|
||||||
bool no_trans_update, abort_on_warning;
|
struct {
|
||||||
|
bool all:1;
|
||||||
|
bool stmt:1;
|
||||||
|
} no_trans_update;
|
||||||
|
bool abort_on_warning;
|
||||||
bool got_warning; /* Set on call to push_warning() */
|
bool got_warning; /* Set on call to push_warning() */
|
||||||
bool no_warnings_for_error; /* no warnings on call to my_error() */
|
bool no_warnings_for_error; /* no warnings on call to my_error() */
|
||||||
/* set during loop of derived table processing */
|
/* set during loop of derived table processing */
|
||||||
@ -1664,7 +1668,7 @@ public:
|
|||||||
inline bool really_abort_on_warning()
|
inline bool really_abort_on_warning()
|
||||||
{
|
{
|
||||||
return (abort_on_warning &&
|
return (abort_on_warning &&
|
||||||
(!no_trans_update ||
|
(!no_trans_update.stmt ||
|
||||||
(variables.sql_mode & MODE_STRICT_ALL_TABLES)));
|
(variables.sql_mode & MODE_STRICT_ALL_TABLES)));
|
||||||
}
|
}
|
||||||
void set_status_var_init();
|
void set_status_var_init();
|
||||||
|
@ -311,7 +311,7 @@ cleanup:
|
|||||||
error=1;
|
error=1;
|
||||||
}
|
}
|
||||||
if (!transactional_table)
|
if (!transactional_table)
|
||||||
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
thd->no_trans_update.all= TRUE;
|
||||||
}
|
}
|
||||||
free_underlaid_joins(thd, select_lex);
|
free_underlaid_joins(thd, select_lex);
|
||||||
if (transactional_table)
|
if (transactional_table)
|
||||||
@ -791,7 +791,7 @@ bool multi_delete::send_eof()
|
|||||||
local_error=1; // Log write failed: roll back the SQL statement
|
local_error=1; // Log write failed: roll back the SQL statement
|
||||||
}
|
}
|
||||||
if (!transactional_tables)
|
if (!transactional_tables)
|
||||||
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
thd->no_trans_update.all= TRUE;
|
||||||
}
|
}
|
||||||
/* Commit or rollback the current SQL statement */
|
/* Commit or rollback the current SQL statement */
|
||||||
if (transactional_tables)
|
if (transactional_tables)
|
||||||
|
@ -584,7 +584,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
if (lock_type != TL_WRITE_DELAYED && !thd->prelocked_mode)
|
if (lock_type != TL_WRITE_DELAYED && !thd->prelocked_mode)
|
||||||
table->file->start_bulk_insert(values_list.elements);
|
table->file->start_bulk_insert(values_list.elements);
|
||||||
|
|
||||||
thd->no_trans_update= 0;
|
thd->no_trans_update.stmt= FALSE;
|
||||||
thd->abort_on_warning= (!ignore && (thd->variables.sql_mode &
|
thd->abort_on_warning= (!ignore && (thd->variables.sql_mode &
|
||||||
(MODE_STRICT_TRANS_TABLES |
|
(MODE_STRICT_TRANS_TABLES |
|
||||||
MODE_STRICT_ALL_TABLES)));
|
MODE_STRICT_ALL_TABLES)));
|
||||||
@ -731,7 +731,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
error=1;
|
error=1;
|
||||||
}
|
}
|
||||||
if (!transactional_table)
|
if (!transactional_table)
|
||||||
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
thd->no_trans_update.all= TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (transactional_table)
|
if (transactional_table)
|
||||||
@ -1129,7 +1129,7 @@ static int last_uniq_key(TABLE *table,uint keynr)
|
|||||||
then both on update triggers will work instead. Similarly both on
|
then both on update triggers will work instead. Similarly both on
|
||||||
delete triggers will be invoked if we will delete conflicting records.
|
delete triggers will be invoked if we will delete conflicting records.
|
||||||
|
|
||||||
Sets thd->no_trans_update if table which is updated didn't have
|
Sets thd->no_trans_update.stmt to TRUE if table which is updated didn't have
|
||||||
transactions.
|
transactions.
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
@ -1295,7 +1295,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
|||||||
goto err;
|
goto err;
|
||||||
info->deleted++;
|
info->deleted++;
|
||||||
if (!table->file->has_transactions())
|
if (!table->file->has_transactions())
|
||||||
thd->no_trans_update= 1;
|
thd->no_trans_update.stmt= TRUE;
|
||||||
if (table->triggers &&
|
if (table->triggers &&
|
||||||
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
|
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
|
||||||
TRG_ACTION_AFTER, TRUE))
|
TRG_ACTION_AFTER, TRUE))
|
||||||
@ -1327,7 +1327,7 @@ ok_or_after_trg_err:
|
|||||||
if (key)
|
if (key)
|
||||||
my_safe_afree(key,table->s->max_unique_length,MAX_KEY_LENGTH);
|
my_safe_afree(key,table->s->max_unique_length,MAX_KEY_LENGTH);
|
||||||
if (!table->file->has_transactions())
|
if (!table->file->has_transactions())
|
||||||
thd->no_trans_update= 1;
|
thd->no_trans_update.stmt= TRUE;
|
||||||
DBUG_RETURN(trg_error);
|
DBUG_RETURN(trg_error);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@ -2518,7 +2518,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
|||||||
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
|
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
|
||||||
table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
|
table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
|
||||||
}
|
}
|
||||||
thd->no_trans_update= 0;
|
thd->no_trans_update.stmt= FALSE;
|
||||||
thd->abort_on_warning= (!info.ignore &&
|
thd->abort_on_warning= (!info.ignore &&
|
||||||
(thd->variables.sql_mode &
|
(thd->variables.sql_mode &
|
||||||
(MODE_STRICT_TRANS_TABLES |
|
(MODE_STRICT_TRANS_TABLES |
|
||||||
@ -2676,7 +2676,7 @@ void select_insert::send_error(uint errcode,const char *err)
|
|||||||
mysql_bin_log.write(&qinfo);
|
mysql_bin_log.write(&qinfo);
|
||||||
}
|
}
|
||||||
if (!table->s->tmp_table)
|
if (!table->s->tmp_table)
|
||||||
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
thd->no_trans_update.all= TRUE;
|
||||||
}
|
}
|
||||||
if (info.copied || info.deleted || info.updated)
|
if (info.copied || info.deleted || info.updated)
|
||||||
{
|
{
|
||||||
@ -2705,7 +2705,7 @@ bool select_insert::send_eof()
|
|||||||
{
|
{
|
||||||
query_cache_invalidate3(thd, table, 1);
|
query_cache_invalidate3(thd, table, 1);
|
||||||
if (!(table->file->has_transactions() || table->s->tmp_table))
|
if (!(table->file->has_transactions() || table->s->tmp_table))
|
||||||
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
thd->no_trans_update.all= TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_insert_id)
|
if (last_insert_id)
|
||||||
@ -2931,7 +2931,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
|||||||
}
|
}
|
||||||
if (!thd->prelocked_mode)
|
if (!thd->prelocked_mode)
|
||||||
table->file->start_bulk_insert((ha_rows) 0);
|
table->file->start_bulk_insert((ha_rows) 0);
|
||||||
thd->no_trans_update= 0;
|
thd->no_trans_update.stmt= FALSE;
|
||||||
thd->abort_on_warning= (!info.ignore &&
|
thd->abort_on_warning= (!info.ignore &&
|
||||||
(thd->variables.sql_mode &
|
(thd->variables.sql_mode &
|
||||||
(MODE_STRICT_TRANS_TABLES |
|
(MODE_STRICT_TRANS_TABLES |
|
||||||
|
@ -377,7 +377,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||||||
table->file->start_bulk_insert((ha_rows) 0);
|
table->file->start_bulk_insert((ha_rows) 0);
|
||||||
table->copy_blobs=1;
|
table->copy_blobs=1;
|
||||||
|
|
||||||
thd->no_trans_update= 0;
|
thd->no_trans_update.stmt= FALSE;
|
||||||
thd->abort_on_warning= (!ignore &&
|
thd->abort_on_warning= (!ignore &&
|
||||||
(thd->variables.sql_mode &
|
(thd->variables.sql_mode &
|
||||||
(MODE_STRICT_TRANS_TABLES |
|
(MODE_STRICT_TRANS_TABLES |
|
||||||
@ -467,7 +467,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||||||
(ulong) (info.records - info.copied), (ulong) thd->cuted_fields);
|
(ulong) (info.records - info.copied), (ulong) thd->cuted_fields);
|
||||||
|
|
||||||
if (!transactional_table)
|
if (!transactional_table)
|
||||||
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
thd->no_trans_update.all= TRUE;
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
if (mysql_bin_log.is_open())
|
if (mysql_bin_log.is_open())
|
||||||
{
|
{
|
||||||
@ -531,7 +531,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||||||
Item_field *sql_field;
|
Item_field *sql_field;
|
||||||
TABLE *table= table_list->table;
|
TABLE *table= table_list->table;
|
||||||
ulonglong id;
|
ulonglong id;
|
||||||
bool no_trans_update;
|
bool no_trans_update_stmt;
|
||||||
DBUG_ENTER("read_fixed_length");
|
DBUG_ENTER("read_fixed_length");
|
||||||
|
|
||||||
id= 0;
|
id= 0;
|
||||||
@ -559,7 +559,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||||||
#ifdef HAVE_purify
|
#ifdef HAVE_purify
|
||||||
read_info.row_end[0]=0;
|
read_info.row_end[0]=0;
|
||||||
#endif
|
#endif
|
||||||
no_trans_update= !table->file->has_transactions();
|
no_trans_update_stmt= !table->file->has_transactions();
|
||||||
|
|
||||||
restore_record(table, s->default_values);
|
restore_record(table, s->default_values);
|
||||||
/*
|
/*
|
||||||
@ -627,7 +627,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||||||
|
|
||||||
if (write_record(thd, table, &info))
|
if (write_record(thd, table, &info))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
thd->no_trans_update= no_trans_update;
|
thd->no_trans_update.stmt= no_trans_update_stmt;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If auto_increment values are used, save the first one for
|
If auto_increment values are used, save the first one for
|
||||||
@ -670,12 +670,12 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||||||
TABLE *table= table_list->table;
|
TABLE *table= table_list->table;
|
||||||
uint enclosed_length;
|
uint enclosed_length;
|
||||||
ulonglong id;
|
ulonglong id;
|
||||||
bool no_trans_update;
|
bool no_trans_update_stmt;
|
||||||
DBUG_ENTER("read_sep_field");
|
DBUG_ENTER("read_sep_field");
|
||||||
|
|
||||||
enclosed_length=enclosed.length();
|
enclosed_length=enclosed.length();
|
||||||
id= 0;
|
id= 0;
|
||||||
no_trans_update= !table->file->has_transactions();
|
no_trans_update_stmt= !table->file->has_transactions();
|
||||||
|
|
||||||
for (;;it.rewind())
|
for (;;it.rewind())
|
||||||
{
|
{
|
||||||
@ -817,7 +817,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
|||||||
We don't need to reset auto-increment field since we are restoring
|
We don't need to reset auto-increment field since we are restoring
|
||||||
its default value at the beginning of each loop iteration.
|
its default value at the beginning of each loop iteration.
|
||||||
*/
|
*/
|
||||||
thd->no_trans_update= no_trans_update;
|
thd->no_trans_update.stmt= no_trans_update_stmt;
|
||||||
if (read_info.next_line()) // Skip to next line
|
if (read_info.next_line()) // Skip to next line
|
||||||
break;
|
break;
|
||||||
if (read_info.line_cuted)
|
if (read_info.line_cuted)
|
||||||
|
@ -147,7 +147,8 @@ static bool end_active_trans(THD *thd)
|
|||||||
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
||||||
if (ha_commit(thd))
|
if (ha_commit(thd))
|
||||||
error=1;
|
error=1;
|
||||||
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
|
thd->options&= ~(ulong) OPTION_BEGIN;
|
||||||
|
thd->no_trans_update.all= FALSE;
|
||||||
}
|
}
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
@ -171,8 +172,8 @@ static bool begin_trans(THD *thd)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
|
thd->no_trans_update.all= FALSE;
|
||||||
OPTION_BEGIN);
|
thd->options|= (ulong) OPTION_BEGIN;
|
||||||
thd->server_status|= SERVER_STATUS_IN_TRANS;
|
thd->server_status|= SERVER_STATUS_IN_TRANS;
|
||||||
if (lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
|
if (lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
|
||||||
error= ha_start_consistent_snapshot(thd);
|
error= ha_start_consistent_snapshot(thd);
|
||||||
@ -1463,7 +1464,8 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
|
|||||||
*/
|
*/
|
||||||
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
||||||
res= ha_commit(thd);
|
res= ha_commit(thd);
|
||||||
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
|
thd->options&= ~(ulong) OPTION_BEGIN;
|
||||||
|
thd->no_trans_update.all= FALSE;
|
||||||
break;
|
break;
|
||||||
case COMMIT_RELEASE:
|
case COMMIT_RELEASE:
|
||||||
do_release= 1; /* fall through */
|
do_release= 1; /* fall through */
|
||||||
@ -1480,7 +1482,8 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
|
|||||||
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
||||||
if (ha_rollback(thd))
|
if (ha_rollback(thd))
|
||||||
res= -1;
|
res= -1;
|
||||||
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
|
thd->options&= ~(ulong) OPTION_BEGIN;
|
||||||
|
thd->no_trans_update.all= FALSE;
|
||||||
if (!res && (completion == ROLLBACK_AND_CHAIN))
|
if (!res && (completion == ROLLBACK_AND_CHAIN))
|
||||||
res= begin_trans(thd);
|
res= begin_trans(thd);
|
||||||
break;
|
break;
|
||||||
@ -2933,7 +2936,7 @@ mysql_execute_command(THD *thd)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
|
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
|
||||||
thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
|
thd->no_trans_update.all= TRUE;
|
||||||
}
|
}
|
||||||
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
DBUG_ASSERT(first_table == all_tables && first_table != 0);
|
||||||
bool link_to_local;
|
bool link_to_local;
|
||||||
@ -3707,10 +3710,10 @@ end_with_restore_list:
|
|||||||
we silently add IF EXISTS if TEMPORARY was used.
|
we silently add IF EXISTS if TEMPORARY was used.
|
||||||
*/
|
*/
|
||||||
if (thd->slave_thread)
|
if (thd->slave_thread)
|
||||||
lex->drop_if_exists= 1;
|
lex->drop_if_exists= 1;
|
||||||
|
|
||||||
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
|
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
|
||||||
thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
|
thd->no_trans_update.all= TRUE;
|
||||||
}
|
}
|
||||||
/* DDL and binlog write order protected by LOCK_open */
|
/* DDL and binlog write order protected by LOCK_open */
|
||||||
res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
|
res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
|
||||||
@ -4296,7 +4299,7 @@ end_with_restore_list:
|
|||||||
res= TRUE; // cannot happen
|
res= TRUE; // cannot happen
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) &&
|
if (thd->no_trans_update.all &&
|
||||||
!thd->slave_thread)
|
!thd->slave_thread)
|
||||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
ER_WARNING_NOT_COMPLETE_ROLLBACK,
|
ER_WARNING_NOT_COMPLETE_ROLLBACK,
|
||||||
@ -4939,8 +4942,8 @@ create_sp_error:
|
|||||||
thd->transaction.xid_state.xa_state=XA_ACTIVE;
|
thd->transaction.xid_state.xa_state=XA_ACTIVE;
|
||||||
thd->transaction.xid_state.xid.set(thd->lex->xid);
|
thd->transaction.xid_state.xid.set(thd->lex->xid);
|
||||||
xid_cache_insert(&thd->transaction.xid_state);
|
xid_cache_insert(&thd->transaction.xid_state);
|
||||||
thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
|
thd->no_trans_update.all= FALSE;
|
||||||
OPTION_BEGIN);
|
thd->options|= (ulong) OPTION_BEGIN;
|
||||||
thd->server_status|= SERVER_STATUS_IN_TRANS;
|
thd->server_status|= SERVER_STATUS_IN_TRANS;
|
||||||
send_ok(thd);
|
send_ok(thd);
|
||||||
break;
|
break;
|
||||||
@ -5033,7 +5036,8 @@ create_sp_error:
|
|||||||
xa_state_names[thd->transaction.xid_state.xa_state]);
|
xa_state_names[thd->transaction.xid_state.xa_state]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
|
thd->options&= ~(ulong) OPTION_BEGIN;
|
||||||
|
thd->no_trans_update.all= FALSE;
|
||||||
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
||||||
xid_cache_delete(&thd->transaction.xid_state);
|
xid_cache_delete(&thd->transaction.xid_state);
|
||||||
thd->transaction.xid_state.xa_state=XA_NOTR;
|
thd->transaction.xid_state.xa_state=XA_NOTR;
|
||||||
@ -5063,7 +5067,8 @@ create_sp_error:
|
|||||||
my_error(ER_XAER_RMERR, MYF(0));
|
my_error(ER_XAER_RMERR, MYF(0));
|
||||||
else
|
else
|
||||||
send_ok(thd);
|
send_ok(thd);
|
||||||
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
|
thd->options&= ~(ulong) OPTION_BEGIN;
|
||||||
|
thd->no_trans_update.all= FALSE;
|
||||||
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
||||||
xid_cache_delete(&thd->transaction.xid_state);
|
xid_cache_delete(&thd->transaction.xid_state);
|
||||||
thd->transaction.xid_state.xa_state=XA_NOTR;
|
thd->transaction.xid_state.xa_state=XA_NOTR;
|
||||||
|
@ -3968,7 +3968,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
|
|||||||
alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
|
alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
|
||||||
|
|
||||||
/* We can abort alter table for any table type */
|
/* We can abort alter table for any table type */
|
||||||
thd->no_trans_update= 0;
|
thd->no_trans_update.stmt= FALSE;
|
||||||
thd->abort_on_warning= !ignore && test(thd->variables.sql_mode &
|
thd->abort_on_warning= !ignore && test(thd->variables.sql_mode &
|
||||||
(MODE_STRICT_TRANS_TABLES |
|
(MODE_STRICT_TRANS_TABLES |
|
||||||
MODE_STRICT_ALL_TABLES));
|
MODE_STRICT_ALL_TABLES));
|
||||||
|
@ -429,7 +429,7 @@ int mysql_update(THD *thd,
|
|||||||
query_id=thd->query_id;
|
query_id=thd->query_id;
|
||||||
|
|
||||||
transactional_table= table->file->has_transactions();
|
transactional_table= table->file->has_transactions();
|
||||||
thd->no_trans_update= 0;
|
thd->no_trans_update.stmt= FALSE;
|
||||||
thd->abort_on_warning= test(!ignore &&
|
thd->abort_on_warning= test(!ignore &&
|
||||||
(thd->variables.sql_mode &
|
(thd->variables.sql_mode &
|
||||||
(MODE_STRICT_TRANS_TABLES |
|
(MODE_STRICT_TRANS_TABLES |
|
||||||
@ -452,7 +452,7 @@ int mysql_update(THD *thd,
|
|||||||
if (fill_record_n_invoke_before_triggers(thd, fields, values, 0,
|
if (fill_record_n_invoke_before_triggers(thd, fields, values, 0,
|
||||||
table->triggers,
|
table->triggers,
|
||||||
TRG_EVENT_UPDATE))
|
TRG_EVENT_UPDATE))
|
||||||
break; /* purecov: inspected */
|
break; /* purecov: inspected */
|
||||||
|
|
||||||
found++;
|
found++;
|
||||||
|
|
||||||
@ -470,12 +470,12 @@ int mysql_update(THD *thd,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(error=table->file->update_row((byte*) table->record[1],
|
if (!(error=table->file->update_row((byte*) table->record[1],
|
||||||
(byte*) table->record[0])))
|
(byte*) table->record[0])))
|
||||||
{
|
{
|
||||||
updated++;
|
updated++;
|
||||||
thd->no_trans_update= !transactional_table;
|
thd->no_trans_update.stmt= !transactional_table;
|
||||||
|
|
||||||
if (table->triggers &&
|
if (table->triggers &&
|
||||||
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
|
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
|
||||||
TRG_ACTION_AFTER, TRUE))
|
TRG_ACTION_AFTER, TRUE))
|
||||||
@ -483,25 +483,25 @@ int mysql_update(THD *thd,
|
|||||||
error= 1;
|
error= 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!ignore || error != HA_ERR_FOUND_DUPP_KEY)
|
else if (!ignore || error != HA_ERR_FOUND_DUPP_KEY)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
If (ignore && error == HA_ERR_FOUND_DUPP_KEY) we don't have to
|
If (ignore && error == HA_ERR_FOUND_DUPP_KEY) we don't have to
|
||||||
do anything; otherwise...
|
do anything; otherwise...
|
||||||
*/
|
*/
|
||||||
if (error != HA_ERR_FOUND_DUPP_KEY)
|
if (error != HA_ERR_FOUND_DUPP_KEY)
|
||||||
thd->fatal_error(); /* Other handler errors are fatal */
|
thd->fatal_error(); /* Other handler errors are fatal */
|
||||||
table->file->print_error(error,MYF(0));
|
table->file->print_error(error,MYF(0));
|
||||||
error= 1;
|
error= 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!--limit && using_limit)
|
if (!--limit && using_limit)
|
||||||
{
|
{
|
||||||
error= -1; // Simulate end of file
|
error= -1; // Simulate end of file
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -546,7 +546,7 @@ int mysql_update(THD *thd,
|
|||||||
error=1; // Rollback update
|
error=1; // Rollback update
|
||||||
}
|
}
|
||||||
if (!transactional_table)
|
if (!transactional_table)
|
||||||
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
thd->no_trans_update.all= TRUE;
|
||||||
}
|
}
|
||||||
free_underlaid_joins(thd, select_lex);
|
free_underlaid_joins(thd, select_lex);
|
||||||
if (transactional_table)
|
if (transactional_table)
|
||||||
@ -910,7 +910,7 @@ bool mysql_multi_update(THD *thd,
|
|||||||
handle_duplicates, ignore)))
|
handle_duplicates, ignore)))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
thd->no_trans_update= 0;
|
thd->no_trans_update.stmt= FALSE;
|
||||||
thd->abort_on_warning= test(thd->variables.sql_mode &
|
thd->abort_on_warning= test(thd->variables.sql_mode &
|
||||||
(MODE_STRICT_TRANS_TABLES |
|
(MODE_STRICT_TRANS_TABLES |
|
||||||
MODE_STRICT_ALL_TABLES));
|
MODE_STRICT_ALL_TABLES));
|
||||||
@ -1224,7 +1224,7 @@ multi_update::~multi_update()
|
|||||||
delete [] copy_field;
|
delete [] copy_field;
|
||||||
thd->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting
|
thd->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting
|
||||||
if (!trans_safe)
|
if (!trans_safe)
|
||||||
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
thd->no_trans_update.all= TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1311,7 +1311,7 @@ bool multi_update::send_data(List<Item> ¬_used_values)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!table->file->has_transactions())
|
if (!table->file->has_transactions())
|
||||||
thd->no_trans_update= 1;
|
thd->no_trans_update.stmt= TRUE;
|
||||||
if (table->triggers &&
|
if (table->triggers &&
|
||||||
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
|
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
|
||||||
TRG_ACTION_AFTER, TRUE))
|
TRG_ACTION_AFTER, TRUE))
|
||||||
@ -1541,10 +1541,10 @@ bool multi_update::send_eof()
|
|||||||
Query_log_event qinfo(thd, thd->query, thd->query_length,
|
Query_log_event qinfo(thd, thd->query, thd->query_length,
|
||||||
transactional_tables, FALSE);
|
transactional_tables, FALSE);
|
||||||
if (mysql_bin_log.write(&qinfo) && trans_safe)
|
if (mysql_bin_log.write(&qinfo) && trans_safe)
|
||||||
local_error= 1; // Rollback update
|
local_error= 1; // Rollback update
|
||||||
}
|
}
|
||||||
if (!transactional_tables)
|
if (!transactional_tables)
|
||||||
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
thd->no_trans_update.all= TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transactional_tables)
|
if (transactional_tables)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user