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

Allow hiding source code of procedures and triggers in FB 3 [CORE4544] #4862

Closed
firebird-automations opened this issue Sep 6, 2014 · 10 comments

Comments

@firebird-automations
Copy link
Collaborator

Submitted by: @WarmBooter

Votes: 2

As discussed in fb-devel, there should be a way to hide the source code of procedures and triggers in FB 3, either by allowing the long-time-used "hack" of nulling the source code in the system tables, or implementing an official way.

@firebird-automations
Copy link
Collaborator Author

Commented by: @dyemanov

Solution for v3 Beta 2 and beyond: re-allow setting RDB$*_SOURCE to NULL (while protecting all other modifications).

@firebird-automations
Copy link
Collaborator Author

Modified by: @dyemanov

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

resolution: Fixed [ 1 ]

Fix Version: 3.0 Beta 2 [ 10586 ]

assignee: Dmitry Yemanov [ dimitr ]

@firebird-automations
Copy link
Collaborator Author

Commented by: @pavel-zotov

Engine raises exception when 'UPDATE ... SET RDB$...SOURCE = NULL' tries to clear source of some object (proc/trigger) *again*, i.e. when this field already is NULL. This will borrow anyone who already has some units with NULL value in source and has added several units after it: one need to explicitly enumerate these units that has to be cleared.
Consider following sample:

=== begin of script ===

recreate table test(id int primary key, x int);
recreate table tlog(id int, x int);

recreate sequence g;

set term ^;
create or alter procedure sp_test1 as
declare c int;
begin
select count(*) from rdb$types into c;
end
^

create or alter function fn_test1 returns int as
begin
return 111;
end
^

create or alter trigger trg_test_1 active before insert on test as
begin
http://new.id = gen_id(g,1);
end
^

set term ;^
commit;

set blob all;
set list on;

------------------------------------------------------ [ 1 ] --------------------------------------------------
set echo on;

select rdb$procedure_name, rdb$procedure_source from rdb$procedures where rdb$system_flag is distinct from 1;

select rdb$function_name, rdb$function_source from rdb$functions where rdb$system_flag is distinct from 1;

select rdb$trigger_name, rdb$trigger_source from rdb$triggers where rdb$system_flag is distinct from 1;

set count on;

update rdb$procedures set rdb$procedure_source = null
where
rdb$system_flag is distinct from 1
;

update rdb$functions set rdb$function_source = null
where
rdb$system_flag is distinct from 1
;

update rdb$triggers set rdb$trigger_source = null
where
rdb$system_flag is distinct from 1
;

commit;

set echo off;
set count off;

set term ^;

create or alter procedure sp_test2 as
declare c int;
begin
select count(*) from rdb$types into c;
end
^

create or alter function fn_test2 returns int as
begin
return 222;
end
^

create or alter trigger trg_test_2 active after insert or update or delete on test as
begin
if ( not deleting ) then
insert into tlog(id, x) values( http://new.id, new.x );
else
insert into tlog(id, x) values( http://old.id, old.x );
end
^

set term ;^
commit;

set count on;

------------------------------------------------------ [ 2 ] --------------------------------------------------
set echo on;

update rdb$procedures set rdb$procedure_source = null
where
rdb$system_flag is distinct from 1
;

update rdb$functions set rdb$function_source = null
where
rdb$system_flag is distinct from 1
;

update rdb$triggers set rdb$trigger_source = null
where
rdb$system_flag is distinct from 1
;

commit;

set count off;

select rdb$procedure_name, rdb$procedure_source from rdb$procedures where rdb$system_flag is distinct from 1;

select rdb$function_name, rdb$function_source from rdb$functions where rdb$system_flag is distinct from 1;

select rdb$trigger_name, rdb$trigger_source from rdb$triggers where rdb$system_flag is distinct from 1;

=== end of script ===

Statements 'update ... set rdb$source = null' in block marked as [ 1 ] will execute without exceptions.
Statements in block marked as [ 2 ] will raise

Statement failed, SQLSTATE = 42000
UPDATE operation is not allowed for system table RDB$...

- and this mean that units that appear after 1st 'update ... set null' (i.e. 'SP_TEST2', 'FN_TEST2' and 'TRG_TEST_2') remain with source code: we have explicitly specify them in 2nd update serie.

@firebird-automations
Copy link
Collaborator Author

Commented by: @pavel-zotov

PS. Of course, we can add in every UPDATE statement additional line like "and rdb$procedure_source is not null" but IMO it engine should allow to avoid this.

@firebird-automations
Copy link
Collaborator Author

Commented by: @pavel-zotov

PPS.

update rdb$packages set rdb$package_body_source = null
where
rdb$system_flag is distinct from 1
and rdb$package_body_source is not null
;
Statement failed, SQLSTATE = 42000
UPDATE operation is not allowed for system table RDB$PACKAGES
After line 85 in file . . .
Records affected: 0

Not implemented yet ?

@firebird-automations
Copy link
Collaborator Author

Modified by: @pcisar

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

QA Status: Done successfully

@firebird-automations
Copy link
Collaborator Author

Commented by: @dyemanov

NULL->NULL changes are intentionally prohibited. The problem, AFAIR, is that it's impossible to distinguish between e.g. SET RDB$PROCEDURE_SOURCE = NULL and SET RDB$PROCEDURE_NAME = RDB$PROCEDURE_NAME or any other kind of dummy update. This may cause confusion as some direct system table updates (that do not actually change anything) become allowed, e.g.:

update rdb$relations set rdb$system_flag = 0

would succeed for records already having rdb$system_flag = 0 and fail for others, and this is impossible to predict without knowing what's actually stored inside rdb$system_flag.

Given that the SOURCE->NULL changes are allowed only temporarily, until something better is implemented, and given that the issue can be worked around using the WHERE clause, I tend to leave everything as is.

@firebird-automations
Copy link
Collaborator Author

Commented by: @dyemanov

SET RDB$PACKAGE_BODY_SOURCE = NULL is allowed now.

@firebird-automations
Copy link
Collaborator Author

Modified by: @pavel-zotov

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

@firebird-automations
Copy link
Collaborator Author

Modified by: @pavel-zotov

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

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