diff --git a/files/standard_sample_databases.zip b/files/standard_sample_databases.zip index 21a8e44f..b92f3e80 100644 Binary files a/files/standard_sample_databases.zip and b/files/standard_sample_databases.zip differ diff --git a/tests/bugs/gh_7904_test.py b/tests/bugs/gh_7904_test.py index 77cd52fc..824b8566 100644 --- a/tests/bugs/gh_7904_test.py +++ b/tests/bugs/gh_7904_test.py @@ -10,12 +10,16 @@ Checked on 5.0.0.1303, 6.0.0.180 (for UMOWA_ROWS = 700K number of fetches = 270208, elapsed time = 0.741s) [24.09.2024] pzotov - Changed substitutions: one need to suppress '(keys: N, total key length: M)' in FB 6.x (and ONLY there), - otherwise actual and expected output become differ. - Commit: https://github.com/FirebirdSQL/firebird/commit/c50b0aa652014ce3610a1890017c9dd436388c43 - ("Add key info to the hash join plan output", 23.09.2024 18:26) - Discussed with dimitr. - Checked on 6.0.0.467-cc183f5, 5.0.2.1513 + Changed substitutions: one need to suppress '(keys: N, total key length: M)' in FB 6.x (and ONLY there), + otherwise actual and expected output become differ. + Commit: https://github.com/FirebirdSQL/firebird/commit/c50b0aa652014ce3610a1890017c9dd436388c43 + ("Add key info to the hash join plan output", 23.09.2024 18:26) + Discussed with dimitr. + Checked on 6.0.0.467-cc183f5, 5.0.2.1513 + [06.07.2025] pzotov + Separated expected output for FB major versions prior/since 6.x. + No substitutions are used to suppress schema and quotes. Discussed with dimitr, 24.06.2025 12:39. + Checked on 6.0.0.914; 5.0.3.1668. """ import pytest @@ -241,7 +245,7 @@ def test_1(act: Action, capsys): with cur.prepare(q) as ps: print( '\n'.join([replace_leading(s) for s in ps.detailed_plan .split('\n')]) ) - expected_stdout = """ + expected_stdout_5x = """ Select Expression ....-> Aggregate ........-> Sort (record length: 132, key length: 16) @@ -261,7 +265,26 @@ def test_1(act: Action, capsys): ............................-> Table "DOK_ROZLICZENIOWY" as "Q1_DOKR" Full Scan """ + expected_stdout_6x = """ + Select Expression + ....-> Aggregate + ........-> Sort + ............-> Filter + ................-> Hash Join (inner) + ....................-> Nested Loop Join (inner) + ........................-> Filter + ............................-> Table "PUBLIC"."UMOWA" as "Q1_UMOWA" Access By ID + ................................-> Bitmap + ....................................-> Index "PUBLIC"."FK_UMOWA__RODZAJ_UMOWY" Range Scan (partial match: 1/2) + ........................-> Filter + ............................-> Table "PUBLIC"."ROZLICZENIE" as "Q1_ROZL" Access By ID + ................................-> Bitmap + ....................................-> Index "PUBLIC"."FK_ROZLICZENIE__UMOWA" Range Scan (full match) + ....................-> Record Buffer (record length: 25) + ........................-> Filter + ............................-> Table "PUBLIC"."DOK_ROZLICZENIOWY" as "Q1_DOKR" Full Scan + """ - act.expected_stdout = expected_stdout + act.expected_stdout = expected_stdout_5x if act.is_version('<6') else expected_stdout_6x act.stdout = capsys.readouterr().out assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_7921_test.py b/tests/bugs/gh_7921_test.py index aa87a133..838068a6 100644 --- a/tests/bugs/gh_7921_test.py +++ b/tests/bugs/gh_7921_test.py @@ -11,11 +11,14 @@ Checked on 5.0.1.1322 after backporting (commit fef5af38, 23.01.2024). [17.11.2024] pzotov - Query text was replaced after https://github.com/FirebirdSQL/firebird/commit/26e64e9c08f635d55ac7a111469498b3f0c7fe81 - ( Cost-based decision between ORDER and SORT plans (#8316) ): 'OPTIMIZE FOR FIRST ROWS' is used for 6.x - Suggested by dimitr, letter 16.11.2024 15:15 - - Checked on 6.0.0.532; 5.0.2.1567 + Query text was replaced after https://github.com/FirebirdSQL/firebird/commit/26e64e9c08f635d55ac7a111469498b3f0c7fe81 + ( Cost-based decision between ORDER and SORT plans (#8316) ): 'OPTIMIZE FOR FIRST ROWS' is used for 6.x + Suggested by dimitr, letter 16.11.2024 15:15 + Checked on 6.0.0.532; 5.0.2.1567 + [06.07.2025] pzotov + Separated expected output for FB major versions prior/since 6.x. + No substitutions are used to suppress schema and quotes. Discussed with dimitr, 24.06.2025 12:39. + Checked on 6.0.0.914; 5.0.3.1668. """ import pytest @@ -223,7 +226,7 @@ def test_1(act: Action, capsys): with cur.prepare(q) as ps: print( '\n'.join([replace_leading(s) for s in ps.detailed_plan .split('\n')]) ) - expected_stdout = """ + expected_stdout_5x = """ Select Expression ....-> Aggregate ........-> Filter @@ -232,7 +235,16 @@ def test_1(act: Action, capsys): ....................-> Bitmap ........................-> Index "ROZLICZENIE_FK4" Range Scan (full match) """ + expected_stdout_6x = """ + Select Expression + ....-> Aggregate + ........-> Filter + ............-> Table "PUBLIC"."ROZLICZENIE" as "Q2_ROZL" Access By ID + ................-> Index "PUBLIC"."FK_ROZLICZENIE__DYREKCJA" Full Scan + ....................-> Bitmap + ........................-> Index "PUBLIC"."ROZLICZENIE_FK4" Range Scan (full match) + """ - act.expected_stdout = expected_stdout + act.expected_stdout = expected_stdout_5x if act.is_version('<6') else expected_stdout_6x act.stdout = capsys.readouterr().out assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_7924_1_test.py b/tests/bugs/gh_7924_1_test.py index f152edb3..07aaead8 100644 --- a/tests/bugs/gh_7924_1_test.py +++ b/tests/bugs/gh_7924_1_test.py @@ -6,7 +6,10 @@ TITLE: ALTER TABLE ALTER COLUMN can not be changed properly in some cases NOTES: [22.01.2024] pzotov - Checked on 6.0.0.219 (after commit https://github.com/FirebirdSQL/firebird/commit/bcc53d43c8cd0b904d2963173c153056f9465a09) + Checked on 6.0.0.219 (after commit https://github.com/FirebirdSQL/firebird/commit/bcc53d43c8cd0b904d2963173c153056f9465a09) + [06.07.2025] pzotov + Added 'SQL_SCHEMA_PREFIX' to be substituted in expected_* on FB 6.x + Checked on 6.0.0.914. """ import pytest @@ -51,16 +54,19 @@ insert into test(f03) values ('ΔΆ'); """ -act = isql_act('db', test_script) - -expected_stdout = """ - F01 VARCHAR(10) CHARACTER SET WIN1250 COLLATE WIN_CZ_CI_AI Nullable - F02 VARCHAR(10) CHARACTER SET WIN1252 COLLATE WIN_PTBR Nullable - F03 VARCHAR(10) CHARACTER SET WIN1257 COLLATE WIN1257_EE Nullable -""" +substitutions = [('[ \t]+', ' '), (r'Table(:)?\s+\S+.*', '')] +act = isql_act('db', test_script, substitutions = substitutions) @pytest.mark.version('>=6.0') def test_1(act: Action): + + SQL_SCHEMA_PREFIX = '' if act.is_version('<6') else 'SYSTEM.' + expected_stdout = f""" + F01 VARCHAR(10) CHARACTER SET {SQL_SCHEMA_PREFIX}WIN1250 COLLATE {SQL_SCHEMA_PREFIX}WIN_CZ_CI_AI Nullable + F02 VARCHAR(10) CHARACTER SET {SQL_SCHEMA_PREFIX}WIN1252 COLLATE {SQL_SCHEMA_PREFIX}WIN_PTBR Nullable + F03 VARCHAR(10) CHARACTER SET {SQL_SCHEMA_PREFIX}WIN1257 COLLATE {SQL_SCHEMA_PREFIX}WIN1257_EE Nullable + """ + act.expected_stdout = expected_stdout act.execute(combine_output = True) assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_7924_2_test.py b/tests/bugs/gh_7924_2_test.py index 9d06a790..d169c0be 100644 --- a/tests/bugs/gh_7924_2_test.py +++ b/tests/bugs/gh_7924_2_test.py @@ -6,8 +6,11 @@ TITLE: ALTER TABLE ALTER COLUMN can not be changed properly in some cases NOTES: [22.01.2024] pzotov - Checked on 6.0.0.219 (after commit https://github.com/FirebirdSQL/firebird/commit/bcc53d43c8cd0b904d2963173c153056f9465a09) - TODO: check ability to insert into fields some data specific to appropriate collation and proper order of selected characters. + Checked on 6.0.0.219 (after commit https://github.com/FirebirdSQL/firebird/commit/bcc53d43c8cd0b904d2963173c153056f9465a09) + TODO: check ability to insert into fields some data specific to appropriate collation and proper order of selected characters. + [06.07.2025] pzotov + Added 'SQL_SCHEMA_PREFIX' to be substituted in expected_* on FB 6.x + Checked on 6.0.0.914. """ import pytest @@ -44,16 +47,19 @@ show table test; -------------------- [ 1 ] """ -act = isql_act('db', test_script) +substitutions = [('[ \t]+', ' '), (r'Table(:)?\s+\S+.*', '')] +act = isql_act('db', test_script, substitutions = substitutions) -expected_stdout = """ - F_CURR_1250 VARCHAR(10) CHARACTER SET WIN1250 COLLATE WIN_CZ_CI_AI Nullable - F_CURR_1252 VARCHAR(10) CHARACTER SET WIN1252 COLLATE WIN_PTBR Nullable - F_CURR_1257 VARCHAR(10) CHARACTER SET WIN1257 COLLATE WIN1257_EE Nullable -""" @pytest.mark.version('>=6.0') def test_1(act: Action): + + SQL_SCHEMA_PREFIX = '' if act.is_version('<6') else 'SYSTEM.' + expected_stdout = f""" + F_CURR_1250 VARCHAR(10) CHARACTER SET {SQL_SCHEMA_PREFIX}WIN1250 COLLATE {SQL_SCHEMA_PREFIX}WIN_CZ_CI_AI Nullable + F_CURR_1252 VARCHAR(10) CHARACTER SET {SQL_SCHEMA_PREFIX}WIN1252 COLLATE {SQL_SCHEMA_PREFIX}WIN_PTBR Nullable + F_CURR_1257 VARCHAR(10) CHARACTER SET {SQL_SCHEMA_PREFIX}WIN1257 COLLATE {SQL_SCHEMA_PREFIX}WIN1257_EE Nullable + """ act.expected_stdout = expected_stdout act.execute(combine_output = True) assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_7962_test.py b/tests/bugs/gh_7962_test.py index 230d5fa3..58a7a15f 100644 --- a/tests/bugs/gh_7962_test.py +++ b/tests/bugs/gh_7962_test.py @@ -6,8 +6,11 @@ TITLE: System procedure/function inconsistency between ISQL SHOW FUNCTIONS and SHOW PROCEDURES NOTES: [23.01.2024] pzotov - Confirmed on 6.0.0.219 - Checked on 6.0.0.219 after commit https://github.com/FirebirdSQL/firebird/commit/bcc53d43c8cd0b904d2963173c153056f9465a09 + Confirmed on 6.0.0.219 + Checked on 6.0.0.219 after commit https://github.com/FirebirdSQL/firebird/commit/bcc53d43c8cd0b904d2963173c153056f9465a09 + [06.07.2025] pzotov + Added 'SQL_SCHEMA_PREFIX' to be substituted in expected_* on FB 6.x + Checked on 6.0.0.914. """ import pytest @@ -34,15 +37,16 @@ act = isql_act('db', test_script) -expected_stdout = """ - STANDALONE_FN - PG_TEST.FN_USER - STANDALONE_SP - PG_TEST.SP_USER -""" - @pytest.mark.version('>=5.0.1') def test_1(act: Action): + + SQL_SCHEMA_PREFIX = '' if act.is_version('<6') else 'PUBLIC.' + expected_stdout = f""" + {SQL_SCHEMA_PREFIX}STANDALONE_FN + {SQL_SCHEMA_PREFIX}PG_TEST.FN_USER + {SQL_SCHEMA_PREFIX}STANDALONE_SP + {SQL_SCHEMA_PREFIX}PG_TEST.SP_USER + """ act.expected_stdout = expected_stdout act.execute(combine_output = True) assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_8020_test.py b/tests/bugs/gh_8020_test.py index f2b49549..9de5a9b6 100644 --- a/tests/bugs/gh_8020_test.py +++ b/tests/bugs/gh_8020_test.py @@ -7,21 +7,15 @@ DESCRIPTION: NOTES: [12.03.2024] pzotov - 1. Crash occured only when connection is done via TCP protocol. - 2. Another bug currently *remains* in FB 6.x if DROP-statements are in DSQL form, i.e are not 'enclosed' in PSQL and begin/end blocks: - ========== - Statement failed, SQLSTATE = 39000 - unsuccessful metadata update - -DROP TABLE T_FN failed - -invalid request BLR at offset 1 - -function F is not defined - ========== - See https://github.com/FirebirdSQL/firebird/issues/8021 (currently not fixed). - Because of this, it was decided to run DROP statements within PSQL code. - 3. Test checks whether MON$SERVER_PID remains the same after execution of DROP statements. In case of crash this is not so. - - Confirmed bug on 6.0.0.268 - Checked on 6.0.0.269 + 1. Crash occured only when connection is done via TCP protocol. + 2. Another bug currently *remains* in FB 6.x if DROP-statements are in DSQL form, i.e are not 'enclosed' in PSQL and begin/end blocks: + See https://github.com/FirebirdSQL/firebird/issues/8021 (currently not fixed). + Because of this, it was decided to run DROP statements within PSQL code. + 3. Test checks whether MON$SERVER_PID remains the same after execution of DROP statements. In case of crash this is not so. + Confirmed bug on 6.0.0.268. Checked on 6.0.0.269 + [06.07.2025] pzotov + Added 'SQL_SCHEMA_PREFIX' to be substituted in expected_* on FB 6.x + Checked on 6.0.0.914. """ import pytest @@ -29,15 +23,6 @@ db = db_factory() -expected_stdout = """ - IS_SERVER_PID_THE_SAME - Statement failed, SQLSTATE = 38000 - unsuccessful metadata update - -cannot delete - -Function F - -there are 1 dependencies -""" - act = python_act('db') @pytest.mark.version('>=6.0') @@ -86,6 +71,16 @@ def test_1(act: Action): commit; """ + SQL_SCHEMA_PREFIX = '' if act.is_version('<6') else '"PUBLIC".' + TEST_FUNC_NAME = 'F' if act.is_version('<6') else f'{SQL_SCHEMA_PREFIX}"F"' + expected_stdout = f""" + IS_SERVER_PID_THE_SAME + Statement failed, SQLSTATE = 38000 + unsuccessful metadata update + -cannot delete + -Function {TEST_FUNC_NAME} + -there are 1 dependencies + """ act.expected_stdout = expected_stdout act.isql(switches=['-q'], input = test_script, combine_output = True) assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_8061_addi_test.py b/tests/bugs/gh_8061_addi_test.py index c99b81ea..ded4c632 100644 --- a/tests/bugs/gh_8061_addi_test.py +++ b/tests/bugs/gh_8061_addi_test.py @@ -14,22 +14,30 @@ (paragraph "Validity of Unnesting") 2) https://jonathanlewis.wordpress.com/2007/02/26/subquery-with-or/ NOTES: - 1. One need to change config parameter SubQueryConversion to 'true' when check FB 5.x. - 2. Commits: - 6.x: - 22.03.2025 10:47 - https://github.com/FirebirdSQL/firebird/commit/fc12c0ef392fec9c83d41bc17da3dc233491498c - (Unnest IN/ANY/EXISTS subqueries and optimize them using semi-join algorithm (#8061)) - 5.x - 31.07.2024 09:46 - https://github.com/FirebirdSQL/firebird/commit/4943b3faece209caa93cc9573803677019582f1c - (Added support for semi/anti and outer joins to hash join algorithm ...) - Also: - 14.09.2024 09:24 - https://github.com/FirebirdSQL/firebird/commit/5fa4ae611d18fd4ce9aac1c8dbc79e5fea2bc1f2 - (Fix bug #8252: Incorrect subquery unnesting with complex dependencies) - - Checked on 6.0.0.735, 5.0.3.1647 + 1. One need to change config parameter SubQueryConversion to 'true' when check FB 5.x. + 2. Commits: + 6.x: + 22.03.2025 10:47 + https://github.com/FirebirdSQL/firebird/commit/fc12c0ef392fec9c83d41bc17da3dc233491498c + (Unnest IN/ANY/EXISTS subqueries and optimize them using semi-join algorithm (#8061)) + 5.x + 31.07.2024 09:46 + https://github.com/FirebirdSQL/firebird/commit/4943b3faece209caa93cc9573803677019582f1c + (Added support for semi/anti and outer joins to hash join algorithm ...) + Also: + 14.09.2024 09:24 + https://github.com/FirebirdSQL/firebird/commit/5fa4ae611d18fd4ce9aac1c8dbc79e5fea2bc1f2 + (Fix bug #8252: Incorrect subquery unnesting with complex dependencies) + + Checked on 6.0.0.735, 5.0.3.1647 + [06.07.2025] pzotov + Script 'sample-DB_-_firebird.sql' in filed/standard_sample_databases.zip has been adjusted + for applying in FB 6.x: 'ALTER CHARACTER SET ... SET DEFAULT COLLATION ' + requires explicitly specified `PUBLIC.` prefix. Execute block with if/else is used now there. + + Separated expected output for FB major versions prior/since 6.x. + No substitutions are used to suppress schema and quotes. Discussed with dimitr, 24.06.2025 12:39. + Checked on 6.0.0.914; 5.0.3.1668. """ import pytest @@ -163,7 +171,7 @@ def test_1(act: Action, tmp_sql: Path, capsys): print(line) act.reset() - act.expected_stdout = f""" + expected_stdout_5x = f""" 1000 {query_map[1000][0]} {query_map[1000][1]} @@ -221,5 +229,66 @@ def test_1(act: Action, tmp_sql: Path, capsys): ....-> Filter ........-> Table "EMPLOYEE" as "X1" Full Scan """ + + expected_stdout_6x = f""" + 1000 + {query_map[1000][0]} + {query_map[1000][1]} + Sub-query + ....-> Filter + ........-> Table "PUBLIC"."EMPLOYEE" as "X" Full Scan + Sub-query + ....-> Filter (preliminary) + ........-> Filter + ............-> Table "PUBLIC"."SALES" as "S3" Access By ID + ................-> Bitmap + ....................-> Index "PUBLIC"."SALES_CUSTOMER_FK_CUST_NO" Range Scan (full match) + Select Expression + ....-> Filter + ........-> Table "PUBLIC"."CUSTOMER" as "C3" Full Scan + + 2000 + {query_map[2000][0]} + {query_map[2000][1]} + Sub-query + ....-> Aggregate + ........-> Filter + ............-> Table "PUBLIC"."SALES" as "S3" Access By ID + ................-> Index "PUBLIC"."SALES_CUSTOMER_FK_CUST_NO" Range Scan (full match) + Select Expression + ....-> Filter + ........-> Table "PUBLIC"."CUSTOMER" as "C3" Full Scan + + 3000 + {query_map[3000][0]} + {query_map[3000][1]} + Sub-query + ....-> Union + ........-> Filter + ............-> Table "PUBLIC"."CUSTOMER" as "C1" Access By ID + ................-> Bitmap + ....................-> Index "PUBLIC"."CUSTOMER_PK" Unique Scan + ........-> Filter + ............-> Table "PUBLIC"."EMPLOYEE" as "X1" Access By ID + ................-> Bitmap + ....................-> Index "PUBLIC"."EMPLOYEE_PK" Unique Scan + Select Expression + ....-> Filter + ........-> Table "PUBLIC"."SALES" as "S1" Full Scan + + 4000 + {query_map[4000][0]} + {query_map[4000][1]} + Sub-query + ....-> Filter + ........-> Table "PUBLIC"."SALES" as "S1" Access By ID + ............-> Bitmap + ................-> Index "PUBLIC"."SALES_EMPLOYEE_FK_SALES_REP" Range Scan (full match) + Select Expression + ....-> Filter + ........-> Table "PUBLIC"."EMPLOYEE" as "X1" Full Scan + """ + + act.expected_stdout = expected_stdout_5x if act.is_version('<6') else expected_stdout_6x act.stdout = capsys.readouterr().out assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_8061_test.py b/tests/bugs/gh_8061_test.py index 8b6ee94e..b7de1bd5 100644 --- a/tests/bugs/gh_8061_test.py +++ b/tests/bugs/gh_8061_test.py @@ -12,34 +12,42 @@ Some examples for this test were taken from: https://blogs.oracle.com/optimizer/post/optimizer-transformations-subquery-unnesting-part-1 NOTES: - 1. One need to change config parameter SubQueryConversion to 'true' when check FB 5.x. - 2. Explained plan in FB 5.x has no details about keys and total key length, so we have to apply - substitution in order to ignore these data when make comparison with expected output. - 3. Commits: - 6.x: - 22.03.2025 10:47 - https://github.com/FirebirdSQL/firebird/commit/fc12c0ef392fec9c83d41bc17da3dc233491498c - (Unnest IN/ANY/EXISTS subqueries and optimize them using semi-join algorithm (#8061)) - 5.x - 31.07.2024 09:46 - https://github.com/FirebirdSQL/firebird/commit/4943b3faece209caa93cc9573803677019582f1c - (Added support for semi/anti and outer joins to hash join algorithm ...) - Also: - 14.09.2024 09:24 - https://github.com/FirebirdSQL/firebird/commit/5fa4ae611d18fd4ce9aac1c8dbc79e5fea2bc1f2 - (Fix bug #8252: Incorrect subquery unnesting with complex dependencies) - - 4. Following tests also relate to unnesting but they check only FB 5.x (and not FB 6.x): - bugs/gh_8265_test.py; // additional examples related to ability of subquery unnesting; - bugs/gh_8252_test.py; // example when unnesting must NOT be performed; - bugs/gh_8233_test.py; - bugs/gh_8231_test.py; - bugs/gh_8225_test.py; - bugs/gh_8223_test.py; - All these tests will be reimplemented soon in order to check FB 6.x also. - - Confirmed old execution plan in 6.0.0.680 (19.03.2025), it had no 'hash join (semi)' in any explanied plan. - Checked on 6.0.0.687-730aa8f (22-mar-2025), 5.0.1.1464-d1033cc (01-aug-2024). + 1. One need to change config parameter SubQueryConversion to 'true' when check FB 5.x. + 2. Explained plan in FB 5.x has no details about keys and total key length, so we have to apply + substitution in order to ignore these data when make comparison with expected output. + 3. Commits: + 6.x: + 22.03.2025 10:47 + https://github.com/FirebirdSQL/firebird/commit/fc12c0ef392fec9c83d41bc17da3dc233491498c + (Unnest IN/ANY/EXISTS subqueries and optimize them using semi-join algorithm (#8061)) + 5.x + 31.07.2024 09:46 + https://github.com/FirebirdSQL/firebird/commit/4943b3faece209caa93cc9573803677019582f1c + (Added support for semi/anti and outer joins to hash join algorithm ...) + Also: + 14.09.2024 09:24 + https://github.com/FirebirdSQL/firebird/commit/5fa4ae611d18fd4ce9aac1c8dbc79e5fea2bc1f2 + (Fix bug #8252: Incorrect subquery unnesting with complex dependencies) + + 4. Following tests also relate to unnesting but they check only FB 5.x (and not FB 6.x): + bugs/gh_8265_test.py; // additional examples related to ability of subquery unnesting; + bugs/gh_8252_test.py; // example when unnesting must NOT be performed; + bugs/gh_8233_test.py; + bugs/gh_8231_test.py; + bugs/gh_8225_test.py; + bugs/gh_8223_test.py; + All these tests will be reimplemented soon in order to check FB 6.x also. + + Confirmed old execution plan in 6.0.0.680 (19.03.2025), it had no 'hash join (semi)' in any explanied plan. + Checked on 6.0.0.687-730aa8f (22-mar-2025), 5.0.1.1464-d1033cc (01-aug-2024). + [06.07.2025] pzotov + Script 'sample-DB_-_firebird.sql' in filed/standard_sample_databases.zip has been adjusted + for applying in FB 6.x: 'ALTER CHARACTER SET ... SET DEFAULT COLLATION ' + requires explicitly specified `PUBLIC.` prefix. Execute block with if/else is used now there. + + Separated expected output for FB major versions prior/since 6.x. + No substitutions are used to suppress schema and quotes. Discussed with dimitr, 24.06.2025 12:39. + Checked on 6.0.0.914; 5.0.3.1668. """ import pytest @@ -172,7 +180,7 @@ def test_1(act: Action, tmp_sql: Path, capsys): print(line) act.reset() - act.expected_stdout = f""" + expected_stdout_5x = f""" 1000 {query_map[1000][0]} {query_map[1000][1]} @@ -226,7 +234,64 @@ def test_1(act: Action, tmp_sql: Path, capsys): ............-> Record Buffer (record length: 33) ................-> Filter ....................-> Table "SALES" as "S4" Full Scan + """ + + expected_stdout_6x = f""" + 1000 + {query_map[1000][0]} + {query_map[1000][1]} + Select Expression + ....-> Filter + ........-> Hash Join (semi) + ............-> Table "PUBLIC"."CUSTOMER" as "C1" Full Scan + ............-> Record Buffer (record length: NN) + ................-> Filter + ....................-> Table "PUBLIC"."SALES" as "S1" Full Scan + + 2000 + {query_map[2000][0]} + {query_map[2000][1]} + Select Expression + ....-> Filter + ........-> Hash Join (semi) + ............-> Table "PUBLIC"."CUSTOMER" as "C2" Full Scan + ............-> Record Buffer (record length: NN) + ................-> Filter + ....................-> Table "PUBLIC"."SALES" as "S2" Full Scan + + 3000 + {query_map[3000][0]} + {query_map[3000][1]} + Select Expression + ....-> Filter + ........-> Hash Join (semi) + ............-> Table "PUBLIC"."CUSTOMER" as "C3" Full Scan + ............-> Record Buffer (record length: NN) + ................-> Filter + ....................-> Hash Join (semi) + ........................-> Table "PUBLIC"."SALES" as "S3" Full Scan + ........................-> Record Buffer (record length: NN) + ............................-> Filter + ................................-> Table "PUBLIC"."EMPLOYEE" as "X" Full Scan + 4000 + {query_map[4000][0]} + {query_map[4000][1]} + Sub-query + ....-> Filter + ........-> Filter + ............-> Table "PUBLIC"."EMPLOYEE" as "X" Access By ID + ................-> Bitmap + ....................-> Index "PUBLIC"."EMPLOYEE_PK" Unique Scan + Select Expression + ....-> Filter + ........-> Hash Join (semi) + ............-> Table "PUBLIC"."CUSTOMER" as "C4" Full Scan + ............-> Record Buffer (record length: NN) + ................-> Filter + ....................-> Table "PUBLIC"."SALES" as "S4" Full Scan """ + + act.expected_stdout = expected_stdout_5x if act.is_version('<6') else expected_stdout_6x act.stdout = capsys.readouterr().out assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_8077_test.py b/tests/bugs/gh_8077_test.py index 3ae6a0f5..832fc67c 100644 --- a/tests/bugs/gh_8077_test.py +++ b/tests/bugs/gh_8077_test.py @@ -12,15 +12,17 @@ (Error at disconnect: / Execute statement error at attach : / 335544830 : Too many recursion levels of EXECUTE STATEMENT) NOTES: [27.05.2024] pzotov - Time of ISQL execution is limited by MAX_WAIT_FOR_ISQL_TERMINATE seconds. Currently it is ~6s for SS and ~18s for CS. - + Time of ISQL execution is limited by MAX_WAIT_FOR_ISQL_TERMINATE seconds. Currently it is ~6s for SS and ~18s for CS. [08.06.2024] pzotov - Added threshold in order to prevent infinite recursion in case of regression. - Otherwise this test can cause collapse of test machine because of infinite launch of firebird processes (in case of Classic). - See notes in the code below, variable 'STOP_RECURSIVE_ES_AFTER_ITER'. - Checked on snapshot 5.x that was not yet fixed. - - Checked on 6.0.0.362, 5.0.1.1408, 4.0.5.3103 (all SS/CS). + Added threshold in order to prevent infinite recursion in case of regression. + Otherwise this test can cause collapse of test machine because of infinite launch of firebird processes (in case of Classic). + See notes in the code below, variable 'STOP_RECURSIVE_ES_AFTER_ITER'. + Checked on snapshot 5.x that was not yet fixed. + + Checked on 6.0.0.362, 5.0.1.1408, 4.0.5.3103 (all SS/CS). + [06.07.2025] pzotov + Added 'SQL_SCHEMA_PREFIX' to be substituted in expected_* on FB 6.x + Checked on 6.0.0.914; 5.0.3.1668; 4.0.6.3214. """ import re @@ -171,6 +173,8 @@ def test_1(act: Action, tmp_sql: Path, tmp_log: Path, capsys): f.write(line[1:] + '\n') + SQL_SCHEMA_PREFIX = '' if act.is_version('<6') else '"PUBLIC".' + TRG_DETACH_NAME = "'TRG_DETACH'" if act.is_version('<6') else f'{SQL_SCHEMA_PREFIX}"TRG_DETACH"' expected_stdout = f""" rdb_trg_name TRG_ATTACH rdb_trg_type 8192 @@ -181,13 +185,13 @@ def test_1(act: Action, tmp_sql: Path, tmp_log: Path, capsys): Execute statement error at attach : 335544830 : Too many recursion levels of EXECUTE STATEMENT Data source : Firebird:: - At trigger 'TRG_DETACH' + At trigger {TRG_DETACH_NAME} Error at disconnect: Execute statement error at attach : 335544830 : Too many recursion levels of EXECUTE STATEMENT Data source : Firebird:: - At trigger 'TRG_DETACH' + At trigger {TRG_DETACH_NAME} """ with open(tmp_log, 'r') as f: diff --git a/tests/bugs/gh_8084_test.py b/tests/bugs/gh_8084_test.py index 5c6db971..1d0080cc 100644 --- a/tests/bugs/gh_8084_test.py +++ b/tests/bugs/gh_8084_test.py @@ -7,9 +7,12 @@ DESCRIPTION: NOTES: [19.04.2024] pzotov - Reduced min_version to 5.0.1 after backporting (commit #0e9ef69). - Confirmed bug on 6.0.0.315; confirmed problem noted as second case (see ticket) in 6.0.0.321 #1d96c10. - Checked on 6.0.0.325 #f5930a5, 5.0.1.1383 #0e9ef69 (intermediate snapshot) - all OK. + Reduced min_version to 5.0.1 after backporting (commit #0e9ef69). + Confirmed bug on 6.0.0.315; confirmed problem noted as second case (see ticket) in 6.0.0.321 #1d96c10. + Checked on 6.0.0.325 #f5930a5, 5.0.1.1383 #0e9ef69 (intermediate snapshot) - all OK. + [06.07.2025] pzotov + Added 'SQL_SCHEMA_PREFIX' to be substituted in expected_* on FB 6.x + Checked on 6.0.0.914; 5.0.3.1668. """ import pytest @@ -75,39 +78,41 @@ act = isql_act('db', test_script, substitutions=[('[ \t]+', ' ')]) -expected_stdout = """ - Statement failed, SQLSTATE = 23000 - attempt to store duplicate value (visible to active transactions) in unique index "TEST1_IDX_A" - -Problematic key value is ("T1_A" = 2) - Statement failed, SQLSTATE = 23000 - attempt to store duplicate value (visible to active transactions) in unique index "TEST1_IDX_A" - -Problematic key value is ("T1_A" = 1) +@pytest.mark.version('>=5.0.1') +def test_1(act: Action): - T1_A 1 - T1_A_CNT 1 + SQL_SCHEMA_PREFIX = '' if act.is_version('<6') else '"PUBLIC".' + expected_stdout = f""" + Statement failed, SQLSTATE = 23000 + attempt to store duplicate value (visible to active transactions) in unique index {SQL_SCHEMA_PREFIX}"TEST1_IDX_A" + -Problematic key value is ("T1_A" = 2) + Statement failed, SQLSTATE = 23000 + attempt to store duplicate value (visible to active transactions) in unique index {SQL_SCHEMA_PREFIX}"TEST1_IDX_A" + -Problematic key value is ("T1_A" = 1) - T1_A 2 - T1_A_CNT 1 + T1_A 1 + T1_A_CNT 1 - T2_ID 1 - T2_A 1 - T2_B 0 + T1_A 2 + T1_A_CNT 1 - T2_ID 2 - T2_A 2 - T2_B 0 + T2_ID 1 + T2_A 1 + T2_B 0 - T2_ID 3 - T2_A 1 - T2_B 0 + T2_ID 2 + T2_A 2 + T2_B 0 - T2_ID 4 - T2_A 2 - T2_B 1 -""" + T2_ID 3 + T2_A 1 + T2_B 0 + + T2_ID 4 + T2_A 2 + T2_B 1 + """ -@pytest.mark.version('>=5.0.1') -def test_1(act: Action): act.expected_stdout = expected_stdout act.execute(combine_output = True) assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_8091_test.py b/tests/bugs/gh_8091_test.py index 166e48bb..663cd2b9 100644 --- a/tests/bugs/gh_8091_test.py +++ b/tests/bugs/gh_8091_test.py @@ -15,7 +15,10 @@ Result must be the same as for iteration with default dialect = 3. NOTES: [25.10.2024] pzotov - Checked on 6.0.0.508-67d8e39 (intermediate build). + Checked on 6.0.0.508-67d8e39 (intermediate build). + [06.07.2025] pzotov + Added 'SQL_SCHEMA_PREFIX' to be substituted in expected_* on FB 6.x + Checked on 6.0.0.914; 5.0.3.1668. """ import time from io import BytesIO @@ -95,11 +98,13 @@ def test_1(act: Action, capsys): ,8 : 'select count(*) from test where z is not distinct from null and mod(id,2) = 0' ,9 : 'select count(*) from test where x-y is not distinct from null and mod(id,3) <= 1' } - nr_block = """ + + SQL_SCHEMA_PREFIX = '' if act.is_version('<6') else '"PUBLIC".' + nr_block = f""" Select Expression ....-> Aggregate ........-> Filter - ............-> Table "TEST" Full Scan + ............-> Table {SQL_SCHEMA_PREFIX}"TEST" Full Scan """ for iter in range(2): diff --git a/tests/bugs/gh_8109_test.py b/tests/bugs/gh_8109_test.py index 8608ea54..fd67ea50 100644 --- a/tests/bugs/gh_8109_test.py +++ b/tests/bugs/gh_8109_test.py @@ -7,8 +7,12 @@ DESCRIPTION: NOTES: [03.02.2025] pzotov - Confirmed problem (regression) on 6.0.0.595-2c5b146, 5.0.2.1601-f094936 - Checked on 6.0.0.601-5dee439, 5.0.2.1606-fd31e52 (intermediate snapshots). + Confirmed problem (regression) on 6.0.0.595-2c5b146, 5.0.2.1601-f094936 + Checked on 6.0.0.601-5dee439, 5.0.2.1606-fd31e52 (intermediate snapshots). + [06.07.2025] pzotov + Separated expected output for FB major versions prior/since 6.x. + No substitutions are used to suppress schema and quotes. Discussed with dimitr, 24.06.2025 12:39. + Checked on 6.0.0.914; 5.0.3.1668. """ import pytest @@ -78,7 +82,7 @@ def test_1(act: Action, capsys): ps.free() - expected_stdout = f""" + expected_stdout_5x = f""" {queries_map[ 0 ]} Select Expression ....-> Filter @@ -150,6 +154,78 @@ def test_1(act: Action, capsys): ....................-> Index "TEST_Q_DEC" Range Scan (full match) """ - act.expected_stdout = expected_stdout + expected_stdout_6x = f""" + {queries_map[ 0 ]} + Select Expression + ....-> Filter + ........-> Table "PUBLIC"."TEST" Access By ID + ............-> Bitmap Or + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_X_ASC" Range Scan (full match) + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_Y_ASC" Range Scan (full match) + + {queries_map[ 1 ]} + Select Expression + ....-> Filter + ........-> Table "PUBLIC"."TEST" Access By ID + ............-> Bitmap Or + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_U_DEC" Range Scan (full match) + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_V_DEC" Range Scan (full match) + + {queries_map[ 2 ]} + Select Expression + ....-> Filter + ........-> Table "PUBLIC"."TEST" Access By ID + ............-> Bitmap Or + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_X_ASC" Range Scan (full match) + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_U_DEC" Range Scan (full match) + + {queries_map[ 3 ]} + Select Expression + ....-> Filter + ........-> Table "PUBLIC"."TEST" Access By ID + ............-> Bitmap Or + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_V_DEC" Range Scan (full match) + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_Y_ASC" Range Scan (full match) + + {queries_map[ 4 ]} + Select Expression + ....-> Filter + ........-> Table "PUBLIC"."TEST" Access By ID + ............-> Bitmap Or + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_C_ASC" Range Scan (full match) + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_C_DEC" Range Scan (full match) + + {queries_map[ 5 ]} + Select Expression + ....-> Filter + ........-> Table "PUBLIC"."TEST" Access By ID + ............-> Bitmap Or + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_P_ASC" Range Scan (full match) + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_Q_ASC" Range Scan (full match) + + {queries_map[ 6 ]} + Select Expression + ....-> Filter + ........-> Table "PUBLIC"."TEST" Access By ID + ............-> Bitmap Or + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_P_DEC" Range Scan (full match) + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_Q_DEC" Range Scan (full match) + """ + + act.expected_stdout = expected_stdout_5x if act.is_version('<6') else expected_stdout_6x act.stdout = capsys.readouterr().out assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_8115_test.py b/tests/bugs/gh_8115_test.py index 9d57fffc..53ba627d 100644 --- a/tests/bugs/gh_8115_test.py +++ b/tests/bugs/gh_8115_test.py @@ -8,28 +8,22 @@ Original title: "FB 5.0.0.1306 - unexpected results using LEFT JOIN with When " NOTES: [16.09.2024] pzotov - Confirmed bug in 5.0.1.1369-8c31082 (17.03.2024) - Bug was fixed in 5.0.1.1369-bbd35ab (20.03.2024) - Commit: - https://github.com/FirebirdSQL/firebird/commit/bbd35ab07c129e9735f081fcd29172a8187aa8ab - Avoid reading/hashing the inner stream(s) if the leader stream is empty - Checked on 6.0.0.457, 5.0.2.1499 - - [18.01.2025] pzotov - Resultset of cursor that executes using instance of selectable PreparedStatement must be stored - in some variable in order to have ability close it EXPLICITLY (before PS will be freed). - Otherwise access violation raises during Python GC and pytest hangs at final point (does not return control to OS). - This occurs at least for: Python 3.11.2 / pytest: 7.4.4 / firebird.driver: 1.10.6 / Firebird.Qa: 0.19.3 - The reason of that was explained by Vlad, 26.10.24 17:42 ("oddities when use instances of selective statements"). - + Confirmed bug in 5.0.1.1369-8c31082 (17.03.2024) + Bug was fixed in 5.0.1.1369-bbd35ab (20.03.2024) + Commit: + https://github.com/FirebirdSQL/firebird/commit/bbd35ab07c129e9735f081fcd29172a8187aa8ab + Avoid reading/hashing the inner stream(s) if the leader stream is empty + Checked on 6.0.0.457, 5.0.2.1499 [27.03.2025] pzotov - Explained plan for 6.x became the same as for 5.x, see commit: - https://github.com/FirebirdSQL/firebird/commit/6c21404c6ef800ceb7d3bb9c97dc8249431dbc5b - Comparison of actual output must be done with single expected_out in both 5.x and 6.x. - Plan for 5.x (with TWO 'Filter' clauses) must be considered as more effective. - Disussed with dimitr, letter 16.09.2024 17:55. - - Checked on 6.0.0.698-6c21404. + Explained plan for 6.x became the same as for 5.x, see commit: + https://github.com/FirebirdSQL/firebird/commit/6c21404c6ef800ceb7d3bb9c97dc8249431dbc5b + Comparison of actual output must be done with single expected_out in both 5.x and 6.x. + Plan for 5.x (with TWO 'Filter' clauses) must be considered as more effective. + Disussed with dimitr, letter 16.09.2024 17:55. + Checked on 6.0.0.698-6c21404. + [06.07.2025] pzotov + Added 'SQL_SCHEMA_PREFIX' to be substituted in expected_* on FB 6.x + Checked on 6.0.0.914; 5.0.3.1668. """ import zipfile from pathlib import Path @@ -98,13 +92,15 @@ def test_1(act: Action, tmp_fbk: Path, capsys): if ps: ps.free() - expected_stdout = """ + + SQL_SCHEMA_PREFIX = '' if act.is_version('<6') else '"PUBLIC".' + expected_stdout = f""" Select Expression ....-> Nested Loop Join (inner) - ........-> Procedure "SAL_INPERIOADA2" as "AA" Scan + ........-> Procedure {SQL_SCHEMA_PREFIX}"SAL_INPERIOADA2" as "AA" Scan ........-> Filter ............-> Filter - ................-> Procedure "USER_CNP" as "AB" Scan + ................-> Procedure {SQL_SCHEMA_PREFIX}"USER_CNP" as "AB" Scan 000DD4E1-B4D0-4D6E-9D9F-DE9A7D0D6492 E574F734-CECB-4A8F-B9BE-FAF51BC61FAD diff --git a/tests/bugs/gh_8123_test.py b/tests/bugs/gh_8123_test.py index ac25d1e8..e4a0fc73 100644 --- a/tests/bugs/gh_8123_test.py +++ b/tests/bugs/gh_8123_test.py @@ -13,8 +13,12 @@ "SQLSTATE = 42000 / ... / -cannot delete ... / -there are 1 dependencies" NOTES: [21.05.2024] pzotov - Confirmed bug on 6.0.0.357-bf6c467 (regular daily snapshot, 18-may-2024). - Checked on intermediate snapshots 6.0.0.357-f94343e, 5.0.1.1404-88bf561. + Confirmed bug on 6.0.0.357-bf6c467 (regular daily snapshot, 18-may-2024). + Checked on intermediate snapshots 6.0.0.357-f94343e, 5.0.1.1404-88bf561. + [06.07.2025] pzotov + Separated expected output for FB major versions prior/since 6.x. + No substitutions are used to suppress schema and quotes. Discussed with dimitr, 24.06.2025 12:39. + Checked on 6.0.0.914; 5.0.3.1668. """ import pytest @@ -116,48 +120,87 @@ act = isql_act('db', test_script, substitutions=[('[ \t]+', ' ')]) -expected_stdout = """ - RDB$DEPENDED_ON_NAME TB_TEST1 - RDB$FIELD_NAME N1 - RDB$DEPENDENT_TYPE 3 - RDB$DEPENDED_ON_TYPE 0 - Records affected: 1 - - Statement failed, SQLSTATE = 42000 - unsuccessful metadata update - -cannot delete - -COLUMN TB_TEST1.N1 - -there are 1 dependencies - - - RDB$DEPENDED_ON_NAME TB_TEST2 - RDB$FIELD_NAME N1 - RDB$DEPENDENT_TYPE 3 - RDB$DEPENDED_ON_TYPE 0 - Records affected: 1 - - Statement failed, SQLSTATE = 42000 - unsuccessful metadata update - -cannot delete - -COLUMN TB_TEST2.N1 - -there are 1 dependencies - - - RDB$DEPENDED_ON_NAME TB_TEST3 - RDB$FIELD_NAME N1 - RDB$DEPENDENT_TYPE 3 - RDB$DEPENDED_ON_TYPE 0 - Records affected: 1 - - Statement failed, SQLSTATE = 42000 - unsuccessful metadata update - -cannot delete - -COLUMN TB_TEST3.N1 - -there are 1 dependencies -""" - @pytest.mark.version('>=5.0.1') def test_1(act: Action): - act.expected_stdout = expected_stdout + + expected_stdout_5x = """ + RDB$DEPENDED_ON_NAME TB_TEST1 + RDB$FIELD_NAME N1 + RDB$DEPENDENT_TYPE 3 + RDB$DEPENDED_ON_TYPE 0 + Records affected: 1 + + Statement failed, SQLSTATE = 42000 + unsuccessful metadata update + -cannot delete + -COLUMN TB_TEST1.N1 + -there are 1 dependencies + + + RDB$DEPENDED_ON_NAME TB_TEST2 + RDB$FIELD_NAME N1 + RDB$DEPENDENT_TYPE 3 + RDB$DEPENDED_ON_TYPE 0 + Records affected: 1 + + Statement failed, SQLSTATE = 42000 + unsuccessful metadata update + -cannot delete + -COLUMN TB_TEST2.N1 + -there are 1 dependencies + + + RDB$DEPENDED_ON_NAME TB_TEST3 + RDB$FIELD_NAME N1 + RDB$DEPENDENT_TYPE 3 + RDB$DEPENDED_ON_TYPE 0 + Records affected: 1 + + Statement failed, SQLSTATE = 42000 + unsuccessful metadata update + -cannot delete + -COLUMN TB_TEST3.N1 + -there are 1 dependencies + """ + + expected_stdout_6x = """ + RDB$DEPENDED_ON_NAME TB_TEST1 + RDB$FIELD_NAME N1 + RDB$DEPENDENT_TYPE 3 + RDB$DEPENDED_ON_TYPE 0 + Records affected: 1 + + Statement failed, SQLSTATE = 42000 + unsuccessful metadata update + -cannot delete + -COLUMN "PUBLIC"."TB_TEST1"."N1" + -there are 1 dependencies + + RDB$DEPENDED_ON_NAME TB_TEST2 + RDB$FIELD_NAME N1 + RDB$DEPENDENT_TYPE 3 + RDB$DEPENDED_ON_TYPE 0 + Records affected: 1 + + Statement failed, SQLSTATE = 42000 + unsuccessful metadata update + -cannot delete + -COLUMN "PUBLIC"."TB_TEST2"."N1" + -there are 1 dependencies + + RDB$DEPENDED_ON_NAME TB_TEST3 + RDB$FIELD_NAME N1 + RDB$DEPENDENT_TYPE 3 + RDB$DEPENDED_ON_TYPE 0 + Records affected: 1 + + Statement failed, SQLSTATE = 42000 + unsuccessful metadata update + -cannot delete + -COLUMN "PUBLIC"."TB_TEST3"."N1" + -there are 1 dependencies + """ + + act.expected_stdout = expected_stdout_5x if act.is_version('<6') else expected_stdout_6x act.execute(combine_output = True) assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_8203_test.py b/tests/bugs/gh_8203_test.py index 5604102c..cb374d95 100644 --- a/tests/bugs/gh_8203_test.py +++ b/tests/bugs/gh_8203_test.py @@ -26,8 +26,17 @@ err.sqlstate='2F000' NOTES: [11.08.2024] pzotov - Confirmed bug on 6.0.0.421, 5.0.1.1469 - Checked on 6.0.0.423, 5.0.2.1477 + Confirmed bug on 6.0.0.421, 5.0.1.1469 + Checked on 6.0.0.423, 5.0.2.1477 + [06.07.2025] pzotov + ::: NB ::: See doc/sql.extensions/README.schemas.md + When working with object names in ... `MAKE_DBKEY`, the names containing special characters or lowercase + letters must be enclosed in quotes ... In earlier versions, `MAKE_DBKEY` required an exact table name as + its first parameter and did not support the use of double quotes for special characters. + ---------------------------------------------------------------------------------------- + Separated expected output for FB major versions prior/since 6.x. + No substitutions are used to suppress schema and quotes. Discussed with dimitr, 24.06.2025 12:39. + Checked on 6.0.0.914; 5.0.3.1668. """ import pytest from firebird.qa import * @@ -192,22 +201,46 @@ def test_1(act: Action, capsys): for bound_points, range_name in UNICODE_RANGES_MAP.items(): for iter in range(1,REPEAT_CHECKS_FOR_SELECTED_UNICODE_RANGE+1): - table_random_unicode_name = get_random_unicode( random.randint(NAME_MIN_LEN, NAME_MAX_LEN), bound_points ) table_random_unicode_name = ''.join(c for c in table_random_unicode_name if c not in CHARS_TO_SKIP) - - test_sql = f""" - recreate table "{table_random_unicode_name.replace('"','""')}"(id int) - ^ - create or alter procedure sp_chk as - declare id1 int; - begin - select /* {range_name=} {iter=} */ id from "{table_random_unicode_name.replace('"','""')}" where rdb$db_key = make_dbkey('{table_random_unicode_name}', 0) into id1; - end - ^ - """ - # select id from "{table_random_unicode_name.replace('"','""')}" where rdb$db_key = make_dbkey('{table_random_unicode_name.replace("'","''")}', 0) into id1; + table_random_uname_quoted = table_random_unicode_name.replace('"','""') + if act.is_version('<6'): + test_sql = f""" + recreate table "{table_random_uname_quoted}"(id int) + ^ + create or alter procedure sp_chk as + declare id1 int; + begin + select /* {range_name=} {iter=} */ id + from "{table_random_uname_quoted}" + where rdb$db_key = make_dbkey('{table_random_unicode_name}', 0) + into id1; + end + ^ + """ + else: + # ::: NB ::: See doc/sql.extensions/README.schemas.md + # When working with object names in ... `MAKE_DBKEY`, the names containing special characters or lowercase + # letters must be enclosed in quotes ... In earlier versions, `MAKE_DBKEY` required an exact table name as + # its first parameter and did not support the use of double quotes for special characters. + # + test_sql = f""" + recreate table "{table_random_uname_quoted}"(id int) + ^ + create or alter procedure sp_chk as + declare id1 int; + begin + select /* {range_name=} {iter=} */ id + from "{table_random_uname_quoted}" + where rdb$db_key = make_dbkey('"{table_random_uname_quoted}"', 0) + -- | | + -- | | + -- +----- required in 6.x ----+ + into id1; + end + ^ + """ expected_txt = f'{iter=} of {REPEAT_CHECKS_FOR_SELECTED_UNICODE_RANGE=}: SUCCESS' with act.db.connect(charset = 'utf-8') as con: diff --git a/tests/bugs/gh_8223_test.py b/tests/bugs/gh_8223_test.py index b22b7a8f..bd01d74f 100644 --- a/tests/bugs/gh_8223_test.py +++ b/tests/bugs/gh_8223_test.py @@ -7,26 +7,27 @@ DESCRIPTION: NOTES: [27.08.2024] pzotov - 1. Confirmed bug on 5.0.1.1469-1d792e4 (Release (15.08.2024), got for SubQueryConversion=true: - no current record for fetch operation / gdscode = 335544348. - - 2. Parameter 'SubQueryConversion' currently presents only in FB 5.x and _NOT_ in FB 6.x. - Because of that, testing version are limited only for 5.0.2. FB 6.x currently is NOT tested. - 3. Custom driver config objects are created here, one with SubQueryConversion = true and second with false. - + 1. Confirmed bug on 5.0.1.1469-1d792e4 (Release (15.08.2024), got for SubQueryConversion=true: + no current record for fetch operation / gdscode = 335544348. + 2. Parameter 'SubQueryConversion' currently presents only in FB 5.x and _NOT_ in FB 6.x. + Because of that, testing version are limited only for 5.0.2. FB 6.x currently is NOT tested. + 3. Custom driver config objects are created here, one with SubQueryConversion = true and second with false. [18.01.2025] pzotov - Resultset of cursor that executes using instance of selectable PreparedStatement must be stored - in some variable in order to have ability close it EXPLICITLY (before PS will be freed). - Otherwise access violation raises during Python GC and pytest hangs at final point (does not return control to OS). - This occurs at least for: Python 3.11.2 / pytest: 7.4.4 / firebird.driver: 1.10.6 / Firebird.Qa: 0.19.3 - The reason of that was explained by Vlad, 26.10.24 17:42 ("oddities when use instances of selective statements"). - - Checked on 5.0.2.1483-0bf2de0 -- all ok. - Thanks to dimitr for the advice on implementing the test. - + Resultset of cursor that executes using instance of selectable PreparedStatement must be stored + in some variable in order to have ability close it EXPLICITLY (before PS will be freed). + Otherwise access violation raises during Python GC and pytest hangs at final point (does not return control to OS). + This occurs at least for: Python 3.11.2 / pytest: 7.4.4 / firebird.driver: 1.10.6 / Firebird.Qa: 0.19.3 + The reason of that was explained by Vlad, 26.10.24 17:42 ("oddities when use instances of selective statements"). + + Checked on 5.0.2.1483-0bf2de0 -- all ok. + Thanks to dimitr for the advice on implementing the test. [16.04.2025] pzotov - Re-implemented in order to check FB 5.x with set 'SubQueryConversion = true' and FB 6.x w/o any changes in its config. - Checked on 6.0.0.687-730aa8f, 5.0.3.1647-8993a57 + Re-implemented in order to check FB 5.x with set 'SubQueryConversion = true' and FB 6.x w/o any changes in its config. + Checked on 6.0.0.687-730aa8f, 5.0.3.1647-8993a57 + [06.07.2025] pzotov + Separated expected output for FB major versions prior/since 6.x. + No substitutions are used to suppress schema and quotes. Discussed with dimitr, 24.06.2025 12:39. + Checked on 6.0.0.914; 5.0.3.1668. """ import pytest @@ -129,7 +130,7 @@ def test_1(act: Action, capsys): ps.free() - act.expected_stdout = f""" + expected_stdout_5x = f""" Select Expression ....-> Filter ........-> Hash Join (semi) @@ -148,5 +149,27 @@ def test_1(act: Action, capsys): ................-> Table "T5" as "E" Full Scan 1 1 1 """ + + expected_stdout_6x = f""" + Select Expression + ....-> Filter + ........-> Hash Join (semi) + ............-> Filter + ................-> Hash Join (inner) + ....................-> Nested Loop Join (outer) + ........................-> Nested Loop Join (outer) + ............................-> Table "PUBLIC"."T1" as "PUBLIC"."V" "A" Full Scan + ............................-> Filter + ................................-> Table "PUBLIC"."T2" as "PUBLIC"."V" "B" Full Scan + ........................-> Filter + ............................-> Table "PUBLIC"."T3" as "PUBLIC"."V" "C" Full Scan + ....................-> Record Buffer (record length: NN) + ........................-> Table "PUBLIC"."T4" as "D" Full Scan + ............-> Record Buffer (record length: NN) + ................-> Table "PUBLIC"."T5" as "E" Full Scan + 1 1 1 + """ + + act.expected_stdout = expected_stdout_5x if act.is_version('<6') else expected_stdout_6x act.stdout = capsys.readouterr().out assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_8225_test.py b/tests/bugs/gh_8225_test.py index a0074886..3ab7fa0f 100644 --- a/tests/bugs/gh_8225_test.py +++ b/tests/bugs/gh_8225_test.py @@ -7,22 +7,24 @@ DESCRIPTION: NOTES: [03.09.2024] pzotov - Parameter 'SubQueryConversion' currently presents only in FB 5.x and _NOT_ in FB 6.x. - Because of that, testing version are limited only for 5.0.2. FB 6.x currently is NOT tested. - + Parameter 'SubQueryConversion' currently presents only in FB 5.x and _NOT_ in FB 6.x. + Because of that, testing version are limited only for 5.0.2. FB 6.x currently is NOT tested. [18.01.2025] pzotov - Resultset of cursor that executes using instance of selectable PreparedStatement must be stored - in some variable in order to have ability close it EXPLICITLY (before PS will be freed). - Otherwise access violation raises during Python GC and pytest hangs at final point (does not return control to OS). - This occurs at least for: Python 3.11.2 / pytest: 7.4.4 / firebird.driver: 1.10.6 / Firebird.Qa: 0.19.3 - The reason of that was explained by Vlad, 26.10.24 17:42 ("oddities when use instances of selective statements"). - - Confirmed bug on 5.0.2.1479-adfe97a. - Checked on 5.0.2.1482-604555f. - + Resultset of cursor that executes using instance of selectable PreparedStatement must be stored + in some variable in order to have ability close it EXPLICITLY (before PS will be freed). + Otherwise access violation raises during Python GC and pytest hangs at final point (does not return control to OS). + This occurs at least for: Python 3.11.2 / pytest: 7.4.4 / firebird.driver: 1.10.6 / Firebird.Qa: 0.19.3 + The reason of that was explained by Vlad, 26.10.24 17:42 ("oddities when use instances of selective statements"). + + Confirmed bug on 5.0.2.1479-adfe97a. + Checked on 5.0.2.1482-604555f. [16.04.2025] pzotov - Re-implemented in order to check FB 5.x with set 'SubQueryConversion = true' and FB 6.x w/o any changes in its config. - Checked on 6.0.0.687-730aa8f, 5.0.3.1647-8993a57 + Re-implemented in order to check FB 5.x with set 'SubQueryConversion = true' and FB 6.x w/o any changes in its config. + Checked on 6.0.0.687-730aa8f, 5.0.3.1647-8993a57 + [06.07.2025] pzotov + Separated expected output for FB major versions prior/since 6.x. + No substitutions are used to suppress schema and quotes. Discussed with dimitr, 24.06.2025 12:39. + Checked on 6.0.0.914; 5.0.3.1668. """ import pytest @@ -135,7 +137,7 @@ def test_1(act: Action, capsys): con.rollback() - act.expected_stdout = f""" + expected_stdout_5x = f""" Select Expression ....-> First N Records ........-> Filter @@ -147,6 +149,21 @@ def test_1(act: Action, capsys): ....................-> Table "EMPLOYEE" as "E" Full Scan 2 d2 """ + + expected_stdout_6x = f""" + Select Expression + ....-> First N Records + ........-> Filter + ............-> Hash Join (semi) + ................-> Refetch + ....................-> Sort (record length: NN, key length: NN) + ........................-> Table "PUBLIC"."DEPARTMENT" as "D" Full Scan + ................-> Record Buffer (record length: NN) + ....................-> Table "PUBLIC"."EMPLOYEE" as "E" Full Scan + 2 d2 + """ + + act.expected_stdout = expected_stdout_5x if act.is_version('<6') else expected_stdout_6x act.stdout = capsys.readouterr().out assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_8231_test.py b/tests/bugs/gh_8231_test.py index 415c8c16..218a3556 100644 --- a/tests/bugs/gh_8231_test.py +++ b/tests/bugs/gh_8231_test.py @@ -7,24 +7,23 @@ DESCRIPTION: NOTES: [26.08.2024] pzotov - Two tables must be joined by columns which has different charset or collates. - Confirmed bug on 5.0.2.1484-3cdfd38 (25.08.2024), got: - Statement failed, SQLSTATE = HY000 - request size limit exceeded - Checked on 5.0.2.1485-274af35 -- all ok. - + Two tables must be joined by columns which has different charset or collates. + Confirmed bug on 5.0.2.1484-3cdfd38 (25.08.2024), got: SQLSTATE = HY000 / request size limit exceeded + Checked on 5.0.2.1485-274af35 -- all ok. [18.01.2025] pzotov - Resultset of cursor that executes using instance of selectable PreparedStatement must be stored - in some variable in order to have ability close it EXPLICITLY (before PS will be freed). - Otherwise access violation raises during Python GC and pytest hangs at final point (does not return control to OS). - This occurs at least for: Python 3.11.2 / pytest: 7.4.4 / firebird.driver: 1.10.6 / Firebird.Qa: 0.19.3 - The reason of that was explained by Vlad, 26.10.24 17:42 ("oddities when use instances of selective statements"). - - Thanks to dimitr for the advice on implementing the test. + Resultset of cursor that executes using instance of selectable PreparedStatement must be stored + in some variable in order to have ability close it EXPLICITLY (before PS will be freed). + Otherwise access violation raises during Python GC and pytest hangs at final point (does not return control to OS). + This occurs at least for: Python 3.11.2 / pytest: 7.4.4 / firebird.driver: 1.10.6 / Firebird.Qa: 0.19.3 + The reason of that was explained by Vlad, 26.10.24 17:42 ("oddities when use instances of selective statements"). + Thanks to dimitr for the advice on implementing the test. [16.04.2025] pzotov - Re-implemented in order to check FB 5.x with set 'SubQueryConversion = true' and FB 6.x w/o any changes in its config. - Checked on 6.0.0.687-730aa8f, 5.0.3.1647-8993a57 + Re-implemented in order to check FB 5.x with set 'SubQueryConversion = true' and FB 6.x w/o any changes in its config. + Checked on 6.0.0.687-730aa8f, 5.0.3.1647-8993a57 + [06.07.2025] pzotov + Added 'SQL_SCHEMA_PREFIX' to be substituted in expected_* on FB 6.x + Checked on 6.0.0.914; 5.0.3.1668. """ import pytest @@ -100,12 +99,13 @@ def test_1(act: Action, capsys): con.rollback() + SQL_SCHEMA_PREFIX = '' if act.is_version('<6') else '"PUBLIC".' act.expected_stdout = f""" Select Expression ....-> Nested Loop Join (semi) - ........-> Table "T1" Full Scan + ........-> Table {SQL_SCHEMA_PREFIX}"T1" Full Scan ........-> Filter - ............-> Table "T2" Full Scan + ............-> Table {SQL_SCHEMA_PREFIX}"T2" Full Scan 1 """ act.stdout = capsys.readouterr().out diff --git a/tests/bugs/gh_8233_test.py b/tests/bugs/gh_8233_test.py index 696227f7..a07f5cd2 100644 --- a/tests/bugs/gh_8233_test.py +++ b/tests/bugs/gh_8233_test.py @@ -7,26 +7,27 @@ DESCRIPTION: NOTES: [27.08.2024] pzotov - 1. Confirmed bug on 5.0.1.1485-274af35 (26.08.2024), got for SubQueryConversion=true: - "multiple rows in singleton select", gdscodes: (335544652, 335544842) - 2. Parameter 'SubQueryConversion' currently presents only in FB 5.x and _NOT_ in FB 6.x. - Because of that, testing version are limited only for 5.0.2. FB 6.x currently is NOT tested. - 3. Table 't1' must have more than one row for bug reproducing. Query must be enclosed in execute block. - 4. Custom driver config objects are created here, one with SubQueryConversion = true and second with false. - + 1. Confirmed bug on 5.0.1.1485-274af35 (26.08.2024), got for SubQueryConversion=true: + "multiple rows in singleton select", gdscodes: (335544652, 335544842) + 2. Parameter 'SubQueryConversion' currently presents only in FB 5.x and _NOT_ in FB 6.x. + Because of that, testing version are limited only for 5.0.2. FB 6.x currently is NOT tested. + 3. Table 't1' must have more than one row for bug reproducing. Query must be enclosed in execute block. + 4. Custom driver config objects are created here, one with SubQueryConversion = true and second with false. [18.01.2025] pzotov - Resultset of cursor that executes using instance of selectable PreparedStatement must be stored - in some variable in order to have ability close it EXPLICITLY (before PS will be freed). - Otherwise access violation raises during Python GC and pytest hangs at final point (does not return control to OS). - This occurs at least for: Python 3.11.2 / pytest: 7.4.4 / firebird.driver: 1.10.6 / Firebird.Qa: 0.19.3 - The reason of that was explained by Vlad, 26.10.24 17:42 ("oddities when use instances of selective statements"). - - Checked on 5.0.2.1487-6934878 -- all ok. - Thanks to dimitr for the advice on implementing the test. + Resultset of cursor that executes using instance of selectable PreparedStatement must be stored + in some variable in order to have ability close it EXPLICITLY (before PS will be freed). + Otherwise access violation raises during Python GC and pytest hangs at final point (does not return control to OS). + This occurs at least for: Python 3.11.2 / pytest: 7.4.4 / firebird.driver: 1.10.6 / Firebird.Qa: 0.19.3 + The reason of that was explained by Vlad, 26.10.24 17:42 ("oddities when use instances of selective statements"). + Checked on 5.0.2.1487-6934878 -- all ok. + Thanks to dimitr for the advice on implementing the test. [16.04.2025] pzotov - Re-implemented in order to check FB 5.x with set 'SubQueryConversion = true' and FB 6.x w/o any changes in its config. - Checked on 6.0.0.687-730aa8f, 5.0.3.1647-8993a57 + Re-implemented in order to check FB 5.x with set 'SubQueryConversion = true' and FB 6.x w/o any changes in its config. + Checked on 6.0.0.687-730aa8f, 5.0.3.1647-8993a57 + [06.07.2025] pzotov + Added 'SQL_SCHEMA_PREFIX' to be substituted in expected_* on FB 6.x + Checked on 6.0.0.914; 5.0.3.1668. """ import pytest @@ -118,6 +119,7 @@ def test_1(act: Action, capsys): if ps: ps.free() + SQL_SCHEMA_PREFIX = '' if act.is_version('<6') else '"PUBLIC".' act.expected_stdout = f""" Select Expression (line 5, column 12) ....-> Singularity Check @@ -125,9 +127,9 @@ def test_1(act: Action, capsys): ............-> Filter ................-> Hash Join (semi) ....................-> Sort (record length: 28, key length: 8) - ........................-> Table "T1" Full Scan + ........................-> Table {SQL_SCHEMA_PREFIX}"T1" Full Scan ....................-> Record Buffer (record length: 25) - ........................-> Table "T2" Full Scan + ........................-> Table {SQL_SCHEMA_PREFIX}"T2" Full Scan 3 """ act.stdout = capsys.readouterr().out diff --git a/tests/bugs/gh_8249_test.py b/tests/bugs/gh_8249_test.py index 30009f1d..04a04b64 100644 --- a/tests/bugs/gh_8249_test.py +++ b/tests/bugs/gh_8249_test.py @@ -66,62 +66,110 @@ act = isql_act('db', test_script, substitutions = [('[-]?At line \\d+.*', '')]) -expected_stdout = """ - Statement failed, SQLSTATE = 22021 - unsuccessful metadata update - -CREATE VIEW V_TEST_1 failed - -Dynamic SQL Error - -SQL error code = -204 - -COLLATION MISSED_COLL for CHARACTER SET UTF8 is not defined - - Statement failed, SQLSTATE = 22021 - unsuccessful metadata update - -CREATE PROCEDURE SP_TEST_1 failed - -Dynamic SQL Error - -SQL error code = -204 - -COLLATION MISSED_COLL for CHARACTER SET UTF8 is not defined - - Statement failed, SQLSTATE = 22021 - unsuccessful metadata update - -CREATE PROCEDURE SP_TEST_2 failed - -Dynamic SQL Error - -SQL error code = -204 - -COLLATION MISSED_COLL for CHARACTER SET UTF8 is not defined - - Statement failed, SQLSTATE = 22021 - unsuccessful metadata update - -CREATE FUNCTION FN_TEST_1 failed - -Dynamic SQL Error - -SQL error code = -204 - -COLLATION MISSED_COLL for CHARACTER SET UTF8 is not defined - - Statement failed, SQLSTATE = 42S02 - Dynamic SQL Error - -SQL error code = -204 - -Table unknown - -V_TEST_1 - - Statement failed, SQLSTATE = 39000 - Dynamic SQL Error - -SQL error code = -804 - -Function unknown - -FN_TEST_1 - - Statement failed, SQLSTATE = 42S02 - Dynamic SQL Error - -SQL error code = -204 - -Table unknown - -SP_TEST_1 - - Statement failed, SQLSTATE = 42000 - Dynamic SQL Error - -SQL error code = -204 - -Procedure unknown - -SP_TEST_2 -""" - @pytest.mark.version('>=6.0') def test_1(act: Action): - act.expected_stdout = expected_stdout + + expected_stdout_5x = """ + Statement failed, SQLSTATE = 22021 + unsuccessful metadata update + -CREATE VIEW V_TEST_1 failed + -Dynamic SQL Error + -SQL error code = -204 + -COLLATION MISSED_COLL for CHARACTER SET UTF8 is not defined + + Statement failed, SQLSTATE = 22021 + unsuccessful metadata update + -CREATE PROCEDURE SP_TEST_1 failed + -Dynamic SQL Error + -SQL error code = -204 + -COLLATION MISSED_COLL for CHARACTER SET UTF8 is not defined + + Statement failed, SQLSTATE = 22021 + unsuccessful metadata update + -CREATE PROCEDURE SP_TEST_2 failed + -Dynamic SQL Error + -SQL error code = -204 + -COLLATION MISSED_COLL for CHARACTER SET UTF8 is not defined + + Statement failed, SQLSTATE = 22021 + unsuccessful metadata update + -CREATE FUNCTION FN_TEST_1 failed + -Dynamic SQL Error + -SQL error code = -204 + -COLLATION MISSED_COLL for CHARACTER SET UTF8 is not defined + + Statement failed, SQLSTATE = 42S02 + Dynamic SQL Error + -SQL error code = -204 + -Table unknown + -V_TEST_1 + + Statement failed, SQLSTATE = 39000 + Dynamic SQL Error + -SQL error code = -804 + -Function unknown + -FN_TEST_1 + + Statement failed, SQLSTATE = 42S02 + Dynamic SQL Error + -SQL error code = -204 + -Table unknown + -SP_TEST_1 + + Statement failed, SQLSTATE = 42000 + Dynamic SQL Error + -SQL error code = -204 + -Procedure unknown + -SP_TEST_2 + """ + + expected_stdout_6x = """ + Statement failed, SQLSTATE = 22021 + unsuccessful metadata update + -CREATE VIEW "PUBLIC"."V_TEST_1" failed + -Dynamic SQL Error + -SQL error code = -204 + -COLLATION "PUBLIC"."MISSED_COLL" for CHARACTER SET "SYSTEM"."UTF8" is not defined + Statement failed, SQLSTATE = 22021 + unsuccessful metadata update + -CREATE PROCEDURE "PUBLIC"."SP_TEST_1" failed + -Dynamic SQL Error + -SQL error code = -204 + -COLLATION "PUBLIC"."MISSED_COLL" for CHARACTER SET "SYSTEM"."UTF8" is not defined + Statement failed, SQLSTATE = 22021 + unsuccessful metadata update + -CREATE PROCEDURE "PUBLIC"."SP_TEST_2" failed + -Dynamic SQL Error + -SQL error code = -204 + -COLLATION "PUBLIC"."MISSED_COLL" for CHARACTER SET "SYSTEM"."UTF8" is not defined + Statement failed, SQLSTATE = 22021 + unsuccessful metadata update + -CREATE FUNCTION "PUBLIC"."FN_TEST_1" failed + -Dynamic SQL Error + -SQL error code = -204 + -COLLATION "PUBLIC"."MISSED_COLL" for CHARACTER SET "SYSTEM"."UTF8" is not defined + Statement failed, SQLSTATE = 42S02 + Dynamic SQL Error + -SQL error code = -204 + -Table unknown + -"V_TEST_1" + Statement failed, SQLSTATE = 39000 + Dynamic SQL Error + -SQL error code = -804 + -Function unknown + -"FN_TEST_1" + Statement failed, SQLSTATE = 42S02 + Dynamic SQL Error + -SQL error code = -204 + -Table unknown + -"SP_TEST_1" + Statement failed, SQLSTATE = 42000 + Dynamic SQL Error + -SQL error code = -204 + -Procedure unknown + -"SP_TEST_2" + """ + + act.expected_stdout = expected_stdout_5x if act.is_version('<6') else expected_stdout_6x act.execute(combine_output = True) assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_8250_test.py b/tests/bugs/gh_8250_test.py index 121a3e6d..9b4b4fbb 100644 --- a/tests/bugs/gh_8250_test.py +++ b/tests/bugs/gh_8250_test.py @@ -115,7 +115,7 @@ def test_1(act: Action, capsys): print(max_keys_msg) - act.expected_stdout = f""" + expected_stdout_5x = f""" Select Expression ....-> Filter ........-> Hash Join (inner) (keys, total key length) @@ -127,6 +127,21 @@ def test_1(act: Action, capsys): ................-> Table "TEST2" as "T2" Full Scan {expected_keys} """ + + expected_stdout_6x = f""" + Select Expression + ....-> Filter + ........-> Hash Join (inner) (keys, total key length) + ............-> Hash Join (inner) (keys, total key length) + ................-> Table "PUBLIC"."TEST3" as "T3" Full Scan + ................-> Record Buffer (record length) + ....................-> Table "PUBLIC"."TEST1" as "T1" Full Scan + ............-> Record Buffer (record length) + ................-> Table "PUBLIC"."TEST2" as "T2" Full Scan + {expected_keys} + """ + + act.expected_stdout = expected_stdout_5x if act.is_version('<6') else expected_stdout_6x act.stdout = capsys.readouterr().out assert act.clean_stdout == act.clean_expected_stdout act.reset() diff --git a/tests/bugs/gh_8252_test.py b/tests/bugs/gh_8252_test.py index c0748d4e..6dfe4dd8 100644 --- a/tests/bugs/gh_8252_test.py +++ b/tests/bugs/gh_8252_test.py @@ -7,24 +7,24 @@ DESCRIPTION: NOTES: [14.09.2024] pzotov - 1. Parameter 'SubQueryConversion' currently presents only in FB 5.x and _NOT_ in FB 6.x. - Because of that, testing version are limited only for 5.0.2. FB 6.x currently is NOT tested. - 2. Custom driver config object is created here for using 'SubQueryConversion = true'. - 3. Additional test was made for this issue: tests/functional/tabloid/test_aae2ae32.py - + 1. Parameter 'SubQueryConversion' currently presents only in FB 5.x and _NOT_ in FB 6.x. + Because of that, testing version are limited only for 5.0.2. FB 6.x currently is NOT tested. + 2. Custom driver config object is created here for using 'SubQueryConversion = true'. + 3. Additional test was made for this issue: tests/functional/tabloid/test_aae2ae32.py [18.01.2025] pzotov - Resultset of cursor that executes using instance of selectable PreparedStatement must be stored - in some variable in order to have ability close it EXPLICITLY (before PS will be freed). - Otherwise access violation raises during Python GC and pytest hangs at final point (does not return control to OS). - This occurs at least for: Python 3.11.2 / pytest: 7.4.4 / firebird.driver: 1.10.6 / Firebird.Qa: 0.19.3 - The reason of that was explained by Vlad, 26.10.24 17:42 ("oddities when use instances of selective statements"). - - Confirmed bug on 5.0.2.1497. - Checked on 5.0.2.1499-5fa4ae6. - + Resultset of cursor that executes using instance of selectable PreparedStatement must be stored + in some variable in order to have ability close it EXPLICITLY (before PS will be freed). + Otherwise access violation raises during Python GC and pytest hangs at final point (does not return control to OS). + This occurs at least for: Python 3.11.2 / pytest: 7.4.4 / firebird.driver: 1.10.6 / Firebird.Qa: 0.19.3 + The reason of that was explained by Vlad, 26.10.24 17:42 ("oddities when use instances of selective statements"). + Confirmed bug on 5.0.2.1497. Checked on 5.0.2.1499-5fa4ae6. [16.04.2025] pzotov - Re-implemented in order to check FB 5.x with set 'SubQueryConversion = true' and FB 6.x w/o any changes in its config. - Checked on 6.0.0.687-730aa8f, 5.0.3.1647-8993a57 + Re-implemented in order to check FB 5.x with set 'SubQueryConversion = true' and FB 6.x w/o any changes in its config. + Checked on 6.0.0.687-730aa8f, 5.0.3.1647-8993a57 + [06.07.2025] pzotov + Separated expected output for FB major versions prior/since 6.x. + No substitutions are used to suppress schema and quotes. Discussed with dimitr, 24.06.2025 12:39. + Checked on 6.0.0.914; 5.0.3.1668. """ import pytest @@ -91,16 +91,17 @@ def test_1(act: Action, capsys): con.rollback() - act.expected_stdout = """ + SQL_SCHEMA_PREFIX = '' if act.is_version('<6') else '"PUBLIC".' + act.expected_stdout = f""" Sub-query ....-> Filter - ........-> Table "CUSTOMER" as "C" Access By ID + ........-> Table {SQL_SCHEMA_PREFIX}"CUSTOMER" as "C" Access By ID ............-> Bitmap - ................-> Index "RDB$PRIMARY22" Unique Scan + ................-> Index {SQL_SCHEMA_PREFIX}"RDB$PRIMARY22" Unique Scan Select Expression ....-> First N Records ........-> Filter - ............-> Table "SALES" as "S" Full Scan + ............-> Table {SQL_SCHEMA_PREFIX}"SALES" as "S" Full Scan 1 1 1 diff --git a/tests/bugs/gh_8263_test.py b/tests/bugs/gh_8263_test.py index df739190..e744a556 100644 --- a/tests/bugs/gh_8263_test.py +++ b/tests/bugs/gh_8263_test.py @@ -20,15 +20,16 @@ 'Index "..." Full Scan' line. NOTES: [28.09.2024] pzotov - ::: NB ::: - This test forced to change prototypes of firebird.conf for 5.x and 6.x, see in $QA_HOME/firebird-qa/configs/ - files 'fb50_all.conf' and 'fb60_all.conf': they now contain ParallelWorkers > 1. - This change may affect on entire QA run result! Some other tests may need to be adjusted after this. - - Thanks to Vlad for suggestions about this test implementation. - - Confirmed bug on 6.0.0.471, 5.0.2.1516 - Checked on 6.0.0.474, 5.0.2.1519 -- all Ok. + ::: NB ::: + This test forced to change prototypes of firebird.conf for 5.x and 6.x, see in $QA_HOME/firebird-qa/configs/ + files 'fb50_all.conf' and 'fb60_all.conf': they now contain ParallelWorkers > 1. + This change may affect on entire QA run result! Some other tests may need to be adjusted after this. + Thanks to Vlad for suggestions about this test implementation. + Confirmed bug on 6.0.0.471, 5.0.2.1516 + Checked on 6.0.0.474, 5.0.2.1519 -- all Ok. + [06.07.2025] pzotov + Added 'SQL_SCHEMA_PREFIX' to be substituted in expected_* on FB 6.x + Checked on 6.0.0.914; 5.0.3.1668; 4.0.6.3214. """ import locale from pathlib import Path @@ -135,10 +136,11 @@ def test_1(act: Action, tmp_fbk: Path, tmp_fdb: Path, capsys): # Print explained plan with padding eash line by dots in order to see indentations: print( '\n'.join([replace_leading(s) for s in ps.detailed_plan.split('\n')]) ) + SQL_SCHEMA_PREFIX = '' if act.is_version('<6') else '"PUBLIC".' act.expected_stdout = f""" Select Expression - ....-> Table "TEST" Access By ID - ........-> Index "TEST_ID" Full Scan + ....-> Table {SQL_SCHEMA_PREFIX}"TEST" Access By ID + ........-> Index {SQL_SCHEMA_PREFIX}"TEST_ID" Full Scan """ act.stdout = capsys.readouterr().out assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_8265_test.py b/tests/bugs/gh_8265_test.py index 7c122234..29a28c8e 100644 --- a/tests/bugs/gh_8265_test.py +++ b/tests/bugs/gh_8265_test.py @@ -7,61 +7,30 @@ DESCRIPTION: NOTES: [26.09.2024] pzotov - 0. Commits: - 6.x: - 22.03.2025 10:47 - https://github.com/FirebirdSQL/firebird/commit/fc12c0ef392fec9c83d41bc17da3dc233491498c - (Unnest IN/ANY/EXISTS subqueries and optimize them using semi-join algorithm (#8061)) - 5.x - 31.07.2024 09:46 - https://github.com/FirebirdSQL/firebird/commit/4943b3faece209caa93cc9573803677019582f1c - (Added support for semi/anti and outer joins to hash join algorithm ...) - Also: - 14.09.2024 09:24 - https://github.com/FirebirdSQL/firebird/commit/5fa4ae611d18fd4ce9aac1c8dbc79e5fea2bc1f2 - (Fix bug #8252: Incorrect subquery unnesting with complex dependencies) - 1. Parameter 'SubQueryConversion' currently presents only in FB 5.x and _NOT_ in FB 6.x. - 2. Custom driver config objects are created here, one with SubQueryConversion = true and second with false. - 3. First example of this test is also used in tests/functional/tabloid/test_aae2ae32.py - - Confirmed problem on 5.0.2.1516-fe6ba50 (23.09.2024). - Checked on 5.0.2.1516-92316F0 (25.09.2024). - - [15.01.2025] pzotov - - ### CRITICAL ISSUE ### PROBABLY MUST BE APPLIED TO ALL TESTS WITH SIMILAR BEHAVOUR ### - - Resultset of cursor that executes using instance of selectable PreparedStatement must be stored - in some variable in order to have ability close it EXPLICITLY (before PS will be freed). - Otherwise access violation raises. - This occurs at least for: Python 3.11.2 / pytest: 7.4.4 / firebird.driver: 1.10.6 / Firebird.Qa: 0.19.3 - - Example of broken pytest log when AV occurs: - ========== - tests/bugs/gh_8265_test.py::test_1 Windows fatal exception: access violation - - Current thread 0x0000385c (most recent call first): - Garbage-collecting - File "C:/Python3x/Lib/site-packages/firebird/driver/interfaces.py", line 831 in free - File "C:/Python3x/Lib/site-packages/firebird/driver/core.py", line 2736 in free - ... - File "C:/Python3x/Scripts/pytest.exe/__main__.py", line 7 in - File "", line 88 in _run_code - File "", line 198 in _run_module_as_main - PASSED [1773/2565] - ========== - The reason of that was explained by Vlad, letter 26.10.24 17:42 - (subject: "oddities when use instances of selective statements"): - * line 'cur1.execute(ps1)' creates a new cursor but looses reference on it; - * but this cursor is linked with instance of ps1 which *has* reference on that cursor; - * call 'ps1.free()' delete this anonimous cursor but Python runtime - (or - maybe - code that makes connection cleanup) does not know about it - and tries to delete this anon cursor AGAIN when code finishes 'with' block. - This attempt causes AV. - + 0. Commits: + 6.x: + 22.03.2025 10:47 + https://github.com/FirebirdSQL/firebird/commit/fc12c0ef392fec9c83d41bc17da3dc233491498c + (Unnest IN/ANY/EXISTS subqueries and optimize them using semi-join algorithm (#8061)) + 5.x + 31.07.2024 09:46 + https://github.com/FirebirdSQL/firebird/commit/4943b3faece209caa93cc9573803677019582f1c + (Added support for semi/anti and outer joins to hash join algorithm ...) + Also: + 14.09.2024 09:24 + https://github.com/FirebirdSQL/firebird/commit/5fa4ae611d18fd4ce9aac1c8dbc79e5fea2bc1f2 + (Fix bug #8252: Incorrect subquery unnesting with complex dependencies) + 1. Parameter 'SubQueryConversion' currently presents only in FB 5.x and _NOT_ in FB 6.x. + 2. Custom driver config objects are created here, one with SubQueryConversion = true and second with false. + 3. First example of this test is also used in tests/functional/tabloid/test_aae2ae32.py + Confirmed problem on 5.0.2.1516-fe6ba50 (23.09.2024). Checked on 5.0.2.1516-92316F0 (25.09.2024). [16.04.2025] pzotov - Re-implemented in order to check FB 5.x with set 'SubQueryConversion = true' and FB 6.x w/o any changes in its config. - Checked on 6.0.0.687-730aa8f, 5.0.3.1647-8993a57 + Re-implemented in order to check FB 5.x with set 'SubQueryConversion = true' and FB 6.x w/o any changes in its config. + Checked on 6.0.0.687-730aa8f, 5.0.3.1647-8993a57 + [06.07.2025] pzotov + Separated expected output for FB major versions prior/since 6.x. + No substitutions are used to suppress schema and quotes. Discussed with dimitr, 24.06.2025 12:39. + Checked on 6.0.0.914; 5.0.3.1668. """ import pytest @@ -199,7 +168,7 @@ def test_1(act: Action, capsys): if ps: ps.free() - act.expected_stdout = f""" + expected_stdout_5x = f""" 1000 {query_map[1000][0]} {query_map[1000][1]} @@ -268,5 +237,77 @@ def test_1(act: Action, capsys): ............-> Table "TEST1" as "Q4_A" Full Scan 10 """ + + expected_stdout_6x = f""" + 1000 + {query_map[1000][0]} + {query_map[1000][1]} + Select Expression + ....-> Aggregate + ........-> Filter + ............-> Hash Join (semi) + ................-> Table "PUBLIC"."TEST1" as "Q1_A" Full Scan + ................-> Record Buffer (record length: NN) + ....................-> Filter + ........................-> Hash Join (semi) + ............................-> Table "PUBLIC"."TEST2" as "Q1_B" Full Scan + ............................-> Record Buffer (record length: NN) + ................................-> Filter + ....................................-> Table "PUBLIC"."TEST3" as "Q1_C" Full Scan + 10 + + 2000 + {query_map[2000][0]} + {query_map[2000][1]} + Sub-query + ....-> Filter + ........-> Filter + ............-> Table "PUBLIC"."TEST3" as "Q2_C" Full Scan + Select Expression + ....-> Aggregate + ........-> Filter + ............-> Hash Join (semi) + ................-> Table "PUBLIC"."TEST1" as "Q2_A" Full Scan + ................-> Record Buffer (record length: NN) + ....................-> Filter + ........................-> Table "PUBLIC"."TEST2" as "Q2_B" Full Scan + 10 + + 3000 + {query_map[3000][0]} + {query_map[3000][1]} + Sub-query + ....-> Filter + ........-> Filter + ............-> Table "PUBLIC"."TEST3" as "Q3_C" Full Scan + Sub-query + ....-> Filter + ........-> Filter + ............-> Table "PUBLIC"."TEST2" as "Q3_B" Full Scan + Select Expression + ....-> Aggregate + ........-> Filter + ............-> Table "PUBLIC"."TEST1" as "Q3_A" Full Scan + 10 + + 4000 + {query_map[4000][0]} + {query_map[4000][1]} + Sub-query + ....-> Filter + ........-> Filter + ............-> Table "PUBLIC"."TEST3" as "Q4_C" Full Scan + Sub-query + ....-> Filter + ........-> Filter + ............-> Table "PUBLIC"."TEST2" as "Q4_B" Full Scan + Select Expression + ....-> Aggregate + ........-> Filter + ............-> Table "PUBLIC"."TEST1" as "Q4_A" Full Scan + 10 + """ + + act.expected_stdout = expected_stdout_5x if act.is_version('<6') else expected_stdout_6x act.stdout = capsys.readouterr().out assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_8290_test.py b/tests/bugs/gh_8290_test.py index d0efda58..4ef2293f 100644 --- a/tests/bugs/gh_8290_test.py +++ b/tests/bugs/gh_8290_test.py @@ -9,8 +9,12 @@ For each case we ask engine to show explained plan. Every case must have 'Range Scan (full match)'. NOTES: [25.10.2024] pzotov - Confirmed problem on 6.0.0.485, 5.0.2.1519. - Checked on 6.0.0.502-d2f4cf6, 5.0.2.1542-ab50e20 (intermediate builds). + Confirmed problem on 6.0.0.485, 5.0.2.1519. + Checked on 6.0.0.502-d2f4cf6, 5.0.2.1542-ab50e20 (intermediate builds). + [06.07.2025] pzotov + Separated expected output for FB major versions prior/since 6.x. + No substitutions are used to suppress schema and quotes. Discussed with dimitr, 24.06.2025 12:39. + Checked on 6.0.0.914; 5.0.3.1668. """ import pytest @@ -70,7 +74,7 @@ def test_1(act: Action, capsys): ps.free() - expected_out = f""" + expected_stdout_5x = f""" {qry_map[0]} Select Expression ....-> Aggregate @@ -152,7 +156,88 @@ def test_1(act: Action, capsys): ....................-> Index "TEST_X_MINUS_Y_PARTIAL" Range Scan (full match) """ - act.expected_stdout = expected_out + expected_stdout_6x = f""" + {qry_map[0]} + Select Expression + ....-> Aggregate + ........-> Filter + ............-> Table "PUBLIC"."TEST" Access By ID + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_X_ASC" Range Scan (full match) + + {qry_map[1]} + Select Expression + ....-> Aggregate + ........-> Filter + ............-> Table "PUBLIC"."TEST" Access By ID + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_Y_DESC" Range Scan (full match) + + {qry_map[2]} + Select Expression + ....-> Aggregate + ........-> Filter + ............-> Table "PUBLIC"."TEST" Access By ID + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_X_PLUS_Y" Range Scan (full match) + + {qry_map[3]} + Select Expression + ....-> Aggregate + ........-> Filter + ............-> Table "PUBLIC"."TEST" Access By ID + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_Z_PARTIAL" Range Scan (full match) + + {qry_map[4]} + Select Expression + ....-> Aggregate + ........-> Filter + ............-> Table "PUBLIC"."TEST" Access By ID + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_X_MINUS_Y_PARTIAL" Range Scan (full match) + + {qry_map[5]} + Select Expression + ....-> Aggregate + ........-> Filter + ............-> Table "PUBLIC"."TEST" Access By ID + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_X_ASC" Range Scan (full match) + + {qry_map[6]} + Select Expression + ....-> Aggregate + ........-> Filter + ............-> Table "PUBLIC"."TEST" Access By ID + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_Y_DESC" Range Scan (full match) + + {qry_map[7]} + Select Expression + ....-> Aggregate + ........-> Filter + ............-> Table "PUBLIC"."TEST" Access By ID + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_X_PLUS_Y" Range Scan (full match) + + {qry_map[8]} + Select Expression + ....-> Aggregate + ........-> Filter + ............-> Table "PUBLIC"."TEST" Access By ID + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_Z_PARTIAL" Range Scan (full match) + + {qry_map[9]} + Select Expression + ....-> Aggregate + ........-> Filter + ............-> Table "PUBLIC"."TEST" Access By ID + ................-> Bitmap + ....................-> Index "PUBLIC"."TEST_X_MINUS_Y_PARTIAL" Range Scan (full match) + """ + act.expected_stdout = expected_stdout_5x if act.is_version('<6') else expected_stdout_6x act.stdout = capsys.readouterr().out assert act.clean_stdout == act.clean_expected_stdout diff --git a/tests/bugs/gh_8434_test.py b/tests/bugs/gh_8434_test.py index 328f8c56..8c3c9ab3 100644 --- a/tests/bugs/gh_8434_test.py +++ b/tests/bugs/gh_8434_test.py @@ -174,102 +174,95 @@ def test_1(act: Action, capsys): expected_stdout = """ Initial state: - Query: select * from v1_chk_nr Select Expression ....-> Sort (record length: NN, key length: MM) ........-> Filter - ............-> Table "TEST1" as "V1_CHK_NR TEST1" Full Scan + ............-> Table "PUBLIC"."TEST1" as "PUBLIC"."V1_CHK_NR" "PUBLIC"."TEST1" Full Scan 3 lowered "D" normal Query: select * from v1_chk_ir_asc Select Expression ....-> Filter - ........-> Table "TEST1" as "V1_CHK_IR_ASC TEST1" Access By ID - ............-> Index "TEST1_ASC" Range Scan (full match) + ........-> Table "PUBLIC"."TEST1" as "PUBLIC"."V1_CHK_IR_ASC" "PUBLIC"."TEST1" Access By ID + ............-> Index "PUBLIC"."TEST1_ASC" Range Scan (full match) 3 lowered "D" normal Query: select * from v1_chk_ir_dec Select Expression ....-> Filter - ........-> Table "TEST1" as "V1_CHK_IR_DEC TEST1" Access By ID - ............-> Index "TEST1_DEC" Range Scan (full match) + ........-> Table "PUBLIC"."TEST1" as "PUBLIC"."V1_CHK_IR_DEC" "PUBLIC"."TEST1" Access By ID + ............-> Index "PUBLIC"."TEST1_DEC" Range Scan (full match) 3 lowered "D" normal Query: select * from v2_chk_nr Select Expression ....-> Sort (record length: NN, key length: MM) ........-> Filter - ............-> Table "TEST2" as "V2_CHK_NR TEST2" Full Scan + ............-> Table "PUBLIC"."TEST2" as "PUBLIC"."V2_CHK_NR" "PUBLIC"."TEST2" Full Scan 3 lowered "L" normal Query: select * from v2_chk_ir_asc Select Expression ....-> Filter - ........-> Table "TEST2" as "V2_CHK_IR_ASC TEST2" Access By ID - ............-> Index "TEST2_PARTIAL_ASC" Full Scan + ........-> Table "PUBLIC"."TEST2" as "PUBLIC"."V2_CHK_IR_ASC" "PUBLIC"."TEST2" Access By ID + ............-> Index "PUBLIC"."TEST2_PARTIAL_ASC" Full Scan 3 lowered "L" normal Query: select * from v2_chk_ir_dec Select Expression ....-> Sort (record length: NN, key length: MM) ........-> Filter - ............-> Table "TEST2" as "V2_CHK_IR_DEC TEST2" Access By ID + ............-> Table "PUBLIC"."TEST2" as "PUBLIC"."V2_CHK_IR_DEC" "PUBLIC"."TEST2" Access By ID ................-> Bitmap - ....................-> Index "TEST2_PARTIAL_ASC" Full Scan + ....................-> Index "PUBLIC"."TEST2_PARTIAL_ASC" Full Scan 3 lowered "L" normal - - After alter domain dm_utf8 type varchar(1) character set utf8 collate unicode_ci: - Query: select * from v1_chk_nr Select Expression ....-> Sort (record length: NN, key length: MM) ........-> Filter - ............-> Table "TEST1" as "V1_CHK_NR TEST1" Full Scan + ............-> Table "PUBLIC"."TEST1" as "PUBLIC"."V1_CHK_NR" "PUBLIC"."TEST1" Full Scan 3 lowered "D" normal 4 UPPERED "D" normal Query: select * from v1_chk_ir_asc Select Expression ....-> Filter - ........-> Table "TEST1" as "V1_CHK_IR_ASC TEST1" Access By ID - ............-> Index "TEST1_ASC" Range Scan (full match) + ........-> Table "PUBLIC"."TEST1" as "PUBLIC"."V1_CHK_IR_ASC" "PUBLIC"."TEST1" Access By ID + ............-> Index "PUBLIC"."TEST1_ASC" Range Scan (full match) 3 lowered "D" normal 4 UPPERED "D" normal Query: select * from v1_chk_ir_dec Select Expression ....-> Filter - ........-> Table "TEST1" as "V1_CHK_IR_DEC TEST1" Access By ID - ............-> Index "TEST1_DEC" Range Scan (full match) + ........-> Table "PUBLIC"."TEST1" as "PUBLIC"."V1_CHK_IR_DEC" "PUBLIC"."TEST1" Access By ID + ............-> Index "PUBLIC"."TEST1_DEC" Range Scan (full match) 4 UPPERED "D" normal 3 lowered "D" normal Query: select * from v2_chk_nr Select Expression ....-> Sort (record length: NN, key length: MM) ........-> Filter - ............-> Table "TEST2" as "V2_CHK_NR TEST2" Full Scan + ............-> Table "PUBLIC"."TEST2" as "PUBLIC"."V2_CHK_NR" "PUBLIC"."TEST2" Full Scan 3 lowered "L" normal 4 UPPERED "L" normal Query: select * from v2_chk_ir_asc Select Expression ....-> Filter - ........-> Table "TEST2" as "V2_CHK_IR_ASC TEST2" Access By ID - ............-> Index "TEST2_PARTIAL_ASC" Full Scan + ........-> Table "PUBLIC"."TEST2" as "PUBLIC"."V2_CHK_IR_ASC" "PUBLIC"."TEST2" Access By ID + ............-> Index "PUBLIC"."TEST2_PARTIAL_ASC" Full Scan 3 lowered "L" normal 4 UPPERED "L" normal Query: select * from v2_chk_ir_dec Select Expression ....-> Sort (record length: NN, key length: MM) ........-> Filter - ............-> Table "TEST2" as "V2_CHK_IR_DEC TEST2" Access By ID + ............-> Table "PUBLIC"."TEST2" as "PUBLIC"."V2_CHK_IR_DEC" "PUBLIC"."TEST2" Access By ID ................-> Bitmap - ....................-> Index "TEST2_PARTIAL_ASC" Full Scan + ....................-> Index "PUBLIC"."TEST2_PARTIAL_ASC" Full Scan 4 UPPERED "L" normal 3 lowered "L" normal - - After alter domain dm_utf8 type varchar(1) character set utf8 collate unicode_ci_ai: - Query: select * from v1_chk_nr Select Expression ....-> Sort (record length: NN, key length: MM) ........-> Filter - ............-> Table "TEST1" as "V1_CHK_NR TEST1" Full Scan + ............-> Table "PUBLIC"."TEST1" as "PUBLIC"."V1_CHK_NR" "PUBLIC"."TEST1" Full Scan 1 lowered "D" w/accent 2 UPPERED "D" w/accent 3 lowered "D" normal @@ -277,8 +270,8 @@ def test_1(act: Action, capsys): Query: select * from v1_chk_ir_asc Select Expression ....-> Filter - ........-> Table "TEST1" as "V1_CHK_IR_ASC TEST1" Access By ID - ............-> Index "TEST1_ASC" Range Scan (full match) + ........-> Table "PUBLIC"."TEST1" as "PUBLIC"."V1_CHK_IR_ASC" "PUBLIC"."TEST1" Access By ID + ............-> Index "PUBLIC"."TEST1_ASC" Range Scan (full match) 3 lowered "D" normal 4 UPPERED "D" normal 1 lowered "D" w/accent @@ -286,8 +279,8 @@ def test_1(act: Action, capsys): Query: select * from v1_chk_ir_dec Select Expression ....-> Filter - ........-> Table "TEST1" as "V1_CHK_IR_DEC TEST1" Access By ID - ............-> Index "TEST1_DEC" Range Scan (full match) + ........-> Table "PUBLIC"."TEST1" as "PUBLIC"."V1_CHK_IR_DEC" "PUBLIC"."TEST1" Access By ID + ............-> Index "PUBLIC"."TEST1_DEC" Range Scan (full match) 2 UPPERED "D" w/accent 1 lowered "D" w/accent 4 UPPERED "D" normal @@ -296,7 +289,7 @@ def test_1(act: Action, capsys): Select Expression ....-> Sort (record length: NN, key length: MM) ........-> Filter - ............-> Table "TEST2" as "V2_CHK_NR TEST2" Full Scan + ............-> Table "PUBLIC"."TEST2" as "PUBLIC"."V2_CHK_NR" "PUBLIC"."TEST2" Full Scan 1 lowered "L" w/accent 2 UPPERED "L" w/accent 3 lowered "L" normal @@ -304,8 +297,8 @@ def test_1(act: Action, capsys): Query: select * from v2_chk_ir_asc Select Expression ....-> Filter - ........-> Table "TEST2" as "V2_CHK_IR_ASC TEST2" Access By ID - ............-> Index "TEST2_PARTIAL_ASC" Full Scan + ........-> Table "PUBLIC"."TEST2" as "PUBLIC"."V2_CHK_IR_ASC" "PUBLIC"."TEST2" Access By ID + ............-> Index "PUBLIC"."TEST2_PARTIAL_ASC" Full Scan 3 lowered "L" normal 4 UPPERED "L" normal 1 lowered "L" w/accent @@ -314,57 +307,53 @@ def test_1(act: Action, capsys): Select Expression ....-> Sort (record length: NN, key length: MM) ........-> Filter - ............-> Table "TEST2" as "V2_CHK_IR_DEC TEST2" Access By ID + ............-> Table "PUBLIC"."TEST2" as "PUBLIC"."V2_CHK_IR_DEC" "PUBLIC"."TEST2" Access By ID ................-> Bitmap - ....................-> Index "TEST2_PARTIAL_ASC" Full Scan + ....................-> Index "PUBLIC"."TEST2_PARTIAL_ASC" Full Scan 2 UPPERED "L" w/accent 1 lowered "L" w/accent 4 UPPERED "L" normal 3 lowered "L" normal - - After alter domain dm_utf8 type varchar(1) character set utf8: - Query: select * from v1_chk_nr Select Expression ....-> Sort (record length: NN, key length: MM) ........-> Filter - ............-> Table "TEST1" as "V1_CHK_NR TEST1" Full Scan + ............-> Table "PUBLIC"."TEST1" as "PUBLIC"."V1_CHK_NR" "PUBLIC"."TEST1" Full Scan 3 lowered "D" normal Query: select * from v1_chk_ir_asc Select Expression ....-> Filter - ........-> Table "TEST1" as "V1_CHK_IR_ASC TEST1" Access By ID - ............-> Index "TEST1_ASC" Range Scan (full match) + ........-> Table "PUBLIC"."TEST1" as "PUBLIC"."V1_CHK_IR_ASC" "PUBLIC"."TEST1" Access By ID + ............-> Index "PUBLIC"."TEST1_ASC" Range Scan (full match) 3 lowered "D" normal Query: select * from v1_chk_ir_dec Select Expression ....-> Filter - ........-> Table "TEST1" as "V1_CHK_IR_DEC TEST1" Access By ID - ............-> Index "TEST1_DEC" Range Scan (full match) + ........-> Table "PUBLIC"."TEST1" as "PUBLIC"."V1_CHK_IR_DEC" "PUBLIC"."TEST1" Access By ID + ............-> Index "PUBLIC"."TEST1_DEC" Range Scan (full match) 3 lowered "D" normal Query: select * from v2_chk_nr Select Expression ....-> Sort (record length: NN, key length: MM) ........-> Filter - ............-> Table "TEST2" as "V2_CHK_NR TEST2" Full Scan + ............-> Table "PUBLIC"."TEST2" as "PUBLIC"."V2_CHK_NR" "PUBLIC"."TEST2" Full Scan 3 lowered "L" normal Query: select * from v2_chk_ir_asc Select Expression ....-> Filter - ........-> Table "TEST2" as "V2_CHK_IR_ASC TEST2" Access By ID - ............-> Index "TEST2_PARTIAL_ASC" Full Scan + ........-> Table "PUBLIC"."TEST2" as "PUBLIC"."V2_CHK_IR_ASC" "PUBLIC"."TEST2" Access By ID + ............-> Index "PUBLIC"."TEST2_PARTIAL_ASC" Full Scan 3 lowered "L" normal Query: select * from v2_chk_ir_dec Select Expression ....-> Sort (record length: NN, key length: MM) ........-> Filter - ............-> Table "TEST2" as "V2_CHK_IR_DEC TEST2" Access By ID + ............-> Table "PUBLIC"."TEST2" as "PUBLIC"."V2_CHK_IR_DEC" "PUBLIC"."TEST2" Access By ID ................-> Bitmap - ....................-> Index "TEST2_PARTIAL_ASC" Full Scan + ....................-> Index "PUBLIC"."TEST2_PARTIAL_ASC" Full Scan 3 lowered "L" normal """ - act.expected_stdout = expected_stdout act.stdout = capsys.readouterr().out