summaryrefslogtreecommitdiff
path: root/innobase/trx
diff options
context:
space:
mode:
authorunknown <heikki@hundin.mysql.fi>2004-10-09 14:13:40 +0300
committerunknown <heikki@hundin.mysql.fi>2004-10-09 14:13:40 +0300
commit2763d893ea81632b9320ec66258f46e5c380b3b8 (patch)
treeefb385e447fbb66237a536d151271edc437f1ed2 /innobase/trx
parente98bd143a74d6f6743c15b3f5ba866c09558f8c9 (diff)
downloadmariadb-git-2763d893ea81632b9320ec66258f46e5c380b3b8.tar.gz
trx0rec.c:
Fix bug #5960: if one updated a column so that its size changed, or updated it to an externally stored (TEXT or BLOB) value, then ANOTHER externally stored column would show up as 512 bytes of good data + 20 bytes of garbage in a consistent read that fetched the old version of the row innobase/trx/trx0rec.c: Fix bug #5960: if one updated a column so that its size changed, or updated it to an externally stored (TEXT or BLOB) value, then ANOTHER externally stored column would show up as 512 bytes of good data + 20 bytes of garbage in a consistent read that fetched the old version of the row
Diffstat (limited to 'innobase/trx')
-rw-r--r--innobase/trx/trx0rec.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/innobase/trx/trx0rec.c b/innobase/trx/trx0rec.c
index 79fad312e8e..0e1842ef4a0 100644
--- a/innobase/trx/trx0rec.c
+++ b/innobase/trx/trx0rec.c
@@ -1257,7 +1257,7 @@ trx_undo_prev_version_build(
ibool dummy_extern;
byte* buf;
ulint err;
- ulint i;
+
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
#endif /* UNIV_SYNC_DEBUG */
@@ -1367,7 +1367,18 @@ trx_undo_prev_version_build(
}
if (row_upd_changes_field_size_or_external(rec, index, update)) {
-
+ ulint* ext_vect;
+ ulint n_ext_vect;
+
+ /* We have to set the appropriate extern storage bits in the
+ old version of the record: the extern bits in rec for those
+ fields that update does NOT update, as well as the the bits for
+ those fields that update updates to become externally stored
+ fields. Store the info to ext_vect: */
+
+ ext_vect = mem_alloc(sizeof(ulint) * rec_get_n_fields(rec));
+ n_ext_vect = btr_push_update_extern_fields(ext_vect, rec,
+ update);
entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec,
heap);
row_upd_index_replace_new_col_vals(entry, index, update, heap);
@@ -1375,6 +1386,11 @@ trx_undo_prev_version_build(
buf = mem_heap_alloc(heap, rec_get_converted_size(entry));
*old_vers = rec_convert_dtuple_to_rec(buf, entry);
+
+ /* Now set the extern bits in the old version of the record */
+ rec_set_field_extern_bits(*old_vers, ext_vect, n_ext_vect,
+ NULL);
+ mem_free(ext_vect);
} else {
buf = mem_heap_alloc(heap, rec_get_size(rec));
@@ -1383,15 +1399,5 @@ trx_undo_prev_version_build(
row_upd_rec_in_place(*old_vers, update);
}
- for (i = 0; i < upd_get_n_fields(update); i++) {
-
- if (upd_get_nth_field(update, i)->extern_storage) {
-
- rec_set_nth_field_extern_bit(*old_vers,
- upd_get_nth_field(update, i)->field_no,
- TRUE, NULL);
- }
- }
-
return(DB_SUCCESS);
}