Transaction log blending two distinct UPDATES in a single transaction incorrectly
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Drizzle |
Fix Released
|
Undecided
|
Joe Daly |
Bug Description
The transaction log appears to be merging / blending two distinct UPDATES (against the same table) within a single transaction with bad results.
From the test case:
These two UPDATES -
UPDATE `c` SET `col_int_not_null` = 1 WHERE `col_int` BETWEEN 7 AND 108 ORDER BY `col_bigint`
UPDATE `c` SET `col_int_
End up in the transaction log like this (all changes merged into the first update / new values for the second UPDATE are attributed to col_int_not_null instead of col_int_
statement {
type: UPDATE
START_TIMESTAMP
END_TIMESTAMP
update_header {
table_metadata {
schema_name: "test"
table_name: "c"
}
key_
type: INTEGER
name: "pk"
}
set_
type: INTEGER
name: "col_int_not_null"
}
}
update_data {
segment_id: 1
end_segment: true
record {
key_value: "11"
after_value: "1"
is_null: false
}
record {
key_value: "7"
after_value: "1"
is_null: false
}
record {
key_value: "13"
after_value: "1"
is_null: false
}
############# This should be for col_int_
record {
key_value: "3"
after_value: "10"
is_null: false
}
record {
key_value: "7"
after_value: "10"
is_null: false
}
record {
key_value: "8"
after_value: "10"
is_null: false
}
record {
key_value: "9"
after_value: "10"
is_null: false
}
record {
key_value: "12"
after_value: "10"
is_null: false
}
}
}
Related branches
- Drizzle Merge Team: Pending requested
-
Diff: 624 lines (+565/-11)4 files modifieddrizzled/transaction_services.cc (+75/-11)
drizzled/transaction_services.h (+15/-0)
plugin/transaction_log/tests/r/transaction_log_update.result (+417/-0)
plugin/transaction_log/tests/t/transaction_log_update.test (+58/-0)
Changed in drizzle: | |
status: | New → Confirmed |
Changed in drizzle: | |
assignee: | nobody → David Shrewsbury (dshrews) |
Changed in drizzle: | |
assignee: | David Shrewsbury (dshrews) → Joe Daly (skinny.moey) |
Changed in drizzle: | |
status: | Fix Committed → Fix Released |
milestone: | none → 2010-10-11 |
status: | Fix Released → Fix Committed |
status: | Fix Committed → Fix Released |
this looks like the check in getUpdateStatem ent() here:
else :UpdateHeader &update_header= statement- >update_ header( ); header. table_metadata( ).table_ name();
{
const message:
string old_table_name= update_
string current_table_name; >getShare( )->getTableName (current_ table_name) ; table_name. compare( old_table_ name))
finalizeStatem entMessage( *statement, in_session); >getStatementMe ssage() ; >update_ data();
*next_ segment_ id= current_ data.segment_ id();
(void) in_table-
if (current_
{
statement= in_session-
}
else
{
/* carry forward the existing segment id */
const message::UpdateData ¤t_data= statement-
}
needs some improvement to check what fields are updated and call finalizeStateme ntMessage( ) if they differ between updates.