-
-
Notifications
You must be signed in to change notification settings - Fork 262
Description
FB3/4/5 are affected.
How to reproduce:
Connection 1 in isql:
- Create a table:
create table t1 (id integer, str1 varchar(50), str2 varchar(2000));
commit;
- Insert a record:
insert into t1 select 0, NULL, rpad('', 2000, uuid_to_char(gen_uuid())) from rdb$database;
commit;
- Select this record and leave the transaction active to make sure it won't be garbage-collected:
select * from t1;
Connection 2 in isql:
4. Update the record in a way that stores the current version as a delta:
update t1 set id = 1;
commit;
- Drop
str1field:
alter table t1 drop str1;
commit;
- Use
WITH LOCKclause (BUGCHECK may occur here for FB4/5):
select * from t1 with lock;
Return to connection 1:
7. Select the old record version again:
select * from t1;
- Get BUGCHECK "decompression overran buffer (179)".
What happens:
VIO_writelock creates new_rpb by copying from org_rpb which has rpb_delta flag set. new_rpb is passed to prepare_update. It creates a delta but its size exceeds the limit (1024) so the current version is stored as a regular record. The problem is that rpb_delta flag remains set for new_rpb, and then replace_record sets it in the header of the primary version. From this moment any attempt to get data of older versions fails.
The fix I would suggest: let prepare_update clear rpb_delta flag from new_rpb just before an attempt to generate a delta.
The issue #8676 looks kinda similar and the format was changed there as well but I'm not sure if it's related or not.