diff options
author | unknown <heikki@hundin.mysql.fi> | 2004-10-09 14:13:40 +0300 |
---|---|---|
committer | unknown <heikki@hundin.mysql.fi> | 2004-10-09 14:13:40 +0300 |
commit | 2763d893ea81632b9320ec66258f46e5c380b3b8 (patch) | |
tree | efb385e447fbb66237a536d151271edc437f1ed2 /innobase/trx | |
parent | e98bd143a74d6f6743c15b3f5ba866c09558f8c9 (diff) | |
download | mariadb-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.c | 30 |
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); } |