#coding:utf-8 """ ID: issue-5654 ISSUE: https://github.com/FirebirdSQL/firebird/issues/5654 TITLE: Regression: could not execute query (select from view with nested view) DESCRIPTION: Test uses queries from ticket but creates user tables instead of rdb$ ones. We ask FB only to prepare query. Before fix this query preparation lasted ~130 seconds with raising '335544382 : request size limit exceeded. JIRA: CORE-5381 FBTEST: bugs.core_5381 NOTES: [17.11.2024] pzotov Re-implemented. No sense to check execution time or execution plan. We have to ensure only ability of engine to complete prerape_statement. [19.11.2024] pzotov Added max allowed time for prepare duration and appropriate check (suggested by dimitr). Confirmed bug on 3.0.1.32609 (27-sep-2016), got in trace: 2024-11-08T00:42:49.8710 ERROR AT JStatement::prepare 335544382 : request size limit exceeded Checked on 3.0.13.33794, 4.0.6.3168, 5.0.2.1553, 6.0.0.520 """ import datetime as py_dt from datetime import timedelta import pytest from firebird.qa import * from firebird.driver import DatabaseError ################### MAX_PREPARE_TIME_MS=1000 ################### init_sql = """ recreate view test_view as select 1 x from rdb$database; recreate view inner_view as select 1 x from rdb$database; recreate table rdb_types( id int generated by default as identity constraint pk_rdb_types primary key ,type_id int ); recreate table rdb_rels( id int generated by default as identity constraint pk_rdb_rels primary key ,rel_id int ); recreate table rdb_deps( id int generated by default as identity constraint pk_rdb_deps primary key ,dep_type int ); recreate table rdb_colls( id int generated by default as identity constraint pk_rdb_colls primary key ,coll_id int ); recreate table rdb_flds( id int generated by default as identity constraint pk_rdb_flds primary key ,fld_type_id int ); recreate table rdb_csets( id int generated by default as identity constraint pk_rdb_csets primary key ,cset_id int ); recreate table t1(id bigint not null primary key using index pk_t1_id); recreate table t2(id bigint not null primary key using index pk_t2_id); recreate table t3(id bigint not null primary key using index pk_t3_id); recreate table t4(id bigint not null primary key using index pk_t4_id); recreate table t5(id bigint not null primary key using index pk_t5_id); recreate table t6(id bigint not null primary key using index pk_t6_id); recreate table t7(id bigint not null primary key using index pk_t7_id); recreate table t8(id bigint not null primary key using index pk_t8_id); recreate view inner_view as select t1.id from t1 inner join t8 b on b.id = t1.id inner join t2 c on c.id = t1.id left join t4 d on d.id = t1.id inner join t5 e on e.id = t1.id left join t6 f on f.id = t1.id inner join rdb_types g1 on g1.type_id = t1.id inner join rdb_rels g2 on g2.rel_id = t1.id inner join rdb_deps g3 on g3.dep_type = t1.id inner join rdb_colls g4 on g4.coll_id = t1.id inner join rdb_flds g5 on g5.fld_type_id = t1.id inner join rdb_csets g6 on g6.cset_id = t1.id ; recreate view test_view as select t1.id from t1 inner join inner_view on inner_view.id = t1.id inner join t7 on t7.id = t1.id left join t3 on t3.id = t1.id inner join rdb_types d1 on d1.type_id = t1.id inner join rdb_rels d2 on d2.rel_id = t1.id inner join rdb_deps d3 on d3.dep_type = t1.id inner join rdb_colls d4 on d4.coll_id = t1.id inner join rdb_flds d5 on d5.fld_type_id = t1.id ; commit; """ db = db_factory(init = init_sql) act = python_act('db') #----------------------------------------------------------- @pytest.mark.version('>=3.0.1') def test_1(act: Action, capsys): test_sql = """ select count(*) from test_view a inner join rdb_types d1 on d1.type_id = a.id inner join rdb_rels d2 on d2.rel_id = a.id inner join rdb_deps d3 on d3.dep_type = a.id where a.id = 1 ; """ td = 86400000 with act.db.connect() as con: cur = con.cursor() ps = None try: t1=py_dt.datetime.now() ps = cur.prepare(test_sql) t2=py_dt.datetime.now() td = int((t2-t1).total_seconds() * 1000) # milliseconds print('Completed.') except DatabaseError as e: print(e.__str__()) print(e.gds_codes) finally: if ps: ps.free() act.expected_stdout = 'Completed.' act.stdout = capsys.readouterr().out assert act.clean_stdout == act.clean_expected_stdout assert td < MAX_PREPARE_TIME_MS, f'Prepare time: {td} ms - greater than max allowed {MAX_PREPARE_TIME_MS} ms.'