mirror of
https://github.com/FirebirdSQL/firebird-qa.git
synced 2025-01-22 13:33:07 +01:00
Added/Updated tests\bugs\core_5845_test.py: Refactored - see notes.
This commit is contained in:
parent
100370cd21
commit
566e6fa091
@ -2,75 +2,68 @@
|
||||
|
||||
"""
|
||||
ID: issue-6106
|
||||
ISSUE: 6106
|
||||
ISSUE: https://github.com/FirebirdSQL/firebird/issues/6106
|
||||
TITLE: ORDER BY on index can cause suboptimal index choices
|
||||
DESCRIPTION:
|
||||
JIRA: CORE-5845
|
||||
FBTEST: bugs.core_5845
|
||||
NOTES:
|
||||
[12.09.2023] pzotov
|
||||
Refactored: use firebird-driver ability to show plan (instead of call ISQL), removed hard-coded index names.
|
||||
Expected result is "accumulated" by traversing through dictionary items (see 'chk_qry_map') instead of be written beforehand.
|
||||
Added several queries provided by dimitr, letter 12-sep-2023.
|
||||
|
||||
Checked on: 3.0.12.33707; 4.0.4.2986; 5.0.0.1204
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from firebird.qa import *
|
||||
|
||||
db = db_factory()
|
||||
P_KEY_IDX = "test_pk_id1_id2_id3".upper()
|
||||
SINGLE_X_IDX = "test__x_only".upper()
|
||||
COMPOUND_IDX = "test__id1_x".upper()
|
||||
|
||||
test_script = """
|
||||
init_sql = f"""
|
||||
recreate table test
|
||||
(
|
||||
id1 integer,
|
||||
id2 integer,
|
||||
id3 integer,
|
||||
id1 int,
|
||||
id2 int,
|
||||
id3 int,
|
||||
x numeric(18,2),
|
||||
constraint pk_test primary key(id1, id2, id3)
|
||||
constraint pk_test primary key(id1, id2, id3) using index {P_KEY_IDX}
|
||||
);
|
||||
create index ixa_test__x on test(x);
|
||||
create index ixa_test__id1_x on test(id1, x);
|
||||
create index {SINGLE_X_IDX} on test(x);
|
||||
create index {COMPOUND_IDX} on test(id1, x);
|
||||
commit;
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
set plan on;
|
||||
|
||||
select *
|
||||
from test t
|
||||
where t.id1=1 and t.x>0
|
||||
;
|
||||
--plan (t index (ixa_test__id1_x))
|
||||
--index ixa_test__id1_x is used
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
select * from test t
|
||||
where t.id1=1 and t.x>0
|
||||
order by t.id1, t.id2, t.id3
|
||||
;
|
||||
--plan (t order pk_test index (ixa_test__x))
|
||||
--index ixa_test__x - suboptimal
|
||||
--as you can see adding order by which consume some index (pk_test)
|
||||
--cause suboptimal choice of index (ixa_test__x)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
--if query is changed to order by not by index
|
||||
--plan sort (t index (ixa_test__id1_x))
|
||||
|
||||
select * from test t
|
||||
where
|
||||
t.id1=1
|
||||
and t.x>0
|
||||
order by t.id1+0, t.id2, t.id3
|
||||
;
|
||||
"""
|
||||
|
||||
act = isql_act('db', test_script)
|
||||
chk_qry_map = {
|
||||
"select * from test t where t.id1=1 and t.x>0" : f"PLAN (T INDEX ({COMPOUND_IDX}))"
|
||||
,"select * from test t where t.id1=1 and t.x>0 order by t.id1, t.id2, t.id3" : f"PLAN SORT (T INDEX ({COMPOUND_IDX}))"
|
||||
,"select * from test t where t.id1=1 and t.x>0 order by t.id1+0, t.id2, t.id3" : f"PLAN SORT (T INDEX ({COMPOUND_IDX}))"
|
||||
# following examples were provided by dimitr, 12-sep-2023:
|
||||
,"select * from test t where t.id1 = 1 and t.x > 0 and t.id2 = 0" : f"PLAN (T INDEX ({COMPOUND_IDX}))"
|
||||
,"select * from test t where t.id1 = 1 and t.x = 0" : f"PLAN (T INDEX ({COMPOUND_IDX}))"
|
||||
,"select * from test t where t.id1 = 1 and t.id2 = 2" : f"PLAN (T INDEX ({P_KEY_IDX}))"
|
||||
,"select * from test t where t.id1 = 1 and t.id2 = 2 and t.id3 = 3" : f"PLAN (T INDEX ({P_KEY_IDX}))"
|
||||
,"select * from test t where t.id1 = 1 and t.x = 0 and t.id2 = 0" : f"PLAN (T INDEX ({COMPOUND_IDX}))"
|
||||
}
|
||||
|
||||
expected_stdout = """
|
||||
PLAN (T INDEX (IXA_TEST__ID1_X))
|
||||
PLAN SORT (T INDEX (IXA_TEST__ID1_X))
|
||||
PLAN SORT (T INDEX (IXA_TEST__ID1_X))
|
||||
"""
|
||||
db = db_factory(init = init_sql)
|
||||
|
||||
act = python_act('db')
|
||||
|
||||
@pytest.mark.version('>=3.0.4')
|
||||
def test_1(act: Action):
|
||||
act.expected_stdout = expected_stdout
|
||||
act.execute()
|
||||
def test_1(act: Action, capsys):
|
||||
|
||||
expected_plans_lst = [ '\n'.join((k,v)) for k,v in chk_qry_map.items() ]
|
||||
with act.db.connect() as con:
|
||||
cur = con.cursor()
|
||||
for q in chk_qry_map.keys():
|
||||
ps = cur.prepare(q)
|
||||
print( q )
|
||||
print( ps.plan )
|
||||
|
||||
act.expected_stdout = '\n'.join(expected_plans_lst)
|
||||
act.stdout = capsys.readouterr().out
|
||||
assert act.clean_stdout == act.clean_expected_stdout
|
||||
|
Loading…
Reference in New Issue
Block a user