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 :
2024-09-02 10:22:00 +02:00
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
2024-09-02 10:22: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
2024-09-02 10:22: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
2022-02-02 15:46:19 +01:00
FBTEST : bugs . core_2650
2024-09-02 10:22:00 +02:00
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 / 901 b4ced9a3615929e0027d42ebb2392e943b205
Checked on 6.0 .0 .447 - 901 b4ce , 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
2024-09-02 10:22: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 )
) ;
2024-09-02 10:22:00 +02:00
commit ;
2021-04-26 20:07:00 +02:00
2024-09-02 10:22: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
2024-09-02 10:22: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
2024-09-02 10:22:00 +02:00
###############################################################################
2021-04-26 20:07:00 +02:00
2024-09-02 10:22: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
2024-09-02 10:22:00 +02:00
. . . . - > Sort ( record length : 1036 , key length : 8 )
. . . . . . . . - > Table " TEST " as " A01 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
1010
{ query_map [ 1010 ] [ 0 ] }
{ query_map [ 1010 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Refetch
. . . . . . . . - > Sort ( record length : 28 , key length : 8 )
. . . . . . . . . . . . - > Table " TEST " as " A02 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
1020
{ query_map [ 1020 ] [ 0 ] }
{ query_map [ 1020 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > 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
2024-09-02 10:22:00 +02:00
2000
{ query_map [ 2000 ] [ 0 ] }
{ query_map [ 2000 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Sort ( record length : 1036 , key length : 8 )
. . . . . . . . - > Table " TEST " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
2010
{ query_map [ 2010 ] [ 0 ] }
{ query_map [ 2010 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Refetch
. . . . . . . . - > Sort ( record length : 28 , key length : 8 )
. . . . . . . . . . . . - > Table " TEST " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
3000
{ query_map [ 3000 ] [ 0 ] }
{ query_map [ 3000 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > 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
2024-09-02 10:22:00 +02:00
. . . . - > Filter
. . . . . . . . - > Table " TEST " as " A04 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
3010
{ query_map [ 3010 ] [ 0 ] }
{ query_map [ 3010 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > 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
2024-09-02 10:22:00 +02:00
. . . . - > Filter
. . . . . . . . - > Table " TEST " as " A05 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
3020
{ query_map [ 3020 ] [ 0 ] }
{ query_map [ 3020 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Sort ( record length : 1036 , key length : 8 )
. . . . . . . . - > Filter
. . . . . . . . . . . . - > Table " TEST " as " X06 " Full Scan
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Sort ( record length : 1036 , key length : 8 )
. . . . . . . . - > Filter
. . . . . . . . . . . . - > Table " TEST " as " X06 " Full Scan
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Filter
. . . . . . . . - > Table " TEST " as " A06 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
3030
{ query_map [ 3030 ] [ 0 ] }
{ query_map [ 3030 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > 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
2024-09-02 10:22:00 +02:00
. . . . - > 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
2024-09-02 10:22:00 +02:00
. . . . - > Filter
. . . . . . . . - > Table " TEST " as " A07 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22: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
2024-09-02 10:22:00 +02:00
. . . . - > Filter
. . . . . . . . - > Table " TEST " as " A08 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22: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
2024-09-02 10:22:00 +02:00
. . . . - > Filter
. . . . . . . . - > Table " TEST " as " A09 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
3060
{ query_map [ 3060 ] [ 0 ] }
{ query_map [ 3060 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > 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
2024-09-02 10:22:00 +02:00
. . . . - > Filter
. . . . . . . . - > Table " TEST " as " A10 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
3070
{ query_map [ 3070 ] [ 0 ] }
{ query_map [ 3070 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > 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
2024-09-02 10:22:00 +02:00
. . . . - > 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
2024-09-02 10:22:00 +02:00
4040
{ query_map [ 4040 ] [ 0 ] }
{ query_map [ 4040 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > 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
2024-09-02 10:22:00 +02:00
4050
{ query_map [ 4050 ] [ 0 ] }
{ query_map [ 4050 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > 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
2024-09-02 10:22:00 +02:00
4060
{ query_map [ 4060 ] [ 0 ] }
{ query_map [ 4060 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Sort ( record length : 28 , key length : 8 )
. . . . . . . . - > Filter
. . . . . . . . . . . . - > Table " TEST " as " X18 " Full Scan
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Filter
. . . . . . . . - > Table " TEST " as " A18 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
4070
{ query_map [ 4070 ] [ 0 ] }
{ query_map [ 4070 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > 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
2024-09-02 10:22:00 +02:00
. . . . - > 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
2024-09-02 10:22:00 +02:00
. . . . - > 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
2024-09-02 10:22:00 +02:00
5000
{ query_map [ 5000 ] [ 0 ] }
{ query_map [ 5000 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > 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
2024-09-02 10:22:00 +02:00
6000
{ query_map [ 6000 ] [ 0 ] }
{ query_map [ 6000 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Refetch
. . . . . . . . - > Sort ( record length : 28 , key length : 8 )
. . . . . . . . . . . . - > Table " TEST " as " A21 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
6010
{ query_map [ 6010 ] [ 0 ] }
{ query_map [ 6010 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Sort ( record length : 1036 , key length : 8 )
. . . . . . . . - > Table " TEST " as " A22 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
7000
{ query_map [ 7000 ] [ 0 ] }
{ query_map [ 7000 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Refetch
. . . . . . . . - > Sort ( record length : 44 , key length : 24 )
. . . . . . . . . . . . - > Table " TEST_NS_01 " as " A23 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
7010
{ query_map [ 7010 ] [ 0 ] }
{ query_map [ 7010 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Sort ( record length : 1052 , key length : 24 )
. . . . . . . . - > Table " TEST_NS_02 " as " A24 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
7020
{ query_map [ 7020 ] [ 0 ] }
{ query_map [ 7020 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Refetch
. . . . . . . . - > Sort ( record length : 36 , key length : 12 )
. . . . . . . . . . . . - > Table " TEST_NS_03 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
7030
{ query_map [ 7030 ] [ 0 ] }
{ query_map [ 7030 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Sort ( record length : 1036 , key length : 12 )
. . . . . . . . - > Table " TEST_NS_04 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
7040
{ query_map [ 7040 ] [ 0 ] }
{ query_map [ 7040 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Refetch
. . . . . . . . - > Sort ( record length : 36 , key length : 12 )
. . . . . . . . . . . . - > Table " TEST_NS_05 " Full Scan
2021-04-26 20:07:00 +02:00
2024-09-02 10:22:00 +02:00
7050
{ query_map [ 7050 ] [ 0 ] }
{ query_map [ 7050 ] [ 1 ] }
2021-04-26 20:07:00 +02:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > 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
2024-09-02 10:22:00 +02:00
###############################################################################
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
fb5x_expected_out = f """
1000
{ query_map [ 1000 ] [ 0 ] }
{ query_map [ 1000 ] [ 1 ] }
2023-03-04 17:19:28 +01:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Sort ( record length : 1036 , key length : 8 )
. . . . . . . . - > Table " TEST " as " A01 " Full Scan
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
1010
{ query_map [ 1010 ] [ 0 ] }
{ query_map [ 1010 ] [ 1 ] }
2023-03-04 17:19:28 +01:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Refetch
. . . . . . . . - > Sort ( record length : 28 , key length : 8 )
. . . . . . . . . . . . - > Table " TEST " as " A02 " Full Scan
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
1020
{ query_map [ 1020 ] [ 0 ] }
{ query_map [ 1020 ] [ 1 ] }
2023-03-04 17:19:28 +01:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > First N Records
. . . . . . . . - > Refetch
. . . . . . . . . . . . - > Sort ( record length : 28 , key length : 8 )
. . . . . . . . . . . . . . . . - > Table " TEST " as " A03 " Full Scan
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
2000
{ query_map [ 2000 ] [ 0 ] }
{ query_map [ 2000 ] [ 1 ] }
2023-03-04 17:19:28 +01:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Sort ( record length : 1036 , key length : 8 )
. . . . . . . . - > Table " TEST " Full Scan
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
2010
{ query_map [ 2010 ] [ 0 ] }
{ query_map [ 2010 ] [ 1 ] }
2023-03-04 17:19:28 +01:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Refetch
. . . . . . . . - > Sort ( record length : 28 , key length : 8 )
. . . . . . . . . . . . - > Table " TEST " Full Scan
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
3000
{ query_map [ 3000 ] [ 0 ] }
{ query_map [ 3000 ] [ 1 ] }
2023-03-04 17:19:28 +01:00
Sub - query ( invariant )
2024-09-02 10:22:00 +02:00
. . . . - > Filter
. . . . . . . . - > Sort ( record length : 1036 , key length : 8 )
. . . . . . . . . . . . - > Filter
. . . . . . . . . . . . . . . . - > Table " TEST " as " X04 " Full Scan
2023-03-04 17:19:28 +01:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Filter ( preliminary )
. . . . . . . . - > Table " TEST " as " A04 " Full Scan
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
3010
{ query_map [ 3010 ] [ 0 ] }
{ query_map [ 3010 ] [ 1 ] }
2023-03-04 17:19:28 +01:00
Sub - query ( invariant )
2024-09-02 10:22:00 +02:00
. . . . - > 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 ] }
2023-03-04 17:19:28 +01:00
Sub - query ( invariant )
2024-09-02 10:22:00 +02:00
. . . . - > Filter
. . . . . . . . - > Sort ( record length : 1036 , key length : 8 )
. . . . . . . . . . . . - > Filter
. . . . . . . . . . . . . . . . - > Table " TEST " as " X08 " Full Scan
2023-03-04 17:19:28 +01:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Filter ( preliminary )
. . . . . . . . - > Table " TEST " as " A08 " Full Scan
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
3050
{ query_map [ 3050 ] [ 0 ] }
{ query_map [ 3050 ] [ 1 ] }
2023-03-04 17:19:28 +01:00
Sub - query ( invariant )
2024-09-02 10:22:00 +02:00
. . . . - > 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 ] }
2023-03-04 17:19:28 +01:00
Sub - query ( invariant )
2024-09-02 10:22:00 +02:00
. . . . - > Filter
. . . . . . . . - > Sort ( record length : 1036 , key length : 8 )
. . . . . . . . . . . . - > Filter
. . . . . . . . . . . . . . . . - > Table " TEST " as " X10 " Full Scan
2023-03-04 17:19:28 +01:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Filter ( preliminary )
. . . . . . . . - > Table " TEST " as " A10 " Full Scan
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
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 ] }
2023-03-04 17:19:28 +01:00
Sub - query ( invariant )
2024-09-02 10:22:00 +02:00
. . . . - > Refetch
. . . . . . . . - > Sort ( record length : 28 , key length : 8 )
. . . . . . . . . . . . - > Filter
. . . . . . . . . . . . . . . . - > Table " TEST " as " X12 " Full Scan
2023-03-04 17:19:28 +01:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Filter ( preliminary )
. . . . . . . . - > Table " TEST " as " A12 " Full Scan
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
4010
{ query_map [ 4010 ] [ 0 ] }
{ query_map [ 4010 ] [ 1 ] }
2023-03-04 17:19:28 +01:00
Sub - query ( invariant )
2024-09-02 10:22:00 +02:00
. . . . - > Sort ( record length : 28 , key length : 8 )
. . . . . . . . - > Filter
. . . . . . . . . . . . - > Table " TEST " as " X13 " Full Scan
2023-03-04 17:19:28 +01:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Filter ( preliminary )
. . . . . . . . - > Table " TEST " as " A13 " Full Scan
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
4020
{ query_map [ 4020 ] [ 0 ] }
{ query_map [ 4020 ] [ 1 ] }
2023-03-04 17:19:28 +01:00
Sub - query ( invariant )
2024-09-02 10:22:00 +02:00
. . . . - > Refetch
. . . . . . . . - > Sort ( record length : 36 , key length : 12 )
. . . . . . . . . . . . - > Filter
. . . . . . . . . . . . . . . . - > Table " TEST " as " X14 " Full Scan
2023-03-04 17:19:28 +01:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Filter ( preliminary )
. . . . . . . . - > Table " TEST " as " A14 " Full Scan
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
4030
{ query_map [ 4030 ] [ 0 ] }
{ query_map [ 4030 ] [ 1 ] }
2023-03-04 17:19:28 +01:00
Sub - query ( invariant )
2024-09-02 10:22:00 +02:00
. . . . - > Sort ( record length : 36 , key length : 16 )
. . . . . . . . - > Filter
. . . . . . . . . . . . - > Table " TEST " as " X15 " Full Scan
2023-03-04 17:19:28 +01:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Filter ( preliminary )
. . . . . . . . - > Table " TEST " as " A15 " Full Scan
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
4040
{ query_map [ 4040 ] [ 0 ] }
{ query_map [ 4040 ] [ 1 ] }
2023-03-04 17:19:28 +01:00
Sub - query ( invariant )
2024-09-02 10:22:00 +02:00
. . . . - > Refetch
. . . . . . . . - > Sort ( record length : 36 , key length : 16 )
. . . . . . . . . . . . - > Filter
. . . . . . . . . . . . . . . . - > Table " TEST " as " X16 " Full Scan
2023-03-04 17:19:28 +01:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Filter ( preliminary )
. . . . . . . . - > Table " TEST " as " A16 " Full Scan
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
4050
{ query_map [ 4050 ] [ 0 ] }
{ query_map [ 4050 ] [ 1 ] }
2023-03-04 17:19:28 +01:00
Sub - query ( invariant )
2024-09-02 10:22:00 +02:00
. . . . - > Refetch
. . . . . . . . - > Sort ( record length : 28 , key length : 8 )
. . . . . . . . . . . . - > Filter
. . . . . . . . . . . . . . . . - > Table " TEST " as " X17 " Full Scan
2023-03-04 17:19:28 +01:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Filter ( preliminary )
. . . . . . . . - > Table " TEST " as " A17 " Full Scan
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
4060
{ query_map [ 4060 ] [ 0 ] }
{ query_map [ 4060 ] [ 1 ] }
2023-03-04 17:19:28 +01:00
Sub - query ( invariant )
2024-09-02 10:22:00 +02:00
. . . . - > Sort ( record length : 28 , key length : 8 )
. . . . . . . . - > Filter
. . . . . . . . . . . . - > Table " TEST " as " X18 " Full Scan
2023-03-04 17:19:28 +01:00
Select Expression
2024-09-02 10:22:00 +02:00
. . . . - > Filter ( preliminary )
. . . . . . . . - > Table " TEST " as " A18 " Full Scan
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
4070
{ query_map [ 4070 ] [ 0 ] }
{ query_map [ 4070 ] [ 1 ] }
2023-03-04 17:19:28 +01:00
Sub - query
2024-09-02 10:22:00 +02:00
. . . . - > Refetch
. . . . . . . . - > Sort ( record length : 28 , key length : 8 )
. . . . . . . . . . . . - > Filter
. . . . . . . . . . . . . . . . - > Table " TEST " as " R X " Full Scan
2023-03-04 17:19:28 +01:00
Sub - query
2024-09-02 10:22:00 +02:00
. . . . - > 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
"""
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
act = python_act ( ' db ' )
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
#-----------------------------------------------------------
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
def replace_leading ( source , char = " . " ) :
stripped = source . lstrip ( )
return char * ( len ( source ) - len ( stripped ) ) + stripped
2023-03-04 17:19:28 +01:00
2024-09-02 10:22:00 +02:00
#-----------------------------------------------------------
2023-03-04 17:19:28 +01:00
2021-04-26 20:07:00 +02:00
@pytest.mark.version ( ' >=4.0 ' )
2024-09-02 10:22:00 +02:00
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 ( )
2023-03-04 17:19:28 +01:00
act . expected_stdout = fb4x_expected_out if act . is_version ( ' <5 ' ) else fb5x_expected_out
2024-09-02 10:22:00 +02:00
act . stdout = capsys . readouterr ( ) . out
2022-01-21 18:49:26 +01:00
assert act . clean_stdout == act . clean_expected_stdout