Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Result of several updates of RDB$PROCEDURES (and RDB$TRIGGERS) depends on presence of ROLLBACK between each of DML statements [CORE4772] #5071

Closed
firebird-automations opened this issue Apr 24, 2015 · 4 comments

Comments

@firebird-automations
Copy link
Collaborator

Submitted by: @pavel-zotov

On empty database (Firebird version: WI-T3.0.0.31807, tested on SS and SC) do:

TEST-1.
#⁠#⁠#⁠#⁠#⁠#⁠

---------------- start of script `test1.sql` ---------------
set term ^;
create procedure sp_dummy(a_id int) returns(o_txt varchar(20)) as
begin
o_txt = 'get id='||a_id;
suspend;
end
^
set term ;^
commit;

set count on; set echo on;
update RDB$PROCEDURES t set t.RDB$PROCEDURE_SOURCE = null where coalesce(rdb$system_flag,0)=0 rows 1;
update RDB$PROCEDURES t set t.RDB$RUNTIME = null where coalesce(rdb$system_flag,0)=0 rows 1;
update RDB$PROCEDURES t set t.RDB$ENGINE_NAME = null where coalesce(rdb$system_flag,0)=0 rows 1;
update RDB$PROCEDURES t set t.RDB$ENTRYPOINT = null where coalesce(rdb$system_flag,0)=0 rows 1;
update RDB$PROCEDURES t set t.RDB$PACKAGE_NAME = null where coalesce(rdb$system_flag,0)=0 rows 1;
update RDB$PROCEDURES t set t.RDB$PRIVATE_FLAG = null where coalesce(rdb$system_flag,0)=0 rows 1;

rollback;

update RDB$PROCEDURES t set t.RDB$PROCEDURE_SOURCE = null where coalesce(rdb$system_flag,0)=0 rows 1;
update RDB$PROCEDURES t set t.RDB$RUNTIME = null where coalesce(rdb$system_flag,0)=0 rows 1;
update RDB$PROCEDURES t set t.RDB$ENGINE_NAME = null where coalesce(rdb$system_flag,0)=0 rows 1;
update RDB$PROCEDURES t set t.RDB$ENTRYPOINT = null where coalesce(rdb$system_flag,0)=0 rows 1;
update RDB$PROCEDURES t set t.RDB$PACKAGE_NAME = null where coalesce(rdb$system_flag,0)=0 rows 1;
update RDB$PROCEDURES t set t.RDB$PRIVATE_FLAG = null where coalesce(rdb$system_flag,0)=0 rows 1;

rollback;
---------------- end of script `test1.sql` ---------------

Run: isql.exe localhost/port:<path>\<file> -i test1.sql 1>result1.log 2>&1

Result-1:
#⁠#⁠#⁠#⁠#⁠#⁠#⁠

update RDB$PROCEDURES t set t.RDB$PROCEDURE_SOURCE = null where coalesce(rdb$system_flag,0)=0 rows 1;
Records affected: 1
update RDB$PROCEDURES t set t.RDB$RUNTIME = null where coalesce(rdb$system_flag,0)=0 rows 1;
Records affected: 1
update RDB$PROCEDURES t set t.RDB$ENGINE_NAME = null where coalesce(rdb$system_flag,0)=0 rows 1;
Records affected: 1
update RDB$PROCEDURES t set t.RDB$ENTRYPOINT = null where coalesce(rdb$system_flag,0)=0 rows 1;
Records affected: 1
update RDB$PROCEDURES t set t.RDB$PACKAGE_NAME = null where coalesce(rdb$system_flag,0)=0 rows 1;
Records affected: 1
update RDB$PROCEDURES t set t.RDB$PRIVATE_FLAG = null where coalesce(rdb$system_flag,0)=0 rows 1;
Records affected: 1

rollback;

update RDB$PROCEDURES t set t.RDB$PROCEDURE_SOURCE = null where coalesce(rdb$system_flag,0)=0 rows 1;
Records affected: 1
update RDB$PROCEDURES t set t.RDB$RUNTIME = null where coalesce(rdb$system_flag,0)=0 rows 1;
Records affected: 1
update RDB$PROCEDURES t set t.RDB$ENGINE_NAME = null where coalesce(rdb$system_flag,0)=0 rows 1;
Records affected: 1
update RDB$PROCEDURES t set t.RDB$ENTRYPOINT = null where coalesce(rdb$system_flag,0)=0 rows 1;
Records affected: 1
update RDB$PROCEDURES t set t.RDB$PACKAGE_NAME = null where coalesce(rdb$system_flag,0)=0 rows 1;
Records affected: 1
update RDB$PROCEDURES t set t.RDB$PRIVATE_FLAG = null where coalesce(rdb$system_flag,0)=0 rows 1;
Records affected: 1

rollback;

(So, each DML really can update at least one row - we can see it in affected records; and NO errors occured).

TEST-2
#⁠#⁠#⁠#⁠#⁠#⁠

Recreate again new database and apply following:

---------------- start of script `test2.sql` ---------------
set term ^;
create procedure sp_dummy(a_id int) returns(o_txt varchar(20)) as
begin
o_txt = 'get id='||a_id;
suspend;
end
^
set term ;^
commit;

set count on; set echo on;
update RDB$PROCEDURES t set t.RDB$PROCEDURE_SOURCE = null where coalesce(rdb$system_flag,0)=0 rows 1;
rollback;
update RDB$PROCEDURES t set t.RDB$RUNTIME = null where coalesce(rdb$system_flag,0)=0 rows 1;
rollback;
update RDB$PROCEDURES t set t.RDB$ENGINE_NAME = null where coalesce(rdb$system_flag,0)=0 rows 1;
rollback;
update RDB$PROCEDURES t set t.RDB$ENTRYPOINT = null where coalesce(rdb$system_flag,0)=0 rows 1;
rollback;
update RDB$PROCEDURES t set t.RDB$PACKAGE_NAME = null where coalesce(rdb$system_flag,0)=0 rows 1;
rollback;
update RDB$PROCEDURES t set t.RDB$PRIVATE_FLAG = null where coalesce(rdb$system_flag,0)=0 rows 1;
rollback;
---------------- start of script `test2.sql` ---------------

Run: isql.exe localhost/port:<path>\<file> -i test2.sql 1>result2.log 2>&1

Result-2:
#⁠#⁠#⁠#⁠#⁠#⁠#⁠

update RDB$PROCEDURES t set t.RDB$PROCEDURE_SOURCE = null where coalesce(rdb$system_flag,0)=0 rows 1;
Records affected: 1
rollback;
update RDB$PROCEDURES t set t.RDB$RUNTIME = null where coalesce(rdb$system_flag,0)=0 rows 1;
Statement failed, SQLSTATE = 42000
UPDATE operation is not allowed for system table RDB$PROCEDURES
After line 13 in file test2.sql
Records affected: 0
rollback;
update RDB$PROCEDURES t set t.RDB$ENGINE_NAME = null where coalesce(rdb$system_flag,0)=0 rows 1;
Statement failed, SQLSTATE = 42000
UPDATE operation is not allowed for system table RDB$PROCEDURES
After line 15 in file test2.sql
Records affected: 0
rollback;
update RDB$PROCEDURES t set t.RDB$ENTRYPOINT = null where coalesce(rdb$system_flag,0)=0 rows 1;
Statement failed, SQLSTATE = 42000
UPDATE operation is not allowed for system table RDB$PROCEDURES
After line 17 in file test2.sql
Records affected: 0
rollback;
update RDB$PROCEDURES t set t.RDB$PACKAGE_NAME = null where coalesce(rdb$system_flag,0)=0 rows 1;
Statement failed, SQLSTATE = 42000
UPDATE operation is not allowed for system table RDB$PROCEDURES
After line 19 in file test2.sql
Records affected: 0
rollback;
update RDB$PROCEDURES t set t.RDB$PRIVATE_FLAG = null where coalesce(rdb$system_flag,0)=0 rows 1;
Statement failed, SQLSTATE = 42000
UPDATE operation is not allowed for system table RDB$PROCEDURES
After line 21 in file test2.sql
Records affected: 0
rollback;

How could 'rollback;' statements that are placed after each DML prohibit all subsequent updates except first one ?

@firebird-automations
Copy link
Collaborator Author

Modified by: @AlexPeshkoff

assignee: Alexander Peshkov [ alexpeshkoff ]

@firebird-automations
Copy link
Collaborator Author

Commented by: @AlexPeshkoff

Behavior is as designed.

The only update possible for RDB$PROCEDURES (and RDB$TRIGGERS) is setting to NULL source blob. If this field is nullified and other fields are not changed update is possible. Therefore setting in single transaction fields that are already NULL to NULL is possible together with nullifying source blob. When you add rollback between update operators first condition (source blob is nullified) is not satisfied any more.

@firebird-automations
Copy link
Collaborator Author

Modified by: @AlexPeshkoff

status: Open [ 1 ] => Resolved [ 5 ]

resolution: Won't Fix [ 2 ]

@firebird-automations
Copy link
Collaborator Author

Modified by: @pcisar

status: Resolved [ 5 ] => Closed [ 6 ]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants