mirror of
https://github.com/FirebirdSQL/firebird-qa.git
synced 2025-01-23 22:13:05 +01:00
127 lines
3.9 KiB
Python
127 lines
3.9 KiB
Python
#coding:utf-8
|
|
|
|
"""
|
|
ID: issue-4310
|
|
ISSUE: 4310
|
|
TITLE: DELETE FROM MON$STATEMENTS does not interrupt a longish fetch
|
|
DESCRIPTION:
|
|
NOTES:
|
|
[02.11.2019]
|
|
restored DB state must be changed to full shutdown in order to make sure tha all attachments are gone.
|
|
Otherwise one may get:
|
|
Error while dropping database
|
|
- SQLCODE: -901
|
|
- lock time-out on wait transaction
|
|
- object E:\\QA\\FBT-REPO\\TMP\\BUGS.CORE_3977.FDB is in use
|
|
This is actual for 4.0+ SS/SC when ExtConnPoolLifeTime > 0.
|
|
JIRA: CORE-3977
|
|
FBTEST: bugs.core_3977
|
|
"""
|
|
|
|
import pytest
|
|
import subprocess
|
|
import time
|
|
from pathlib import Path
|
|
from firebird.qa import *
|
|
|
|
init_script = """
|
|
create sequence g;
|
|
commit;
|
|
"""
|
|
|
|
db = db_factory(init=init_script)
|
|
|
|
act = python_act('db', substitutions=[('^((?!RECORDS AFFECTED:|RESULT_MSG).)*$', '')])
|
|
|
|
expected_stdout = """
|
|
DEL FROM MON$STTM: RECORDS AFFECTED: 2
|
|
CHECK RESULTS LOG: RESULT_MSG OK: QUERY WAS INTERRUPTED IN THE MIDDLE POINT.
|
|
CHECK RESULTS LOG: RECORDS AFFECTED: 1
|
|
"""
|
|
|
|
work_script_1 = temp_file('work_script.sql')
|
|
|
|
@pytest.mark.version('>=3')
|
|
def test_1(act: Action, work_script_1: Path, capsys):
|
|
work_script_1.write_text(f"""
|
|
alter sequence g restart with 0;
|
|
commit;
|
|
|
|
set term ^;
|
|
execute block as
|
|
declare x int;
|
|
begin
|
|
for
|
|
execute statement ('select gen_id(g,1) from rdb$types,rdb$types,rdb$types')
|
|
on external
|
|
'localhost:' || rdb$get_context('SYSTEM','DB_NAME')
|
|
as user '{act.db.user}' password '{act.db.password}'
|
|
into x
|
|
do begin
|
|
end
|
|
end
|
|
^
|
|
set term ;^
|
|
""")
|
|
# Starting ISQL in separate process with doing 'heavy query'
|
|
p_work_sql = subprocess.Popen([act.vars['isql'], '-i', str(work_script_1),
|
|
'-user', act.db.user,
|
|
'-password', act.db.password, act.db.dsn],
|
|
stderr = subprocess.STDOUT)
|
|
time.sleep(3)
|
|
# Run 2nd isql and issue there DELETE FROM MON$ATATSMENTS command. First ISQL process should be terminated for short time.
|
|
drop_sql = """
|
|
commit;
|
|
set list on;
|
|
|
|
select *
|
|
from mon$statements
|
|
where
|
|
mon$attachment_id != current_connection
|
|
and mon$sql_text containing 'gen_id('
|
|
--order by mon$stat_id
|
|
;
|
|
|
|
set count on;
|
|
|
|
delete from mon$statements
|
|
where
|
|
mon$attachment_id != current_connection
|
|
and mon$sql_text containing 'gen_id('
|
|
--order by mon$stat_id
|
|
;
|
|
quit;
|
|
"""
|
|
try:
|
|
act.isql(switches=[], input=drop_sql)
|
|
delete_from_mon_sttm_log = act.clean_string(act.stdout)
|
|
finally:
|
|
p_work_sql.terminate()
|
|
# Run checking query: what is resuling value of sequence 'g' ?
|
|
# (it must be > 0 and < total number of records to be handled).
|
|
check_sql = """
|
|
--set echo on;
|
|
set list on;
|
|
set count on;
|
|
select iif( current_gen > 0 and current_gen < total_rows,
|
|
'OK: query was interrupted in the middle point.',
|
|
'WRONG! Query to be interrupted '
|
|
|| iif(current_gen <= 0, 'did not start.', 'already gone, current_gen = '||current_gen )
|
|
) as result_msg
|
|
from (
|
|
select gen_id(g,0) as current_gen, c.n * c.n * c.n as total_rows
|
|
from (select (select count(*) from rdb$types) as n from rdb$database) c
|
|
);
|
|
"""
|
|
act.isql(switches=[], input=check_sql)
|
|
#
|
|
for line in delete_from_mon_sttm_log.splitlines():
|
|
if not 'EXECUTE STATEMENT' in line.upper():
|
|
print('DEL FROM MON$STTM: ', ' '.join(line.upper().split()))
|
|
for line in act.clean_string(act.stdout).splitlines():
|
|
print('CHECK RESULTS LOG: ', ' '.join(line.upper().split()))
|
|
#
|
|
act.expected_stdout = expected_stdout
|
|
act.stdout = capsys.readouterr().out
|
|
assert act.clean_stdout == act.clean_expected_stdout
|