Skip to content

Commit 045cf35

Browse files
committed
Added/Updated tests\bugs\gh_8104_test.py: Checked on 6.0.0.345, 5.0.1.1395, 4.0.5.3092 (fetches in req #2 LESS than in req #1).
1 parent 751d4d8 commit 045cf35

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed

tests/bugs/gh_8104_test.py

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#coding:utf-8
2+
3+
"""
4+
ID: issue-8104
5+
ISSUE: https://github.com/FirebirdSQL/firebird/issues/8104
6+
TITLE: Inefficient evaluation of expressions like rdb$db_key <= ? after mass delete
7+
DESCRIPTION:
8+
NOTES:
9+
[08.05.2024] pzotov
10+
Confirmed problem on 6.0.0.344, 5.0.1.1394, 4.0.5.3091 (request #1: 47643; request #2: 115943).
11+
Checked on 6.0.0.345, 5.0.1.1395, 4.0.5.3092 (fetches in req #2 LESS than in req #1).
12+
"""
13+
14+
import pytest
15+
from firebird.qa import *
16+
17+
TAB_NAME = 'T1'.upper()
18+
ROWS_CNT = 100000
19+
20+
init_sql = f"""
21+
create table {TAB_NAME} (
22+
id int not null,
23+
val varchar(256)
24+
);
25+
commit;
26+
27+
-- fill with some data
28+
set term ^;
29+
execute block as
30+
declare n int = 0;
31+
declare s varchar(36);
32+
begin
33+
while (n < {ROWS_CNT}) do
34+
begin
35+
n = n + 1;
36+
s = uuid_to_char(gen_uuid());
37+
insert into {TAB_NAME} (id, val) values (:n, lpad('', 256, :s));
38+
end
39+
end
40+
^
41+
set term ;^
42+
commit;
43+
"""
44+
45+
db = db_factory(init = init_sql)
46+
act = python_act('db')
47+
48+
@pytest.mark.version('>=4.0.5')
49+
def test_1(act: Action, capsys):
50+
51+
get_last_pp_for_table = f"""
52+
select p.rdb$relation_id, p.rdb$page_sequence
53+
from rdb$pages p join rdb$relations r on p.rdb$relation_id = r.rdb$relation_id
54+
where r.rdb$relation_name = '{TAB_NAME}' and p.rdb$page_type = 4
55+
order by 2 desc
56+
rows 1
57+
"""
58+
rel_id, max_pp = -1, -1
59+
with act.db.connect(no_gc = True) as con:
60+
cur = con.cursor()
61+
cur.execute(get_last_pp_for_table)
62+
for r in cur:
63+
rel_id, max_pp = r[:2]
64+
assert rel_id > 0 and max_pp > 0
65+
#--------------------------------
66+
67+
# Subsequent number of PP that we want to check ('20' in the ticket):
68+
##########
69+
chk_pp = 0
70+
##########
71+
72+
read_records_for_chk_pp = f"""
73+
select count(*), min(id), max(id)
74+
from t1
75+
where
76+
rdb$db_key >= make_dbkey({rel_id}, 0, 0, {chk_pp})
77+
and rdb$db_key < make_dbkey({rel_id}, 0, 0, {chk_pp+1})
78+
"""
79+
80+
fetches_ini = con.info.fetches
81+
# read records from selected PP only -- FIRST TIME
82+
cur.execute(read_records_for_chk_pp)
83+
cur.fetchall()
84+
fetches_1 = con.info.fetches - fetches_ini
85+
86+
#----------------------------------
87+
88+
# delete records from selected PP and up to the end
89+
del_rows_starting_from_chk_pp = f"""
90+
delete from t1
91+
where rdb$db_key >= make_dbkey({rel_id}, 0, 0, {chk_pp})
92+
"""
93+
con.execute_immediate(del_rows_starting_from_chk_pp)
94+
95+
#----------------------------------
96+
97+
fetches_ini = con.info.fetches
98+
# read records from selected PP only -- SECOND TIME
99+
cur.execute(read_records_for_chk_pp)
100+
cur.fetchall()
101+
fetches_2 = con.info.fetches - fetches_ini
102+
103+
expected_msg = 'Fetches ratio expected.'
104+
105+
if fetches_2 <= fetches_1:
106+
print(expected_msg)
107+
else:
108+
print(f'Fetches ratio between 1st and 2nd requests to PP = {chk_pp} - UNEXPECTED:')
109+
print('Request #1:', fetches_1)
110+
print('Request #2:', fetches_2)
111+
112+
act.expected_stdout = f"""
113+
{expected_msg}
114+
"""
115+
act.stdout = capsys.readouterr().out
116+
assert act.clean_stdout == act.clean_expected_stdout

0 commit comments

Comments
 (0)