6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-01-23 14:03:06 +01:00
firebird-qa/tests/bugs/core_4819_test.py

278 lines
8.6 KiB
Python
Raw Normal View History

2021-04-26 20:07:00 +02:00
#coding:utf-8
2022-01-24 20:27:02 +01:00
"""
ID: issue-5116
ISSUE: 5116
TITLE: EXECUTE PROCEDURE's RETURNING_VALUES and EXECUTE STATEMENT's INTO does not
check validity of assignments targets leading to bugcheck
2022-01-24 20:27:02 +01:00
DESCRIPTION:
JIRA: CORE-4819
FBTEST: bugs.core_4819
2022-01-24 20:27:02 +01:00
"""
2021-04-26 20:07:00 +02:00
2022-01-24 20:27:02 +01:00
import pytest
from firebird.qa import *
2021-04-26 20:07:00 +02:00
2022-01-24 20:27:02 +01:00
db = db_factory()
2021-04-26 20:07:00 +02:00
2022-01-24 20:27:02 +01:00
test_script = """
2021-04-26 20:07:00 +02:00
create or alter procedure sp_test(a_x int) as begin end;
recreate table test(id int primary key, x bigint, y bigint);
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
insert into test values(1, 3, 7);
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
set list on;
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
---------------------
select 'initial state' msg, t.* from test t;
---------------------
commit;
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
set term ^;
create or alter procedure sp_test(a_x int) returns(o_y int) as
begin
o_y = 7 * a_x;
suspend;
end
^
commit
^
create or alter trigger test_aud1 for test active after insert or update or delete as
begin
-- Since WI-T3.0.0.31846 following must produce:
-- Statement failed, SQLSTATE = 42000
-- attempted update of read-only column
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
if (not inserting) then
begin
execute procedure sp_test(old.x) returning_values(old.x);
execute procedure sp_test(old.x) returning_values(old.y);
end
else
begin
execute procedure sp_test(new.x) returning_values(new.x);
execute procedure sp_test(new.x) returning_values(new.y);
end
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
rdb$set_context( 'USER_SESSION', 'X_TRG_AIUD1', iif( inserting, new.x, old.x ) );
rdb$set_context( 'USER_SESSION', 'Y_TRG_AIUD1', iif( inserting, new.y, old.y ) );
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
end
^
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
create or alter trigger test_aud2 for test active after insert or update or delete as
begin
-- Since WI-T3.0.0.31846 following must produce:
-- Statement failed, SQLSTATE = 42000
-- attempted update of read-only column
if (not inserting) then
begin
execute statement ('execute procedure sp_test( ? )') ( 2 * old.x ) into old.x;
execute statement ('execute procedure sp_test( ? )') ( 2 * old.x ) into old.y;
end
else
begin
execute statement ('execute procedure sp_test( ? )') ( 2 * new.x ) into new.x;
execute statement ('execute procedure sp_test( ? )') ( 2 * new.x ) into new.y;
end
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
rdb$set_context( 'USER_SESSION', 'X_TRG_AIUD2', iif( inserting, new.x, old.x ) );
rdb$set_context( 'USER_SESSION', 'Y_TRG_AIUD2', iif( inserting, new.y, old.y ) );
end
^
set term ;^
commit;
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
-- ######################################################################
-- 1. Check when 'execute proc returning_values' is called from trigger,
-- making invalid update of old. & new. variables:
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
delete from test where id = 1
returning 'delete-returning:' as msg,
x as old_x,
y as old_y;
select
'after delete' msg,
cast(rdb$get_context('USER_SESSION', 'X_TRG_AIUD1') as int) as X_TRG_AIUD1,
cast(rdb$get_context('USER_SESSION', 'Y_TRG_AIUD1') as int) as Y_TRG_AIUD1,
cast(rdb$get_context('USER_SESSION', 'X_TRG_AIUD2') as int) as X_TRG_AIUD2,
cast(rdb$get_context('USER_SESSION', 'Y_TRG_AIUD2') as int) as Y_TRG_AIUD2
from rdb$database;
rollback;
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
update test set x = 17 where id = 1
returning 'update-returning:' as msg,
old.x as old_x,
new.x as new_x,
old.y as old_y,
new.y as new_y;
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
select
'after update' msg,
cast(rdb$get_context('USER_SESSION', 'X_TRG_AIUD1') as int) as X_TRG_AIUD1,
cast(rdb$get_context('USER_SESSION', 'Y_TRG_AIUD1') as int) as Y_TRG_AIUD1,
cast(rdb$get_context('USER_SESSION', 'X_TRG_AIUD2') as int) as X_TRG_AIUD2,
cast(rdb$get_context('USER_SESSION', 'Y_TRG_AIUD2') as int) as Y_TRG_AIUD2,
2022-01-24 20:27:02 +01:00
t.*
2021-04-26 20:07:00 +02:00
from test t;
rollback;
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
---------------------
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
insert into test(id, x) values(2, 19)
returning 'insert-returning:' as msg, x as new_x, y as new_y;
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
select
'after insert' msg,
cast(rdb$get_context('USER_SESSION', 'X_TRG_AIUD1') as int) as X_TRG_AIUD1,
cast(rdb$get_context('USER_SESSION', 'Y_TRG_AIUD1') as int) as Y_TRG_AIUD1,
cast(rdb$get_context('USER_SESSION', 'X_TRG_AIUD2') as int) as X_TRG_AIUD2,
cast(rdb$get_context('USER_SESSION', 'Y_TRG_AIUD2') as int) as Y_TRG_AIUD2,
t.*
from test t where id=2;
rollback;
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
-- ######################################################################
-- 2. Check when call 'execute proc returning_values' inside implicit cursor:
set term ^;
execute block returns(msg varchar(20), old_y int, new_y int) as
begin
msg='within cursor-1:';
for
select x, y from test
as cursor ce
do begin
old_y = ce.y;
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
-- WI-T3.0.0.31845. Following leads to:
-- Statement failed, SQLSTATE = XX000
-- internal Firebird consistency check (EVL_assign_to: invalid operation (229), file: evl.cpp line: 205)
-- Since WI-T3.0.0.31846 must produce:
-- Statement failed, SQLSTATE = 42000
-- attempted update of read-only column
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
execute procedure sp_test(ce.x) returning_values(ce.y);
new_y = ce.y;
suspend;
end
end
^
set term ;^
rollback;
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
-- ######################################################################
-- 3. Check when call 'execute statement' inside implicit cursor:
set term ^;
execute block returns(msg varchar(20), old_y int, new_y int) as
begin
msg='within cursor-2:';
for
select x, y from test
as cursor ce
do begin
old_y = ce.y;
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
-- Since WI-T3.0.0.31846 following must produce:
-- Statement failed, SQLSTATE = 42000
-- attempted update of read-only column
execute statement ('execute procedure sp_test( ? )') ( ce.x ) into ce.y;
new_y = ce.y;
suspend;
end
end
^
set term ;^
rollback;
2021-12-22 20:23:11 +01:00
"""
2021-04-26 20:07:00 +02:00
2022-01-24 20:27:02 +01:00
act = isql_act('db', test_script)
2021-04-26 20:07:00 +02:00
2022-01-24 20:27:02 +01:00
expected_stdout = """
2021-04-26 20:07:00 +02:00
MSG initial state
ID 1
X 3
Y 7
MSG after delete
X_TRG_AIUD1 <null>
Y_TRG_AIUD1 <null>
X_TRG_AIUD2 <null>
Y_TRG_AIUD2 <null>
MSG after update
X_TRG_AIUD1 <null>
Y_TRG_AIUD1 <null>
X_TRG_AIUD2 <null>
Y_TRG_AIUD2 <null>
ID 1
X 3
Y 7
2021-12-22 20:23:11 +01:00
"""
2022-01-24 20:27:02 +01:00
# version: 3.0
2021-04-26 20:07:00 +02:00
expected_stderr_1 = """
Statement failed, SQLSTATE = 42000
attempted update of read-only column
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
Statement failed, SQLSTATE = 42000
attempted update of read-only column
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
Statement failed, SQLSTATE = 42000
attempted update of read-only column
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
Statement failed, SQLSTATE = 42000
attempted update of read-only column
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
Statement failed, SQLSTATE = 42000
attempted update of read-only column
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
Statement failed, SQLSTATE = 42000
attempted update of read-only column
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
Statement failed, SQLSTATE = 42000
attempted update of read-only column
2021-12-22 20:23:11 +01:00
"""
2021-04-26 20:07:00 +02:00
@pytest.mark.version('>=3.0,<4.0')
2022-01-24 20:27:02 +01:00
def test_1(act: Action):
act.expected_stdout = expected_stdout
act.expected_stderr = expected_stderr_1
act.execute()
assert (act.clean_stderr == act.clean_expected_stderr and
act.clean_stdout == act.clean_expected_stdout)
2021-04-26 20:07:00 +02:00
# version: 4.0
expected_stderr_2 = """
Statement failed, SQLSTATE = 42000
attempted update of read-only column TEST.X
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
Statement failed, SQLSTATE = 42000
attempted update of read-only column TEST.X
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
Statement failed, SQLSTATE = 42000
attempted update of read-only column TEST.X
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
Statement failed, SQLSTATE = 42000
attempted update of read-only column TEST.X
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
Statement failed, SQLSTATE = 42000
attempted update of read-only column TEST.X
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
Statement failed, SQLSTATE = 42000
attempted update of read-only column CE.Y
2022-01-24 20:27:02 +01:00
2021-04-26 20:07:00 +02:00
Statement failed, SQLSTATE = 42000
attempted update of read-only column CE.Y
2021-12-22 20:23:11 +01:00
"""
2021-04-26 20:07:00 +02:00
@pytest.mark.version('>=4.0')
2022-01-24 20:27:02 +01:00
def test_2(act: Action):
act.expected_stdout = expected_stdout
act.expected_stderr = expected_stderr_2
act.execute()
assert (act.clean_stderr == act.clean_expected_stderr and
act.clean_stdout == act.clean_expected_stdout)
2021-04-26 20:07:00 +02:00