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

193 lines
7.4 KiB
Python

#coding:utf-8
#
# id: bugs.gh_6875
# title: Significant performance regression of SIMILAR TO and SUBSTRING(SIMILAR) when pattern is taken from variable (rather than directly specified)
# decription:
# https://github.com/FirebirdSQL/firebird/issues/6875
#
# Confirmed poor performance in 5.0.0.88 (before fix):
# in PSQL explicitly
# variable specified
# ----------------------
# * for SIMILAR TO: 11.40" 2.23"
# * for SUBSTRING...SIMILAR: 42.02" 1.37"
#
# Checked 4.0.1.2523 and 5.0.0.89 -- all OK.
# Performance in 5.0.0.89 (intermediate build 02.07.2021 14:43) after fix:
# in PSQL explicitly
# variable specified
# ----------------------
# * for SIMILAR TO: 1.27" 1.15"
# * for SUBSTRING...SIMILAR: 2.02" 2.00"
#
# Performance in 4.0.1.2523 (intermediate build 02.07.2021 18:55) after fix:
# in PSQL explicitly
# variable specified
# ----------------------
# * for SIMILAR TO: 1.03" 1.06"
# * for SUBSTRING...SIMILAR: 1.96" 1.97"
#
# So, values became almost the same and, moreover, performance was greatly improved.
#
# Test checks ratio between elapsed times and compares it with thresholds.
# Currently both SIMILAR TO and SUBSTRING...SIMILAR use the same thresholds = 1.30.
#
# tracker_id:
# min_versions: ['4.0.1']
# versions: 4.0.1
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
# version: 4.0.1
# resources: None
substitutions_1 = []
init_script_1 = """"""
db_1 = db_factory(sql_dialect=3, init=init_script_1)
test_script_1 = """
set bail on;
set list on;
set term ^;
create or alter procedure sp_similar_to_test (
N integer,
V integer)
as
declare nums varchar(16) = '[-+]?[0-9]{1,10}';
declare b boolean;
begin
while (n > 0) do
begin
if (v = 1) then
b = '5' similar to nums; -------------------- [ 1 ]
else if (v = 2) then
b = '5' similar to '[-+]?[0-9]{1,10}'; ------ [ 2 ]
n = n - 1;
end
end
^
create or alter procedure sp_substring_similar_test (
N integer,
V integer)
as
declare p varchar(100) = '%/#*(=){3,}#"%#"(=){3,}#*/%';
declare s varchar(1000);
begin
while (n > 0) do
begin
if (v = 1) then
s = substring('
aaa
/*==== comment between "equal" characters ====*/
bbb
ccc
ddd
eee
fff
jjj
' similar p escape '#');
else if (v = 2) then
s = substring('
aaa
/*==== comment between "equal" characters ====*/
bbb
ccc
ddd
eee
fff
jjj
' similar '%/#*(=){3,}#"%#"(=){3,}#*/%' escape '#');
n = n - 1;
end
end
^
commit
^
execute block returns(msg_similar2 varchar(255), msg_subs_sim varchar(255)) as
declare t0_similar_to timestamp;
declare t0_subs_simil timestamp;
declare elap_similar2_pattern_in_psql_var int;
declare elap_similar2_pattern_explicitly int;
declare elap_subs_sim_pattern_in_psql_var int;
declare elap_subs_sim_pattern_explicitly int;
-- ##############################
-- ### T H R E S H O L D S ###
-- ##############################
declare SIMILAR2_THRESHOLD double precision = 1.30;
declare SUBS_SIM_THRESHOLD double precision = 1.30;
begin
t0_similar_to = 'now';
execute procedure sp_similar_to_test(1000000, 1);
elap_similar2_pattern_in_psql_var = datediff(millisecond from t0_similar_to to cast('now' as timestamp));
-- rdb$set_context('USER_SESSION', 'SIMILAR2_PATTERN_DECLARED_IN_PSQL_VAR', datediff(millisecond from t0_similar_to to cast('now' as timestamp)));
t0_similar_to = 'now';
execute procedure sp_similar_to_test(1000000, 2);
elap_similar2_pattern_explicitly = datediff(millisecond from t0_similar_to to cast('now' as timestamp));
-- rdb$set_context('USER_SESSION', 'SIMILAR2_PATTERN_EXPLICITLY_SPECIFIED', datediff(millisecond from t0_similar_to to cast('now' as timestamp)));
t0_subs_simil = 'now';
execute procedure sp_substring_similar_test(100000, 1);
elap_subs_sim_pattern_in_psql_var = datediff(millisecond from t0_subs_simil to cast('now' as timestamp));
--rdb$set_context('USER_SESSION', 'SUBS_SIM_PATTERN_DECLARED_IN_PSQL_VAR', datediff(millisecond from t0_subs_simil to cast('now' as timestamp)));
t0_subs_simil = 'now';
execute procedure sp_substring_similar_test(100000, 2);
elap_subs_sim_pattern_explicitly = datediff(millisecond from t0_subs_simil to cast('now' as timestamp));
-- rdb$set_context('USER_SESSION', 'SUBS_SIM_PATTERN_EXPLICITLY_SPECIFIED', datediff(millisecond from t0_subs_simil to cast('now' as timestamp)));
if ( 1.00 * elap_similar2_pattern_in_psql_var / elap_similar2_pattern_explicitly > SIMILAR2_THRESHOLD ) then
msg_similar2 = 'INACCEPTABLE: '
|| elap_similar2_pattern_in_psql_var
|| 's == vs == '
|| elap_similar2_pattern_explicitly || 's'
|| ' - greater than treshold = ' || SIMILAR2_THRESHOLD
;
else
msg_similar2 = 'Acceptable.';
if ( 1.00 * elap_subs_sim_pattern_in_psql_var / elap_subs_sim_pattern_explicitly > SUBS_SIM_THRESHOLD ) then
msg_subs_sim = 'INACCEPTABLE: '
|| elap_subs_sim_pattern_in_psql_var
|| 'ms == vs == '
|| elap_subs_sim_pattern_explicitly || 'ms'
|| ' - greater than treshold = ' || SIMILAR2_THRESHOLD
;
else
msg_subs_sim = 'Acceptable.';
suspend;
end
^
set term ;^
commit;
"""
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
MSG_SIMILAR2 Acceptable.
MSG_SUBS_SIM Acceptable.
"""
@pytest.mark.version('>=4.0.1')
def test_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_stdout == act_1.clean_expected_stdout