6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-01-22 21:43:06 +01:00
firebird-qa/tests/bugs/core_2650_test.py

888 lines
30 KiB
Python
Raw Normal View History

2021-04-26 20:07:00 +02:00
#coding:utf-8
2022-01-21 18:49:26 +01:00
"""
ID: issue-3057
ISSUE: 3057
TITLE: Improve sorting performance when long VARCHARs are involved
DESCRIPTION:
Test verifies trivial queries with persistent and computed columns, predicates, views,
expressions without reference to any column and datatypes which have no symmetrical
transformation from value to a key (decfloat, time-with-timezone and varchar with non-default collation).
2021-04-26 20:07:00 +02:00
It is supposed that default value of InlineSortThreshold parameter is 1000.
No changes in the firebird.conf reuired.
2021-04-26 20:07:00 +02:00
This test most probably will be added by some new examples later.
Thanks to dimitr for lot of explanations (e-mail discussion was 28.12.2020).
2022-01-21 18:49:26 +01:00
JIRA: CORE-2650
FBTEST: bugs.core_2650
NOTES:
[02.09.2024]
1. Test was fully re-implemented in order to have ability to see both query and its comment in case of mismatch.
The 'f'-notation is used in expected output with substitution query text and comments to it, e.g.:
{query_map[1000][0]} // output will be compared with: "select txt_short from test a01 order by id"
{query_map[1000][1]} // output will be compared with: "Must NOT use refetch because length of non-key column is less than threshold"
2. Explained plans for FB 4.x and 5.x/6.x not equal.
Because of this, expected output is stored differently (fb4x_expected_out, fb5x_expected_out).
3. Indentation between 'Refetch' and subsequent 'Sort' was removed (only 'master' was affected).
This change was caused by (or related to) profiler, discussed with Adriano.
See letters since 24-aug-2023, subj:
"Test for gh-7687: can't understand the output for trivial .sql (from the ticket)"
See also:
https://groups.google.com/g/firebird-devel/c/dWIgSIemys4/m/TzUWYwmVAQAJ (18-JUL-2023)
https://github.com/FirebirdSQL/firebird/issues/7687 (28-JUL-2023)
4 Need to preserve indentation was explained by dimitr 28-aug-2024 12:57, subj:
'Explained plan, "Refetch": should the indentation be after it at line with subsequent "-> Sort (record ...)" ?'
5. Indentation was restored 01-sep-2024 by fix https://github.com/FirebirdSQL/firebird/issues/8235
https://github.com/FirebirdSQL/firebird/commit/901b4ced9a3615929e0027d42ebb2392e943b205
Checked on 6.0.0.447-901b4ce, 5.0.2.1487, 4.0.6.3142
2022-01-21 18:49:26 +01:00
"""
import pytest
from firebird.qa import *
2021-04-26 20:07:00 +02:00
init_sql = """
2021-04-26 20:07:00 +02:00
set bail on;
recreate view v_unioned as select 1 id from rdb$database;
commit;
recreate table test(
id int
,f01 int
,f02 int
,txt_short varchar(998)
,txt_broad varchar(999)
,computed_id_dup computed by( id*2 )
,computed_ts_dup computed by ( txt_short || txt_short )
,computed_tb_dup computed by ( txt_broad || txt_broad )
,computed_guid computed by ( lpad('', 2000, uuid_to_char(gen_uuid()) ) )
2021-11-09 11:01:26 +01:00
,computed_ts_left computed by( left(txt_short,10) )
,computed_tb_left computed by( left(txt_broad,10) )
2021-04-26 20:07:00 +02:00
);
recreate table test_ns_01(
id decfloat
,txt_short varchar(983)
);
recreate table test_ns_02(
id decfloat
,txt_short varchar(982)
);
recreate table test_ns_03(
id time with time zone
,txt_short varchar(991)
);
recreate table test_ns_04(
id time with time zone
,txt_short varchar(990)
);
recreate table test_ns_05(
id varchar(1) character set utf8 collate unicode_ci_ai
,txt_short varchar(993)
);
recreate table test_ns_06(
id varchar(1) character set utf8 collate unicode_ci_ai
,txt_short varchar(992)
);
commit;
2021-04-26 20:07:00 +02:00
recreate view v_unioned as
select id, txt_broad from test
union all
select -1, 'qwerty'
from rdb$database rows 0;
commit;
"""
db = db_factory(init = init_sql)
query_map = {
########################## p e r s i s t e n t c o l u m n s ##################################
1000 : ( 'select txt_short from test a01 order by id' , 'Must NOT use refetch because length of non-key column is less than threshold' )
,1010 : ( 'select txt_broad from test a02 order by id' , 'MUST use refetch because length of non-key column is greater than threshold' )
,1020 : ( 'select txt_short from test a03 order by id rows 1' , 'MUST use refetch regardless on length of column because ROWS <N> presents' )
########################## c o m p u t e d c o l u m n s #####################################
,2000 : ( 'select id, computed_ts_dup from test order by id' , 'Must NOT use refetch because computed column is based on txt_short with length < threshold' )
,2010 : ( 'select id, computed_tb_dup from test order by id' , 'MUST use refetch because computed column is based on txt_broad which has length >= threshold' )
###################### p r e d i c a t e s [N O T] I N, A L L, A N Y ########################
,3000 : ( "select id from test a04 where '' in (select txt_short from test x04 where txt_short = '' order by id)" , '*** not [yet] commented ***' )
,3010 : ( "select id from test a05 where '' in (select txt_broad from test x05 where txt_broad = '' order by id)" , '*** not [yet] commented ***' )
,3020 : ( "select id from test a06 where '' not in (select txt_short from test x06 where txt_short>'' order by id)" , '*** not [yet] commented ***' )
,3030 : ( "select id from test a07 where '' not in (select txt_broad from test x07 where txt_broad>'' order by id)" , '*** not [yet] commented ***' )
,3040 : ( "select id from test a08 where '' > all (select id from test x08 where txt_short>'' order by id)" , '*** not [yet] commented ***' )
,3050 : ( "select id from test a09 where '' > all (select id from test x09 where txt_broad>'' order by id)" , '*** not [yet] commented ***' )
,3060 : ( "select id from test a10 where '' <> any (select id from test x10 where txt_short>'' order by id)" , '*** not [yet] commented ***' )
,3070 : ( "select id from test a11 where '' <> any (select id from test x11 where txt_broad>'' order by id)" , '*** not [yet] commented ***' )
######################################## e x i s t s ###########################################
# Predicate "EXISTS" must turn on refetching regardless of record length
# but only when "WHERE" has column which not present in "ORDER BY"
,4000 : ( "select id,txt_short from test a12 where exists(select 1 from test x12 where txt_short>'' order by id)"
,"MUST use refetch: column x12.txt_short not present in order by"
)
,4010 : ( "select id,txt_short from test a13 where exists(select 1 from test x13 where computed_id_dup > 0 order by id)"
,"Must NOT use refetch: ORDER BY list contains the single element: ID, and it is base for x13.computed_id_dup column"
)
,4020 : ( "select id,txt_short from test a14 where exists(select 1 from test x14 where computed_id_dup > 0 order by computed_id_dup)"
,"""
MUST use refetch! See letter from dimitr 28.12.2020 14:49
Sort procedure will get:
a KEY = result of evaluating 'computed_id_dup';
a VAL = value of the field 'ID' which is base for computing 'computed_id_dup'
Thus sorter will have a field which not equals to a key, which leads to refetch.
"""
)
,4030 : ( "select id,txt_short from test a15 where exists(select 1 from test x15 where f02>0 and f01>0 order by f01, f02)"
,"Must NOT use refetch: all persistent columns from WHERE expression (f01, f02) belong to ORDER BY list"
)
,4040 : ( "select id,txt_short from test a16 where exists(select 1 from test x16 where id>0 and f01>0 order by f01, f02)"
,"Must use refetch: one of columns from WHERE expr (id) does not belong to ORDER BY list"
)
,4050 : ( "select id,txt_short from test a17 where exists(select 1 from test x17 where computed_id_dup > 0 order by f01)"
,"Must use refetch: computed column in WHERE expr does not belong to ORDER BY list"
)
,4060 : ( "select id,txt_short from test a18 where exists(select 1 from test x18 where computed_guid > '' order by f01)"
,"Must NOT use refetch: computed column x18.computed_guid does is evaluated via GUID and does not refer to any columns"
)
,4070 : (
"""
with recursive
r as (
select a19.id, a19.txt_short
from test a19
where not exists(select * from test x where x.txt_short < a19.txt_short order by id)
UNION ALL
select i.id, i.txt_short
from test i
join r on i.id > r.id
and not exists( select * from test x where x.txt_short between r.txt_short and i.txt_short order by id )
)
select * from r
"""
,"MUST use refetch both in anchor and recursive parts"
)
###################################### v i e w s ###########################################
,5000 : ( 'select txt_broad from v_unioned v01 order by id' , 'Must NOT use refetch because view DDL includes UNION' )
################################# e x p r e s s i o n s #####################################
,6000 : ( 'select left(txt_broad, 50) as txt from test a21 order by id'
,"""
MUST use refetch because expression is based on column which has length >= threshold
(even if final length of expression result is much less than threshold)
"""
)
,6010 : ( 'select left( txt_short || txt_short, 2000) as txt from test a22 order by id'
,"""
Must NOT use refetch because expression is based on column which has length < threshold
(even if final length of expression result is much bigger than threshold)
"""
)
########### n o n - s y m m e t r i c a l k e y - v a l u e d a t a t y p e s #########
# Following data types in common case have no ability to get column value from a key:
# * International type text has a computed key
# * Different decimal float values sometimes have same keys
# * Date/time with time zones too.
# Because of this, a field of any such datatype that is specified in "order by" list, must also be involved
# in the non-key fields and sort will deal with such "concatenated" list.
# If total length of such list not exceeds InlineSortThreshold then sort will be done without refetch.
# Otherwise refetch will occur.
# See src/jrd/opt.cpp, OPT_gen_sort() and explanation from dimitr, letter 28.12.2020 16:44
,7000 : ( 'select * from test_ns_01 a23 order by id' , 'MUST use refetch' )
,7010 : ( 'select * from test_ns_02 a24 order by id' , 'Must NOT refetch' )
,7020 : ( 'select * from test_ns_03 order by id' , 'MUST use refetch' )
,7030 : ( 'select * from test_ns_04 order by id' , 'Must NOT use refetch' )
,7040 : ( 'select * from test_ns_05 order by id' , 'MUST use refetch' )
,7050 : ( 'select * from test_ns_06 order by id' , 'Must NOT use refetch' )
}
2021-04-26 20:07:00 +02:00
test_script = """
set plan on;
set explain on;
2021-12-22 20:23:11 +01:00
"""
2021-04-26 20:07:00 +02:00
###############################################################################
2021-04-26 20:07:00 +02:00
fb4x_expected_out = f"""
1000
{query_map[1000][0]}
{query_map[1000][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Sort (record length: 1036, key length: 8)
........-> Table "TEST" as "A01" Full Scan
2021-04-26 20:07:00 +02:00
1010
{query_map[1010][0]}
{query_map[1010][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Table "TEST" as "A02" Full Scan
2021-04-26 20:07:00 +02:00
1020
{query_map[1020][0]}
{query_map[1020][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> First N Records
........-> Refetch
............-> Sort (record length: 28, key length: 8)
................-> Table "TEST" as "A03" Full Scan
2021-04-26 20:07:00 +02:00
2000
{query_map[2000][0]}
{query_map[2000][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Sort (record length: 1036, key length: 8)
........-> Table "TEST" Full Scan
2021-04-26 20:07:00 +02:00
2010
{query_map[2010][0]}
{query_map[2010][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Table "TEST" Full Scan
2021-04-26 20:07:00 +02:00
3000
{query_map[3000][0]}
{query_map[3000][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Filter
........-> Sort (record length: 1036, key length: 8)
............-> Filter
................-> Table "TEST" as "X04" Full Scan
2021-04-26 20:07:00 +02:00
Select Expression
....-> Filter
........-> Table "TEST" as "A04" Full Scan
2021-04-26 20:07:00 +02:00
3010
{query_map[3010][0]}
{query_map[3010][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Filter
........-> Refetch
............-> Sort (record length: 28, key length: 8)
................-> Filter
....................-> Table "TEST" as "X05" Full Scan
2021-04-26 20:07:00 +02:00
Select Expression
....-> Filter
........-> Table "TEST" as "A05" Full Scan
2021-04-26 20:07:00 +02:00
3020
{query_map[3020][0]}
{query_map[3020][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Sort (record length: 1036, key length: 8)
........-> Filter
............-> Table "TEST" as "X06" Full Scan
2021-04-26 20:07:00 +02:00
Select Expression
....-> Sort (record length: 1036, key length: 8)
........-> Filter
............-> Table "TEST" as "X06" Full Scan
2021-04-26 20:07:00 +02:00
Select Expression
....-> Filter
........-> Table "TEST" as "A06" Full Scan
2021-04-26 20:07:00 +02:00
3030
{query_map[3030][0]}
{query_map[3030][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Filter
................-> Table "TEST" as "X07" Full Scan
2021-04-26 20:07:00 +02:00
Select Expression
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Filter
................-> Table "TEST" as "X07" Full Scan
2021-04-26 20:07:00 +02:00
Select Expression
....-> Filter
........-> Table "TEST" as "A07" Full Scan
2021-04-26 20:07:00 +02:00
3040
{query_map[3040][0]}
{query_map[3040][1]}
Select Expression
....-> Filter
........-> Sort (record length: 1036, key length: 8)
............-> Filter
................-> Table "TEST" as "X08" Full Scan
2021-04-26 20:07:00 +02:00
Select Expression
....-> Filter
........-> Table "TEST" as "A08" Full Scan
2021-04-26 20:07:00 +02:00
3050
{query_map[3050][0]}
{query_map[3050][1]}
Select Expression
....-> Filter
........-> Refetch
............-> Sort (record length: 28, key length: 8)
................-> Filter
....................-> Table "TEST" as "X09" Full Scan
2021-04-26 20:07:00 +02:00
Select Expression
....-> Filter
........-> Table "TEST" as "A09" Full Scan
2021-04-26 20:07:00 +02:00
3060
{query_map[3060][0]}
{query_map[3060][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Filter
........-> Sort (record length: 1036, key length: 8)
............-> Filter
................-> Table "TEST" as "X10" Full Scan
2021-04-26 20:07:00 +02:00
Select Expression
....-> Filter
........-> Table "TEST" as "A10" Full Scan
2021-04-26 20:07:00 +02:00
3070
{query_map[3070][0]}
{query_map[3070][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Filter
........-> Refetch
............-> Sort (record length: 28, key length: 8)
................-> Filter
....................-> Table "TEST" as "X11" Full Scan
2021-04-26 20:07:00 +02:00
Select Expression
....-> Filter
........-> Table "TEST" as "A11" Full Scan
4000
{query_map[4000][0]}
{query_map[4000][1]}
Select Expression
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Filter
................-> Table "TEST" as "X12" Full Scan
Select Expression
....-> Filter
........-> Table "TEST" as "A12" Full Scan
4010
{query_map[4010][0]}
{query_map[4010][1]}
Select Expression
....-> Sort (record length: 28, key length: 8)
........-> Filter
............-> Table "TEST" as "X13" Full Scan
Select Expression
....-> Filter
........-> Table "TEST" as "A13" Full Scan
4020
{query_map[4020][0]}
{query_map[4020][1]}
Select Expression
....-> Refetch
........-> Sort (record length: 36, key length: 12)
............-> Filter
................-> Table "TEST" as "X14" Full Scan
Select Expression
....-> Filter
........-> Table "TEST" as "A14" Full Scan
4030
{query_map[4030][0]}
{query_map[4030][1]}
Select Expression
....-> Sort (record length: 36, key length: 16)
........-> Filter
............-> Table "TEST" as "X15" Full Scan
Select Expression
....-> Filter
........-> Table "TEST" as "A15" Full Scan
2021-04-26 20:07:00 +02:00
4040
{query_map[4040][0]}
{query_map[4040][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Refetch
........-> Sort (record length: 36, key length: 16)
............-> Filter
................-> Table "TEST" as "X16" Full Scan
Select Expression
....-> Filter
........-> Table "TEST" as "A16" Full Scan
2021-04-26 20:07:00 +02:00
4050
{query_map[4050][0]}
{query_map[4050][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Filter
................-> Table "TEST" as "X17" Full Scan
Select Expression
....-> Filter
........-> Table "TEST" as "A17" Full Scan
2021-04-26 20:07:00 +02:00
4060
{query_map[4060][0]}
{query_map[4060][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Sort (record length: 28, key length: 8)
........-> Filter
............-> Table "TEST" as "X18" Full Scan
2021-04-26 20:07:00 +02:00
Select Expression
....-> Filter
........-> Table "TEST" as "A18" Full Scan
2021-04-26 20:07:00 +02:00
4070
{query_map[4070][0]}
{query_map[4070][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Filter
................-> Table "TEST" as "R X" Full Scan
2021-04-26 20:07:00 +02:00
Select Expression
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Filter
................-> Table "TEST" as "R X" Full Scan
2021-04-26 20:07:00 +02:00
Select Expression
....-> Recursion
........-> Filter
............-> Table "TEST" as "R A19" Full Scan
........-> Filter
............-> Table "TEST" as "R I" Full Scan
2021-04-26 20:07:00 +02:00
5000
{query_map[5000][0]}
{query_map[5000][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Sort (record length: 4044, key length: 8)
........-> First N Records
............-> Union
................-> Table "TEST" as "V01 TEST" Full Scan
................-> Table "RDB$DATABASE" as "V01 RDB$DATABASE" Full Scan
2021-04-26 20:07:00 +02:00
6000
{query_map[6000][0]}
{query_map[6000][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Table "TEST" as "A21" Full Scan
2021-04-26 20:07:00 +02:00
6010
{query_map[6010][0]}
{query_map[6010][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Sort (record length: 1036, key length: 8)
........-> Table "TEST" as "A22" Full Scan
2021-04-26 20:07:00 +02:00
7000
{query_map[7000][0]}
{query_map[7000][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Refetch
........-> Sort (record length: 44, key length: 24)
............-> Table "TEST_NS_01" as "A23" Full Scan
2021-04-26 20:07:00 +02:00
7010
{query_map[7010][0]}
{query_map[7010][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Sort (record length: 1052, key length: 24)
........-> Table "TEST_NS_02" as "A24" Full Scan
2021-04-26 20:07:00 +02:00
7020
{query_map[7020][0]}
{query_map[7020][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Refetch
........-> Sort (record length: 36, key length: 12)
............-> Table "TEST_NS_03" Full Scan
2021-04-26 20:07:00 +02:00
7030
{query_map[7030][0]}
{query_map[7030][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Sort (record length: 1036, key length: 12)
........-> Table "TEST_NS_04" Full Scan
2021-04-26 20:07:00 +02:00
7040
{query_map[7040][0]}
{query_map[7040][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Refetch
........-> Sort (record length: 36, key length: 12)
............-> Table "TEST_NS_05" Full Scan
2021-04-26 20:07:00 +02:00
7050
{query_map[7050][0]}
{query_map[7050][1]}
2021-04-26 20:07:00 +02:00
Select Expression
....-> Sort (record length: 1036, key length: 12)
........-> Table "TEST_NS_06" Full Scan
2021-12-22 20:23:11 +01:00
"""
2021-04-26 20:07:00 +02:00
###############################################################################
fb5x_expected_out = f"""
1000
{query_map[1000][0]}
{query_map[1000][1]}
Select Expression
....-> Sort (record length: 1036, key length: 8)
........-> Table "TEST" as "A01" Full Scan
1010
{query_map[1010][0]}
{query_map[1010][1]}
Select Expression
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Table "TEST" as "A02" Full Scan
1020
{query_map[1020][0]}
{query_map[1020][1]}
Select Expression
....-> First N Records
........-> Refetch
............-> Sort (record length: 28, key length: 8)
................-> Table "TEST" as "A03" Full Scan
2000
{query_map[2000][0]}
{query_map[2000][1]}
Select Expression
....-> Sort (record length: 1036, key length: 8)
........-> Table "TEST" Full Scan
2010
{query_map[2010][0]}
{query_map[2010][1]}
Select Expression
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Table "TEST" Full Scan
3000
{query_map[3000][0]}
{query_map[3000][1]}
Sub-query (invariant)
....-> Filter
........-> Sort (record length: 1036, key length: 8)
............-> Filter
................-> Table "TEST" as "X04" Full Scan
Select Expression
....-> Filter (preliminary)
........-> Table "TEST" as "A04" Full Scan
3010
{query_map[3010][0]}
{query_map[3010][1]}
Sub-query (invariant)
....-> Filter
........-> Refetch
............-> Sort (record length: 28, key length: 8)
................-> Filter
....................-> Table "TEST" as "X05" Full Scan
Select Expression
....-> Filter (preliminary)
........-> Table "TEST" as "A05" Full Scan
3020
{query_map[3020][0]}
{query_map[3020][1]}
Select Expression
....-> Sort (record length: 1036, key length: 8)
........-> Filter
............-> Table "TEST" as "X06" Full Scan
Select Expression
....-> Sort (record length: 1036, key length: 8)
........-> Filter
............-> Table "TEST" as "X06" Full Scan
Select Expression
....-> Filter (preliminary)
........-> Table "TEST" as "A06" Full Scan
3030
{query_map[3030][0]}
{query_map[3030][1]}
Select Expression
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Filter
................-> Table "TEST" as "X07" Full Scan
Select Expression
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Filter
................-> Table "TEST" as "X07" Full Scan
Select Expression
....-> Filter (preliminary)
........-> Table "TEST" as "A07" Full Scan
3040
{query_map[3040][0]}
{query_map[3040][1]}
Sub-query (invariant)
....-> Filter
........-> Sort (record length: 1036, key length: 8)
............-> Filter
................-> Table "TEST" as "X08" Full Scan
Select Expression
....-> Filter (preliminary)
........-> Table "TEST" as "A08" Full Scan
3050
{query_map[3050][0]}
{query_map[3050][1]}
Sub-query (invariant)
....-> Filter
........-> Refetch
............-> Sort (record length: 28, key length: 8)
................-> Filter
....................-> Table "TEST" as "X09" Full Scan
Select Expression
....-> Filter (preliminary)
........-> Table "TEST" as "A09" Full Scan
3060
{query_map[3060][0]}
{query_map[3060][1]}
Sub-query (invariant)
....-> Filter
........-> Sort (record length: 1036, key length: 8)
............-> Filter
................-> Table "TEST" as "X10" Full Scan
Select Expression
....-> Filter (preliminary)
........-> Table "TEST" as "A10" Full Scan
3070
{query_map[3070][0]}
{query_map[3070][1]}
Sub-query (invariant)
....-> Filter
........-> Refetch
............-> Sort (record length: 28, key length: 8)
................-> Filter
....................-> Table "TEST" as "X11" Full Scan
Select Expression
....-> Filter (preliminary)
........-> Table "TEST" as "A11" Full Scan
4000
{query_map[4000][0]}
{query_map[4000][1]}
Sub-query (invariant)
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Filter
................-> Table "TEST" as "X12" Full Scan
Select Expression
....-> Filter (preliminary)
........-> Table "TEST" as "A12" Full Scan
4010
{query_map[4010][0]}
{query_map[4010][1]}
Sub-query (invariant)
....-> Sort (record length: 28, key length: 8)
........-> Filter
............-> Table "TEST" as "X13" Full Scan
Select Expression
....-> Filter (preliminary)
........-> Table "TEST" as "A13" Full Scan
4020
{query_map[4020][0]}
{query_map[4020][1]}
Sub-query (invariant)
....-> Refetch
........-> Sort (record length: 36, key length: 12)
............-> Filter
................-> Table "TEST" as "X14" Full Scan
Select Expression
....-> Filter (preliminary)
........-> Table "TEST" as "A14" Full Scan
4030
{query_map[4030][0]}
{query_map[4030][1]}
Sub-query (invariant)
....-> Sort (record length: 36, key length: 16)
........-> Filter
............-> Table "TEST" as "X15" Full Scan
Select Expression
....-> Filter (preliminary)
........-> Table "TEST" as "A15" Full Scan
4040
{query_map[4040][0]}
{query_map[4040][1]}
Sub-query (invariant)
....-> Refetch
........-> Sort (record length: 36, key length: 16)
............-> Filter
................-> Table "TEST" as "X16" Full Scan
Select Expression
....-> Filter (preliminary)
........-> Table "TEST" as "A16" Full Scan
4050
{query_map[4050][0]}
{query_map[4050][1]}
Sub-query (invariant)
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Filter
................-> Table "TEST" as "X17" Full Scan
Select Expression
....-> Filter (preliminary)
........-> Table "TEST" as "A17" Full Scan
4060
{query_map[4060][0]}
{query_map[4060][1]}
Sub-query (invariant)
....-> Sort (record length: 28, key length: 8)
........-> Filter
............-> Table "TEST" as "X18" Full Scan
Select Expression
....-> Filter (preliminary)
........-> Table "TEST" as "A18" Full Scan
4070
{query_map[4070][0]}
{query_map[4070][1]}
Sub-query
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Filter
................-> Table "TEST" as "R X" Full Scan
Sub-query
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Filter
................-> Table "TEST" as "R X" Full Scan
Select Expression
....-> Recursion
........-> Filter
............-> Table "TEST" as "R A19" Full Scan
........-> Filter
............-> Table "TEST" as "R I" Full Scan
5000
{query_map[5000][0]}
{query_map[5000][1]}
Select Expression
....-> Sort (record length: 4044, key length: 8)
........-> First N Records
............-> Union
................-> Table "TEST" as "V01 TEST" Full Scan
................-> Table "RDB$DATABASE" as "V01 RDB$DATABASE" Full Scan
6000
{query_map[6000][0]}
{query_map[6000][1]}
Select Expression
....-> Refetch
........-> Sort (record length: 28, key length: 8)
............-> Table "TEST" as "A21" Full Scan
6010
{query_map[6010][0]}
{query_map[6010][1]}
Select Expression
....-> Sort (record length: 1036, key length: 8)
........-> Table "TEST" as "A22" Full Scan
7000
{query_map[7000][0]}
{query_map[7000][1]}
Select Expression
....-> Refetch
........-> Sort (record length: 44, key length: 24)
............-> Table "TEST_NS_01" as "A23" Full Scan
7010
{query_map[7010][0]}
{query_map[7010][1]}
Select Expression
....-> Sort (record length: 1052, key length: 24)
........-> Table "TEST_NS_02" as "A24" Full Scan
7020
{query_map[7020][0]}
{query_map[7020][1]}
Select Expression
....-> Refetch
........-> Sort (record length: 36, key length: 12)
............-> Table "TEST_NS_03" Full Scan
7030
{query_map[7030][0]}
{query_map[7030][1]}
Select Expression
....-> Sort (record length: 1036, key length: 12)
........-> Table "TEST_NS_04" Full Scan
7040
{query_map[7040][0]}
{query_map[7040][1]}
Select Expression
....-> Refetch
........-> Sort (record length: 36, key length: 12)
............-> Table "TEST_NS_05" Full Scan
7050
{query_map[7050][0]}
{query_map[7050][1]}
Select Expression
....-> Sort (record length: 1036, key length: 12)
........-> Table "TEST_NS_06" Full Scan
"""
act = python_act('db')
#-----------------------------------------------------------
def replace_leading(source, char="."):
stripped = source.lstrip()
return char * (len(source) - len(stripped)) + stripped
#-----------------------------------------------------------
2021-04-26 20:07:00 +02:00
@pytest.mark.version('>=4.0')
def test_1(act: Action, capsys):
with act.db.connect() as con:
cur = con.cursor()
for q_idx, q_tuple in query_map.items():
test_sql, qry_comment = q_tuple[:2]
ps = cur.prepare(test_sql)
print(q_idx)
print(test_sql)
print(qry_comment)
print( '\n'.join([replace_leading(s) for s in ps.detailed_plan.split('\n')]) )
ps.free()
act.expected_stdout = fb4x_expected_out if act.is_version('<5') else fb5x_expected_out
act.stdout = capsys.readouterr().out
2022-01-21 18:49:26 +01:00
assert act.clean_stdout == act.clean_expected_stdout