Skip to content

BUGCHECK "decompression overran buffer (179)" when WITH LOCK clause is used #8799

@ilya071294

Description

@ilya071294

FB3/4/5 are affected.

How to reproduce:
Connection 1 in isql:

  1. Create a table:
create table t1 (id integer, str1 varchar(50), str2 varchar(2000));
commit;
  1. Insert a record:
insert into t1 select 0, NULL, rpad('', 2000, uuid_to_char(gen_uuid())) from rdb$database;
commit;
  1. 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;
  1. Drop str1 field:
alter table t1 drop str1;
commit;
  1. Use WITH LOCK clause (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;
  1. 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.

Metadata

Metadata