mirror of
https://github.com/FirebirdSQL/firebird-qa.git
synced 2025-01-22 21:43:06 +01:00
225 lines
9.0 KiB
Python
225 lines
9.0 KiB
Python
#coding:utf-8
|
|
|
|
"""
|
|
ID: issue-4615
|
|
ISSUE: 4615
|
|
TITLE: Server ignores asynchronous (monitoring or cancellation) requests while
|
|
preparing a query with lot of windowed functions
|
|
DESCRIPTION:
|
|
Preparing stage of test query will last lot of time even on power host.
|
|
We launch separate (child) process with ISQL and allow him to start preparing this query during several
|
|
seconds. Then we launch second child process with ISQL and try to kill first one.
|
|
Before this ticket was fixed it was NOT possible neither to cancel it by using MON$ATTACHMENTS nor even
|
|
query MON$ tables at all (until this 'complex query' preparing finish).
|
|
JIRA: CORE-4292
|
|
FBTEST: bugs.core_4292
|
|
"""
|
|
|
|
import pytest
|
|
import subprocess
|
|
import time
|
|
from pathlib import Path
|
|
from firebird.qa import *
|
|
|
|
db = db_factory()
|
|
heavy_script = temp_file('heavy_script.sql')
|
|
heavy_output = temp_file('heavy_script.out')
|
|
|
|
act = python_act('db', substitutions=[('.*line.*', ''), ('[\t ]+', ' '),
|
|
('.*Killed by database administrator.*', '')])
|
|
|
|
test_script = """
|
|
set bail on;
|
|
set list on;
|
|
set count on;
|
|
with a as (
|
|
select rf.rdb$field_id fid, rr.rdb$relation_id rid, rr.rdb$relation_name rnm
|
|
from rdb$relation_fields rf join rdb$relations rr on rf.rdb$relation_name=rr.rdb$relation_name
|
|
)
|
|
,b as (
|
|
select fid, rnm, rid, iif(rid is null, 1, r) r
|
|
from (--f
|
|
select fid, rnm, rid,
|
|
iif(lag(fid) over(partition by rid order by fid) is not null
|
|
and lag(r) over(partition by rid order by fid) >= r
|
|
, r + 1, r) r
|
|
from (--e
|
|
select fid, rnm, rid,
|
|
iif(lag(fid) over(partition by rid order by fid) is not null
|
|
and lag(r) over(partition by rid order by fid) >= r
|
|
, r + 1, r) r
|
|
from (--d
|
|
select fid, rnm, rid,
|
|
iif(lag(fid) over(partition by rid order by fid) is not null
|
|
and lag(r) over(partition by rid order by fid) >= r
|
|
, r + 1, r) r
|
|
from (--c
|
|
select fid, rnm, rid,
|
|
iif(lag(fid) over(partition by rid order by fid) is not null
|
|
and lag(r) over(partition by rid order by fid) >= r
|
|
,r + 1, r) r
|
|
from (--b
|
|
select fid, rnm, rid,
|
|
iif( lag(fid) over(partition by rid order by fid) is not null
|
|
and lag(r) over(partition by rid order by fid) >= r
|
|
,r + 1, r) r
|
|
from (
|
|
select a.*, 1 r
|
|
from a
|
|
) a
|
|
) b
|
|
) c
|
|
) d
|
|
) e
|
|
) f
|
|
)
|
|
-- select max(r) r from b group by fid having max(r) < 6; -- ok
|
|
|
|
,c
|
|
as (
|
|
select fid, rnm, rid, iif(rid is null, 1, r) r
|
|
from (--f
|
|
select fid, rnm, rid,
|
|
iif(lag(fid) over(partition by rid order by fid) is not null
|
|
and lag(r) over(partition by rid order by fid) >= r
|
|
, r + 1, r) r
|
|
from (--e
|
|
select fid, rnm, rid,
|
|
iif(lag(fid) over(partition by rid order by fid) is not null
|
|
and lag(r) over(partition by rid order by fid) >= r
|
|
, r + 1, r) r
|
|
from (--d
|
|
select fid, rnm, rid,
|
|
iif(lag(fid) over(partition by rid order by fid) is not null
|
|
and lag(r) over(partition by rid order by fid) >= r
|
|
, r + 1, r) r
|
|
from (--c
|
|
select fid, rnm, rid,
|
|
iif(lag(fid) over(partition by rid order by fid) is not null
|
|
and lag(r) over(partition by rid order by fid) >= r
|
|
,r + 1, r) r
|
|
from (--b
|
|
select fid, rnm, rid,
|
|
iif( lag(fid) over(partition by rid order by fid) is not null
|
|
and lag(r) over(partition by rid order by fid) >= r
|
|
,r + 1, r) r
|
|
from (
|
|
select fid, rnm, rid, max(r) over(partition by fid) r from b
|
|
) a
|
|
) b
|
|
) c
|
|
) d
|
|
) e
|
|
) f
|
|
)
|
|
-- select * from c -- ok
|
|
|
|
,d
|
|
as (
|
|
select fid, rnm, rid, iif(rid is null, 1, r) r
|
|
from (--f
|
|
select fid, rnm, rid,
|
|
iif( lag(fid) over(partition by rid order by fid) is not null
|
|
and lag(r) over(partition by rid order by fid) >= r
|
|
, r + 1, r) r
|
|
from (--e
|
|
select fid, rnm, rid,
|
|
iif( lag(fid) over(partition by rid order by fid) is not null
|
|
and lag(r) over(partition by rid order by fid) >= r
|
|
, r + 1, r) r
|
|
from (--d
|
|
select fid, rnm, rid,
|
|
iif( lag(fid) over(partition by rid order by fid) is not null
|
|
and lag(r) over(partition by rid order by fid) >= r
|
|
, r + 1, r) r
|
|
from (--c
|
|
select fid, rnm, rid,
|
|
iif( lag(fid) over(partition by rid order by fid) is not null
|
|
and lag(r) over(partition by rid order by fid) >= r
|
|
,r + 1, r) r
|
|
from (--b
|
|
select fid, rnm, rid,
|
|
iif( lag(fid) over(partition by rid order by fid) is not null
|
|
and lag(r) over(partition by rid order by fid) >= r
|
|
,r + 1, r) r
|
|
from (
|
|
select fid, rnm, rid, max(r) over(partition by fid) r from c
|
|
) a
|
|
) b
|
|
) c
|
|
) d
|
|
) e
|
|
) f
|
|
)
|
|
select * from d rows 0;
|
|
set count off;
|
|
select 'WORKER FINISHED TOO FAST! DELAY IN TEST MUST BE REDUCED!' msg from rdb$database;
|
|
"""
|
|
|
|
killer_sql = """
|
|
set list on;
|
|
/*
|
|
select a.*, s.*
|
|
from mon$attachments a
|
|
left join mon$statements s on a.mon$attachment_id = s.mon$attachment_id
|
|
where
|
|
a.mon$attachment_id <> current_connection
|
|
and a.mon$system_flag is distinct from 1
|
|
;
|
|
*/
|
|
select count(*) as "Found worker ?"
|
|
from mon$attachments a
|
|
where
|
|
a.mon$attachment_id <> current_connection
|
|
and a.mon$system_flag is distinct from 1
|
|
;
|
|
|
|
delete from mon$attachments
|
|
where
|
|
mon$attachment_id <> current_connection
|
|
and mon$system_flag is distinct from 1
|
|
returning
|
|
sign(mon$attachment_id) as deleted_mon_att_id,
|
|
mon$user as deleted_mon_user,
|
|
iif(mon$remote_protocol containing 'tcp', 'tcp', null) as deleted_mon_protocol,
|
|
iif(mon$remote_process containing 'isql', 'isql', null) as deleted_mon_process,
|
|
mon$system_flag as deleted_mon_sys_flag
|
|
;
|
|
"""
|
|
|
|
expected_stdout_killer = """
|
|
Found worker ? 1
|
|
DELETED_MON_ATT_ID 1
|
|
DELETED_MON_USER SYSDBA
|
|
DELETED_MON_PROTOCOL tcp
|
|
DELETED_MON_PROCESS isql
|
|
DELETED_MON_SYS_FLAG 0
|
|
"""
|
|
|
|
expected_stdout_worker = """
|
|
Statement failed, SQLSTATE = 08003
|
|
connection shutdown
|
|
"""
|
|
|
|
@pytest.mark.version('>=3.0')
|
|
def test_1(act: Action, heavy_script: Path, heavy_output: Path):
|
|
heavy_script.write_text(test_script)
|
|
with open(heavy_output, mode='w') as heavy_out:
|
|
p_heavy_sql = subprocess.Popen([act.vars['isql'], '-i', str(heavy_script),
|
|
'-user', act.db.user,
|
|
'-password', act.db.password, act.db.dsn],
|
|
stdout=heavy_out, stderr=subprocess.STDOUT)
|
|
try:
|
|
time.sleep(4)
|
|
act.expected_stdout = expected_stdout_killer
|
|
act.isql(switches=[], input=killer_sql)
|
|
finally:
|
|
p_heavy_sql.terminate()
|
|
#
|
|
assert act.clean_stdout == act.clean_expected_stdout
|
|
# And worker...
|
|
act.reset()
|
|
act.expected_stdout = expected_stdout_worker
|
|
act.stdout = heavy_output.read_text()
|
|
assert act.clean_stdout == act.clean_expected_stdout
|