mirror of
https://github.com/FirebirdSQL/firebird-qa.git
synced 2025-01-22 13:33:07 +01:00
146 lines
5.3 KiB
Python
146 lines
5.3 KiB
Python
#coding:utf-8
|
|
|
|
"""
|
|
ID: issue-7426
|
|
ISSUE: https://github.com/FirebirdSQL/firebird/issues/7426
|
|
TITLE: Ensure the DDL trigger requests are cached
|
|
DESCRIPTION:
|
|
Test prepares trace config with requrement to see TRIGGERS compilation.
|
|
We create two DDL triggers for logging any DDL statement, before and after it occurs.
|
|
Then we create table with two constraints and one index, and make several alter statements.
|
|
|
|
Finally, we parse trace log and filter only lines containing name of DDL triggers.
|
|
Only ONE occurence must be for each of DDL trigger (totally 2).
|
|
Before this ticked was fixed, every time we did some DDL appropriate trigger was compiled
|
|
and this could be seen in a trace log (checked on 5.0.0.1182).
|
|
|
|
No errors must present in the trace log.
|
|
NOTES:
|
|
[07-sep-2023] pzotov
|
|
::: NB :::
|
|
1. It must be noted that the term 'COMPILE' means parsing of BLR code into an execution tree, i.e. this action
|
|
occurs when unit code is loaded into metadata cache.
|
|
2. Currently there is no way to specify in the trace what EXACT type of DDL trigger fired. It is shown as "AFTER DDL".
|
|
|
|
Checked on 5.0.0.1190.
|
|
"""
|
|
import locale
|
|
import re
|
|
import pytest
|
|
from firebird.qa import *
|
|
|
|
db = db_factory()
|
|
|
|
act = python_act('db')
|
|
|
|
trace = ['log_initfini = false',
|
|
'log_errors = true',
|
|
'log_trigger_compile = true',
|
|
]
|
|
|
|
allowed_patterns = [ ' ERROR AT ', 'Trigger TRG_ANY_DDL_STATEMENT_', ]
|
|
allowed_patterns = [ re.compile(r, re.IGNORECASE) for r in allowed_patterns]
|
|
|
|
@pytest.mark.trace
|
|
@pytest.mark.version('>=5.0')
|
|
def test_1(act: Action, capsys):
|
|
|
|
test_script = f"""
|
|
recreate table log_ddl_triggers_activity (
|
|
id int generated by default as identity constraint pk_log_ddl_triggers_activity primary key
|
|
,ddl_trigger_name varchar(64)
|
|
,event_type varchar(25) not null
|
|
,object_type varchar(25) not null
|
|
,ddl_event varchar(25) not null
|
|
,object_name varchar(64) not null
|
|
,dts timestamp default 'now'
|
|
);
|
|
|
|
set autoddl off;
|
|
|
|
set term ^;
|
|
execute block as
|
|
begin
|
|
rdb$set_context('USER_SESSION', 'SKIP_DDL_TRG', '1');
|
|
end
|
|
^
|
|
create or alter trigger trg_any_ddl_statement_alter active after any ddl statement as
|
|
begin
|
|
if (rdb$get_context('USER_SESSION', 'SKIP_DDL_TRG') is null) then
|
|
execute statement
|
|
('insert into log_ddl_triggers_activity(ddl_trigger_name, event_type, object_type, ddl_event, object_name) values( ?, ?, ?, ?, ? )' )
|
|
( 'ANY_DDL_STATEMENT_AFTER'
|
|
,rdb$get_context('DDL_TRIGGER', 'EVENT_TYPE')
|
|
,rdb$get_context('DDL_TRIGGER', 'OBJECT_TYPE')
|
|
,rdb$get_context('DDL_TRIGGER', 'DDL_EVENT')
|
|
,rdb$get_context('DDL_TRIGGER', 'OBJECT_NAME')
|
|
);
|
|
end
|
|
^
|
|
create or alter trigger trg_any_ddl_statement_before active before any ddl statement as
|
|
begin
|
|
if (rdb$get_context('USER_SESSION', 'SKIP_DDL_TRG') is null) then
|
|
execute statement
|
|
('insert into log_ddl_triggers_activity(ddl_trigger_name, event_type, object_type, ddl_event, object_name) values( ?, ?, ?, ?, ? )' )
|
|
( 'ANY_DDL_STATEMENT_BEFORE'
|
|
,rdb$get_context('DDL_TRIGGER', 'EVENT_TYPE')
|
|
,rdb$get_context('DDL_TRIGGER', 'OBJECT_TYPE')
|
|
,rdb$get_context('DDL_TRIGGER', 'DDL_EVENT')
|
|
,rdb$get_context('DDL_TRIGGER', 'OBJECT_NAME')
|
|
);
|
|
end
|
|
^
|
|
execute block as
|
|
begin
|
|
rdb$set_context('USER_SESSION', 'SKIP_DDL_TRG', null);
|
|
end
|
|
^
|
|
commit
|
|
^
|
|
|
|
----------
|
|
create table test(id int not null, x smallint, y int, z int, name varchar(10))
|
|
^
|
|
--/*
|
|
alter table test add constraint test_pk primary key(id) using descending index test_id_desc
|
|
^
|
|
alter table test add constraint test_unq unique(x,y) using descending index test_x_y_unq_desc
|
|
^
|
|
create index test_name on test(name)
|
|
^
|
|
alter index test_name inactive
|
|
^
|
|
alter index test_name active
|
|
^
|
|
drop index test_name
|
|
^
|
|
alter table test drop constraint test_pk, drop constraint test_unq
|
|
^
|
|
alter table test alter x type int, alter y type bigint, alter name type varchar(20), drop z, add u varchar(10)
|
|
^
|
|
--*/
|
|
commit
|
|
^
|
|
set term ;^
|
|
|
|
"""
|
|
|
|
with act.trace(db_events=trace, encoding = locale.getpreferredencoding(), encoding_errors='utf8'):
|
|
act.isql(switches = ['-q'], input = test_script, combine_output = True, io_enc = locale.getpreferredencoding())
|
|
|
|
# Process trace
|
|
for line in act.trace_log:
|
|
if line.rstrip().split():
|
|
for p in allowed_patterns:
|
|
if p.search(line):
|
|
print(line.strip())
|
|
|
|
expected_stdout = f"""
|
|
Trigger TRG_ANY_DDL_STATEMENT_BEFORE (BEFORE DDL):
|
|
Trigger TRG_ANY_DDL_STATEMENT_ALTER (AFTER DDL):
|
|
"""
|
|
|
|
act.expected_stdout = expected_stdout
|
|
act.stdout = capsys.readouterr().out
|
|
assert act.clean_stdout == act.clean_expected_stdout
|