6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-01-22 13:33:07 +01:00
firebird-qa/tests/bugs/core_2724_test.py

186 lines
7.0 KiB
Python
Raw Permalink Normal View History

2021-04-26 20:07:00 +02:00
#coding:utf-8
2022-01-21 18:49:26 +01:00
"""
ID: issue-3120
ISSUE: 3120
TITLE: Validate or transform string of DML queries so that engine internals doesn't receive malformed strings
DESCRIPTION:
Code from doc/sql.extensions/README.ddl_triggers.txt was taken as basis for this test
(see ticket issue: "This situation happened with DDL triggers ...").
Several DB objects are created here and their DDL contain unicode (Greek) text.
Attachment these issues these DDL intentionally is run with charset = NONE.
This charset (NONE) should result in question marks after we finish DDL and want to query log table
that was filled by DDL trigger and contains issued DDL statements.
JIRA: CORE-2724
FBTEST: bugs.core_2724
2022-01-21 18:49:26 +01:00
"""
2021-04-26 20:07:00 +02:00
2022-01-21 18:49:26 +01:00
import pytest
from firebird.qa import *
2021-04-26 20:07:00 +02:00
2022-01-21 18:49:26 +01:00
init_script = """
2021-04-26 20:07:00 +02:00
create sequence ddl_seq;
create table ddl_log (
id bigint not null primary key,
moment timestamp not null,
current_connection_cset varchar(31) not null,
event_type varchar(25) not null,
object_type varchar(25) not null,
ddl_event varchar(25) not null,
object_name varchar(31) not null,
old_object_name varchar(31),
new_object_name varchar(31),
sql_text blob sub_type text not null,
ok char(1) not null,
result_info blob sub_type text
);
commit;
2021-11-16 19:44:53 +01:00
2021-04-26 20:07:00 +02:00
set term ^;
create trigger trig_ddl_log_before before any ddl statement
as
declare id type of column ddl_log.id;
declare v_current_connection_cset varchar(31);
begin
-- We do the changes in an AUTONOMOUS TRANSACTION, so if an exception happens and the command
-- didn't run, the log will survive.
in autonomous transaction do
begin
2021-11-16 19:44:53 +01:00
2021-04-26 20:07:00 +02:00
select coalesce(c.rdb$character_set_name, '??? NULL ???')
from mon$attachments a
left join rdb$character_sets c on a.mon$character_set_id = c.rdb$character_set_id
where a.mon$attachment_id = current_connection
into v_current_connection_cset;
2021-11-16 19:44:53 +01:00
insert into ddl_log (id, moment, current_connection_cset,
2021-04-26 20:07:00 +02:00
event_type, object_type, ddl_event, object_name,
old_object_name, new_object_name, sql_text, ok, result_info)
2021-11-16 19:44:53 +01:00
values (next value for ddl_seq,
'now',
2021-04-26 20:07:00 +02:00
:v_current_connection_cset,
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'),
rdb$get_context('DDL_TRIGGER', 'OLD_OBJECT_NAME'),
rdb$get_context('DDL_TRIGGER', 'NEW_OBJECT_NAME'),
rdb$get_context('DDL_TRIGGER', 'SQL_TEXT'),
'N',
'Κάτι συνέβη. Θα πρέπει να ελέγξετε') -- Something was wrong. One need to check this.
returning id into id;
rdb$set_context('USER_SESSION', 'trig_ddl_log_id', id);
end
end
^
2021-11-16 19:44:53 +01:00
2021-04-26 20:07:00 +02:00
-- Note: the above trigger will fire for this DDL command. It's good idea to use -nodbtriggers
-- when working with them!
create trigger trig_ddl_log_after after any ddl statement
as
begin
-- Here we need an AUTONOMOUS TRANSACTION because the original transaction will not see the
-- record inserted on the BEFORE trigger autonomous transaction if user transaction is not
-- READ COMMITTED.
in autonomous transaction do
2021-11-16 19:44:53 +01:00
update ddl_log set ok = 'Y',
2021-04-26 20:07:00 +02:00
result_info = 'Τα πάντα ήταν επιτυχής' -- Everything has completed successfully
where id = rdb$get_context('USER_SESSION', 'trig_ddl_log_id');
end
^
set term ;^
commit;
2021-11-16 19:44:53 +01:00
2021-04-26 20:07:00 +02:00
-- So lets delete the record about trig_ddl_log_after creation.
delete from ddl_log;
commit;
2021-12-22 20:23:11 +01:00
"""
2021-04-26 20:07:00 +02:00
2022-01-21 18:49:26 +01:00
db = db_factory(charset='UTF8', init=init_script)
2021-04-26 20:07:00 +02:00
2022-01-21 18:49:26 +01:00
act = python_act('db', substitutions=[('SQL_TEXT .*', 'SQL_TEXT'),
('RESULT_INFO .*', 'RESULT_INFO')])
2021-04-26 20:07:00 +02:00
2022-01-21 18:49:26 +01:00
expected_stdout_a = """
2021-04-26 20:07:00 +02:00
ID 2
2021-11-16 19:44:53 +01:00
CURRENT_CONNECTION_CSET NONE
SQL_TEXT
2021-04-26 20:07:00 +02:00
create domain dm_name varchar(50) check (value in ('??????????????????', '??????????', '????????????', '??????????????', '????????????????'))
2021-11-16 19:44:53 +01:00
RESULT_INFO
2021-04-26 20:07:00 +02:00
Τα πάντα ήταν επιτυχής
DDL_EVENT CREATE DOMAIN
OBJECT_NAME DM_NAME
ID 3
2021-11-16 19:44:53 +01:00
CURRENT_CONNECTION_CSET NONE
SQL_TEXT
2021-04-26 20:07:00 +02:00
recreate table t1 (
saller_id integer -- ?????????????????????????? ?????????????? // ID of saler
,customer_id integer -- ?????????????????????????? ???????????? // ID of customer
,product_name dm_name
)
2021-11-16 19:44:53 +01:00
RESULT_INFO
2021-04-26 20:07:00 +02:00
Τα πάντα ήταν επιτυχής
DDL_EVENT CREATE TABLE
2021-11-16 19:44:53 +01:00
OBJECT_NAME T1
"""
2022-01-21 18:49:26 +01:00
expected_stdout_b = """
2021-04-26 20:07:00 +02:00
ID 6
2021-11-16 19:44:53 +01:00
CURRENT_CONNECTION_CSET UTF8
2021-04-26 20:07:00 +02:00
SQL_TEXT 80:0
create domain dm_name varchar(50) check (value in ('αμορτισέρ', 'κόμβο', 'σωλήνα', 'φέροντα', 'βραχίονα'))
RESULT_INFO 80:2
Τα πάντα ήταν επιτυχής
DDL_EVENT CREATE DOMAIN
OBJECT_NAME DM_NAME
ID 7
2021-11-16 19:44:53 +01:00
CURRENT_CONNECTION_CSET UTF8
SQL_TEXT
2021-04-26 20:07:00 +02:00
recreate table t1 (
saller_id integer -- αναγνωριστικό εμπόρου // ID of saler
,customer_id integer -- αναγνωριστικό πελάτη // ID of customer
,product_name dm_name
)
2021-11-16 19:44:53 +01:00
RESULT_INFO
2021-04-26 20:07:00 +02:00
Τα πάντα ήταν επιτυχής
DDL_EVENT CREATE TABLE
2021-11-16 19:44:53 +01:00
OBJECT_NAME T1
2021-12-22 20:23:11 +01:00
"""
2021-04-26 20:07:00 +02:00
2022-01-21 18:49:26 +01:00
sql_check = """
delete from ddl_log;
commit;
create domain dm_name varchar(50) check (value in ('αμορτισέρ', 'κόμβο', 'σωλήνα', 'φέροντα', 'βραχίονα'));
recreate table t1 (
saller_id integer -- αναγνωριστικό εμπόρου // ID of saler
,customer_id integer -- αναγνωριστικό πελάτη // ID of customer
,product_name dm_name
);
commit;
set list on;
select id, current_connection_cset, sql_text, result_info, ddl_event, object_name
from ddl_log order by id;
commit;
drop table t1;
drop domain dm_name;
exit;
"""
2021-11-16 19:44:53 +01:00
2022-01-21 18:49:26 +01:00
@pytest.mark.version('>=3.0')
def test_1(act: Action):
2021-11-16 19:44:53 +01:00
#
2022-01-21 18:49:26 +01:00
act.expected_stdout = expected_stdout_a
act.isql(switches=[], charset='NONE', input=sql_check)
assert act.clean_stdout == act.clean_expected_stdout
2021-11-16 19:44:53 +01:00
#
2022-01-21 18:49:26 +01:00
act.reset()
act.expected_stdout = expected_stdout_b
act.isql(switches=[], charset='UTF8', input=sql_check)
assert act.clean_stdout == act.clean_expected_stdout