Below is the list of changes that have just been committed into a local
5.0 repository of elkin. When elkin does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-05-15 09:40:26+03:00, aelkin@stripped
+4 -0
Bug #27417 thd->no_trans_update.stmt lost value inside of SF-exec-stack
Once had been set the flag might later got reset inside of a stored routine execution
stack.
The reason was in that there was no check if a new statement started at time of
resetting.
The artifact affects most of binlogable DML queries.
Fixed with checking thd->in_sub_stmt to know precisely about the new statement.
Couple of minor issues refined along the fix, see per-file comments.
Test is delayed till related bug#13270, bug#23333.
sql/sql_delete.cc@stripped, 2007-05-15 09:40:21+03:00,
aelkin@stripped +27 -14
correcting delete and multi-delete queries to set and reset
thd->no_trans_update.stmt
sql/sql_insert.cc@stripped, 2007-05-15 09:40:22+03:00,
aelkin@stripped +6 -3
correcting insert and insert .. select to set and reset the flag correctly
sql/sql_load.cc@stripped, 2007-05-15 09:40:22+03:00,
aelkin@stripped +4 -7
correcting load data to set and reset the flag;
eliminating a separate issue where the flag was stored and re-stored after
write_record
which can change it and the change should remain permanent.
sql/sql_update.cc@stripped, 2007-05-15 09:40:22+03:00,
aelkin@stripped +26 -18
correcting update and multi-update to set and reset the flag;
eliminating a separate issue in multi_update::do_updates where
either one of the class members trans_safe, transactional_tables was
set after the per-table loop whereas both should be calculated during
looping.
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: aelkin
# Host: dsl-hkibras-fe31f900-164.dhcp.inet.fi
# Root: /home/elkin/MySQL/TEAM/FIXES/5.0/bug27417-no_trans_update__stmt
--- 1.197/sql/sql_delete.cc 2007-04-17 16:51:56 +03:00
+++ 1.198/sql/sql_delete.cc 2007-05-15 09:40:21 +03:00
@@ -216,6 +216,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *
init_ftfuncs(thd, select_lex, 1);
thd->proc_info="updating";
+ if (!thd->in_sub_stmt)
+ thd->no_trans_update.stmt= FALSE;
+
if (table->triggers)
{
table->triggers->mark_fields_used(thd, TRG_EVENT_DELETE);
@@ -245,10 +248,13 @@ bool mysql_delete(THD *thd, TABLE_LIST *
error= 1;
break;
}
-
+
if (!(error=table->file->delete_row(table->record[0])))
{
- deleted++;
+ deleted++;
+ if (!transactional_table)
+ thd->no_trans_update.stmt= TRUE;
+
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_AFTER, FALSE))
@@ -256,11 +262,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *
error= 1;
break;
}
- if (!--limit && using_limit)
- {
- error= -1;
- break;
- }
+ if (!--limit && using_limit)
+ {
+ error= -1;
+ break;
+ }
}
else
{
@@ -579,6 +585,9 @@ multi_delete::initialize_tables(JOIN *jo
delete_while_scanning= 0;
}
}
+ if (!thd->in_sub_stmt)
+ thd->no_trans_update.stmt= FALSE;
+
walk= delete_tables;
tempfiles_ptr= tempfiles;
if (delete_while_scanning)
@@ -644,20 +653,22 @@ bool multi_delete::send_data(List<Item>
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_BEFORE, FALSE))
- DBUG_RETURN(1);
+ DBUG_RETURN(1);
table->status|= STATUS_DELETED;
if (!(error=table->file->delete_row(table->record[0])))
{
- deleted++;
+ deleted++;
+ if (!table->file->has_transactions())
+ thd->no_trans_update.stmt= TRUE;
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_AFTER, FALSE))
- DBUG_RETURN(1);
+ DBUG_RETURN(1);
}
else
{
- table->file->print_error(error,MYF(0));
- DBUG_RETURN(1);
+ table->file->print_error(error,MYF(0));
+ DBUG_RETURN(1);
}
}
else
@@ -759,10 +770,12 @@ int multi_delete::do_deletes()
}
if ((local_error=table->file->delete_row(table->record[0])))
{
- table->file->print_error(local_error,MYF(0));
- break;
+ table->file->print_error(local_error,MYF(0));
+ break;
}
deleted++;
+ if (!table->file->has_transactions())
+ thd->no_trans_update.stmt= TRUE;
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_AFTER, FALSE))
--- 1.230/sql/sql_insert.cc 2007-04-12 12:46:07 +03:00
+++ 1.231/sql/sql_insert.cc 2007-05-15 09:40:22 +03:00
@@ -629,7 +629,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
if (lock_type != TL_WRITE_DELAYED && !thd->prelocked_mode)
table->file->start_bulk_insert(values_list.elements);
- thd->no_trans_update.stmt= FALSE;
+ if (!thd->in_sub_stmt)
+ thd->no_trans_update.stmt= FALSE;
thd->abort_on_warning= (!ignore && (thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
MODE_STRICT_ALL_TABLES)));
@@ -2564,7 +2565,8 @@ select_insert::prepare(List<Item> &value
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
}
- thd->no_trans_update.stmt= FALSE;
+ if (!thd->in_sub_stmt)
+ thd->no_trans_update.stmt= FALSE;
thd->abort_on_warning= (!info.ignore &&
(thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
@@ -2978,7 +2980,8 @@ select_create::prepare(List<Item> &value
}
if (!thd->prelocked_mode)
table->file->start_bulk_insert((ha_rows) 0);
- thd->no_trans_update.stmt= FALSE;
+ if (!thd->in_sub_stmt)
+ thd->no_trans_update.stmt= FALSE;
thd->abort_on_warning= (!info.ignore &&
(thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
--- 1.113/sql/sql_load.cc 2007-05-08 03:43:16 +03:00
+++ 1.114/sql/sql_load.cc 2007-05-15 09:40:22 +03:00
@@ -377,7 +377,8 @@ bool mysql_load(THD *thd,sql_exchange *e
table->file->start_bulk_insert((ha_rows) 0);
table->copy_blobs=1;
- thd->no_trans_update.stmt= FALSE;
+ if (!thd->in_sub_stmt)
+ thd->no_trans_update.stmt= FALSE;
thd->abort_on_warning= (!ignore &&
(thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
@@ -532,7 +533,7 @@ read_fixed_length(THD *thd, COPY_INFO &i
Item_field *sql_field;
TABLE *table= table_list->table;
ulonglong id;
- bool no_trans_update_stmt, err;
+ bool err;
DBUG_ENTER("read_fixed_length");
id= 0;
@@ -560,7 +561,6 @@ read_fixed_length(THD *thd, COPY_INFO &i
#ifdef HAVE_purify
read_info.row_end[0]=0;
#endif
- no_trans_update_stmt= !table->file->has_transactions();
restore_record(table, s->default_values);
/*
@@ -628,7 +628,6 @@ read_fixed_length(THD *thd, COPY_INFO &i
table->auto_increment_field_not_null= FALSE;
if (err)
DBUG_RETURN(1);
- thd->no_trans_update.stmt= no_trans_update_stmt;
/*
If auto_increment values are used, save the first one for
@@ -671,12 +670,11 @@ read_sep_field(THD *thd, COPY_INFO &info
TABLE *table= table_list->table;
uint enclosed_length;
ulonglong id;
- bool no_trans_update_stmt, err;
+ bool err;
DBUG_ENTER("read_sep_field");
enclosed_length=enclosed.length();
id= 0;
- no_trans_update_stmt= !table->file->has_transactions();
for (;;it.rewind())
{
@@ -817,7 +815,6 @@ read_sep_field(THD *thd, COPY_INFO &info
We don't need to reset auto-increment field since we are restoring
its default value at the beginning of each loop iteration.
*/
- thd->no_trans_update.stmt= no_trans_update_stmt;
if (read_info.next_line()) // Skip to next line
break;
if (read_info.line_cuted)
--- 1.215/sql/sql_update.cc 2007-04-12 12:46:07 +03:00
+++ 1.216/sql/sql_update.cc 2007-05-15 09:40:22 +03:00
@@ -429,7 +429,8 @@ int mysql_update(THD *thd,
query_id=thd->query_id;
transactional_table= table->file->has_transactions();
- thd->no_trans_update.stmt= FALSE;
+ if (!thd->in_sub_stmt)
+ thd->no_trans_update.stmt= FALSE;
thd->abort_on_warning= test(!ignore &&
(thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
@@ -486,7 +487,8 @@ int mysql_update(THD *thd,
(byte*) table->record[0])))
{
updated++;
- thd->no_trans_update.stmt= !transactional_table;
+ if (!transactional_table)
+ thd->no_trans_update.stmt= TRUE;
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
@@ -1484,28 +1486,28 @@ int multi_update::do_updates(bool from_s
else if (error == VIEW_CHECK_ERROR)
goto err;
}
- if ((local_error=table->file->update_row(table->record[1],
- table->record[0])))
- {
- if (!ignore || local_error != HA_ERR_FOUND_DUPP_KEY)
- goto err;
- }
- updated++;
-
+ if ((local_error=table->file->update_row(table->record[1],
+ table->record[0])))
+ {
+ if (!ignore || local_error != HA_ERR_FOUND_DUPP_KEY)
+ goto err;
+ }
+ updated++;
+ if (table->file->has_transactions())
+ transactional_tables= 1;
+ else
+ {
+ trans_safe= 0; // Can't do safe rollback
+ thd->no_trans_update.stmt= TRUE;
+ }
+
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
TRG_ACTION_AFTER, TRUE))
goto err2;
}
}
-
- if (updated != org_updated)
- {
- if (table->file->has_transactions())
- transactional_tables= 1;
- else
- trans_safe= 0; // Can't do safe rollback
- }
+ DBUG_ASSERT(updated == org_updated || transactional_tables || trans_safe == 0);
(void) table->file->ha_rnd_end();
(void) tmp_table->file->ha_rnd_end();
}
@@ -1527,7 +1529,10 @@ err2:
if (table->file->has_transactions())
transactional_tables= 1;
else
+ {
trans_safe= 0;
+ thd->no_trans_update.stmt= TRUE;
+ }
}
DBUG_RETURN(1);
}
@@ -1570,7 +1575,10 @@ bool multi_update::send_eof()
local_error= 1; // Rollback update
}
if (!transactional_tables)
+ {
+ DBUG_ASSERT(thd->no_trans_update.stmt);
thd->no_trans_update.all= TRUE;
+ }
}
if (transactional_tables)
| Thread |
|---|
| • bk commit into 5.0 tree (aelkin:1.2439) BUG#27417 | Andrei Elkin | 15 May |