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

Compilation of Firebird procedures - Firebird 3.0 (Win) doesn't check procedures parameters [CORE6381] #6620

Open
firebird-automations opened this issue Aug 6, 2020 · 3 comments

Comments

@firebird-automations
Copy link
Collaborator

Submitted by: Kevin Smith (kevinsmith)

Consider following example.
First create two dependent procedures:
set term ^;
create or alter procedure A
(
Val integer
)
returns
(
RValue integer
)
as
begin
RValue = RValue * 2;
end
^

create or alter procedure B
returns
(
RValue integer
)
as
begin
execute procedure A(10)
returning_values(RValue);
end

Next alter one of procedure (add input parameter) without altering second procedure:
set term ^;
create or alter procedure A
(
Val integer,
X integer
)
returns
(
RValue integer
)
as
begin
RValue = RValue * X;
end
^

Finally, try to compile procedures:
update rdb$procedures set RDB$PROCEDURE_SOURCE = null where (RDB$PROCEDURE_SOURCE is not null) and (rdb$system_flag=0);
commit;

In Firebird 2.5 and Firebird 3.0 (Linux) we've got error (which is obviously correct and expected)

/*******************************************************************************
The next statement causes the following error:

can't format message 13:99 -- message file C:\Softhard\firebird.msg not found.
Error while parsing procedure B's BLR.
invalid request BLR at offset 32.
Input parameter mismatch for procedure A.
*******************************************************************************/
commit;

However Firebird 3.0 (Win) allow us to compile such procedures. That lead us to having database which we can backup but cannot restore, because of error:

gbak:creating indexes
gbak:committing metadata
gbak: ERROR:invalid request BLR at offset 32
gbak: ERROR: Input parameter mismatch for procedure A
gbak:Exiting before completion due to errors

@firebird-automations
Copy link
Collaborator Author

Commented by: @AlexPeshkoff

Kevin, the only thing that makes me surprised here is that behavior of FB3 on linux & windows differs for you. FB3 does not recompile procedures when one execs
update rdb$procedures set RDB$PROCEDURE_SOURCE = null ....
(you've used undocumented feature of firebird), and it should not do something on linux too.

I'd ask another question here - why does firebird makes it possible to modify procedure's parameters in an incompatible way? It should fail at step 2 of your description.

@firebird-automations
Copy link
Collaborator Author

Commented by: Kevin Smith (kevinsmith)

Alexander,
1. I've been using "update rdb$procedures set RDB$PROCEDURE_SOURCE = null" for more than 10 years and it has always worked like a charm.
Recently I've moved to Firebird 3 and that's where problems started.

Could you please tell me what is the proper way to compile procedures (my primary goal is to protect source code, though I fully understand that BLR is also quite easy to interpret but not as easy as fully readable source code).

2. As for your question in my humble opinion possibility to modify procedure parameters as stated in step 2 is quite convenient. Otherwise I would have to remove execution of procedure A in procedure B, modify procedure A, and finally modify procedure B.

@firebird-automations
Copy link
Collaborator Author

Commented by: @AlexPeshkoff

Modifying system tables directly used to work in some cases but was considered a bad practice and therefore ability to do it was removed from FB3 and it was explicitly mentioned in release notes, chapter 'Compatibility Issues'. The only exception was kept for procedure and trigger sources - they can nullified. But that does not mean that something gets recompiled.

A proper way to compile procedures is to create (or alter) them and commit transaction. Nothing else needed.
BTW, your method can leave database in unstable state if you nullify sources, after it change some parameters and try to nullify sources once again.

I still insist that the only correct way to fix a problem is to avoid invalid parameters at all. Certainly, check must be done not when DDL is issued but on commit after a series of DDLs. And that series must put database in logically correct state.

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

1 participant