diff --git a/tests/bugs/core_5845_test.py b/tests/bugs/core_5845_test.py index 74eba002..5021e5d2 100644 --- a/tests/bugs/core_5845_test.py +++ b/tests/bugs/core_5845_test.py @@ -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