2021-04-26 20:07:00 +02:00
#coding:utf-8
2022-01-25 22:55:48 +01:00
"""
ID : issue - 5394
ISSUE : 5394
TITLE : False PK / FK violation could be reported when attachment used isc_dpb_no_garbage_collect flag
DESCRIPTION :
Fix relates only such transactions that are in the state ' dead ' , see : https : / / sourceforge . net / p / firebird / code / 62965
This mean that such Tx should did sufficiently big changes _before_ inserting key into table with PK / UK .
Number of these changes should force Tx - 1 be rolled back via TIP rather than undo + commit .
Simple experiment shows that threshold is near 80 ' 000 rows being inserted into the table with single
text field of length = 50 characters . This test inserts 120 ' 000 rows for ensuring that rollback will be
done via TIP .
JIRA : CORE - 5110
2022-02-02 15:46:19 +01:00
FBTEST : bugs . core_5110
2022-01-25 22:55:48 +01:00
"""
2021-04-26 20:07:00 +02:00
import pytest
2022-01-25 22:55:48 +01:00
from firebird . qa import *
2021-12-10 19:50:31 +01:00
from firebird . driver import tpb , Isolation
2021-04-26 20:07:00 +02:00
2022-01-25 22:55:48 +01:00
init_script = """
2021-04-26 20:07:00 +02:00
recreate table test ( id int , who varchar ( 5 ) , constraint test_id_unq unique ( id ) using index test_id_unq ) ;
recreate table tbig ( s varchar ( 50 ) ) ;
2021-11-29 20:54:28 +01:00
"""
2021-04-26 20:07:00 +02:00
2022-01-25 22:55:48 +01:00
db = db_factory ( init = init_script )
2021-11-29 20:54:28 +01:00
2022-01-25 22:55:48 +01:00
act = python_act ( ' db ' )
2021-04-26 20:07:00 +02:00
2022-01-25 22:55:48 +01:00
@pytest.mark.version ( ' >=3 ' )
def test_1 ( act : Action ) :
2021-12-10 19:50:31 +01:00
custom_tpb = tpb ( isolation = Isolation . CONCURRENCY )
2022-01-25 22:55:48 +01:00
with act . db . connect ( no_gc = True ) as con :
2021-11-29 20:54:28 +01:00
tx1 = con . transaction_manager ( custom_tpb )
tx2 = con . transaction_manager ( custom_tpb )
tx1 . begin ( )
tx2 . begin ( )
cur1 = tx1 . cursor ( )
cur2 = tx2 . cursor ( )
# Test starts here, no exception should occur
# Tx-1: insert big number of rows.
cur1 . execute ( " insert into tbig(s) select rpad( ' ' , 50, uuid_to_char(gen_uuid())) from rdb$types,rdb$types,(select 1 k from rdb$types rows 2) rows 120000 " )
cur1 . execute ( " insert into test(id, who) values(1, ' Tx-1 ' ) " )
# Tx-1: rollback via TIP.
tx1 . rollback ( )
# Tx-2: insert single test record.
cur2 . execute ( " insert into test(id, who) values(1, ' Tx-2 ' ) " )
tx2 . rollback ( )