Closed dmitry-lipetsk closed 8 months ago
Backup file without these values is malformed. An error must be raised on attempt to restore such backup. To accomplish that the fields must be declared with NOT NULL.
Without initialization to NULL in GBAK, this "NOT NULL" field will be assigned with NOT NULL garbage.
Am I right?
Maybe i did not understand properly: what RDB$ table must be checked ?
Initial DDL:
set list on;
set bail on;
shell del g:\temp\tmp4test.fdb 2>nul;
create database 'localhost:g:\temp\tmp4test.fdb' user sysdba password 'masterkey';
set term ^;
create or alter function fn_test(a_x int, a_y timestamp, a_z boolean) returns varchar(50) character set utf8 as
begin
return '';
end
^
set term ;^
commit;
select f.rdb$return_argument from rdb$functions f where f.rdb$function_name = upper('fn_test');
select g.rdb$argument_name, g.rdb$argument_position from rdb$function_arguments g where g.rdb$function_name = upper('fn_test');
2) do backup and restore:
gbak -b localhost:g:\temp\tmp4test.fdb stdout | gbak -rep stdin localhost:g:\temp\tmp4test.tmp.fdb
3) check what we have in restored DB:
set list on;
select f.rdb$return_argument from rdb$functions f where f.rdb$function_name = upper('fn_test');
select g.rdb$argument_name, g.rdb$argument_position from rdb$function_arguments g where g.rdb$function_name = upper('fn_test');
Result for both init and check scripts:
RDB$RETURN_ARGUMENT 0
RDB$ARGUMENT_NAME <null>
RDB$ARGUMENT_POSITION 0
RDB$ARGUMENT_NAME A_X
RDB$ARGUMENT_POSITION 1
RDB$ARGUMENT_NAME A_Y
RDB$ARGUMENT_POSITION 2
RDB$ARGUMENT_NAME A_Z
RDB$ARGUMENT_POSITION 3
(i.e. no differences)
PS. WI-T6.0.0.230 Firebird 6.0 Initial
Maybe i did not understand properly: what RDB$ table must be checked ?
Your test looks correctly.
One moment - I think, select statements must have "rdb$package_name is null" condition in WHERE sections.
Or select a value of this field.
Just to suppress a paranoia :)
select statements must have "rdb$package_name is null" condition in WHERE sections. Or select a value of this field.
I still no see any problem. Please consider results from attached .zip gh-7869-test.zip
Difference file ( gh-7869-diff.log ) shows that gbak does NOT write nulls in some places (in contrary to initial .sql). Rather, these fields are filled with either zeroes or empty strings during restore:
Comparing files gh-7869-init.log and GH-7869-CHK.LOG
***** gh-7869-init.log
212: RDB$FUNCTION_NAME PG_FUNC
215: RDB$FUNCTION_TYPE <null>
216: RDB$QUERY_NAME <null>
217: RDB$DESCRIPTION <null>
***** GH-7869-CHK.LOG
212: RDB$FUNCTION_NAME PG_FUNC
215: RDB$FUNCTION_TYPE 0
216: RDB$QUERY_NAME
219: RDB$DESCRIPTION <null>
*****
. . .
***** gh-7869-init.log
1091: RDB$ARGUMENT_POSITION 1
1092: RDB$MECHANISM <null>
1093: RDB$FIELD_TYPE <null>
1094: RDB$FIELD_SCALE <null>
1095: RDB$FIELD_LENGTH <null>
1096: RDB$FIELD_SUB_TYPE <null>
1097: RDB$CHARACTER_SET_ID <null>
***** GH-7869-CHK.LOG
1095: RDB$ARGUMENT_POSITION 1
1096: RDB$MECHANISM 0
1097: RDB$FIELD_TYPE 0
1098: RDB$FIELD_SCALE 0
1099: RDB$FIELD_LENGTH 0
1100: RDB$FIELD_SUB_TYPE 0
1101: RDB$CHARACTER_SET_ID <null>
PS. Checked also on 6.0.0.135, build date: 21-nov-2023.
Logs in attachment: gh-7869-init.log -- log after we create packaged and standalone functions and query rdb$ tables; gh-7869-chk.log -- log after we do backup and restore of that DB and again query rdb$ tables. gh-7869-diff.log -- diff
GBAK does not initialize RDB$RETURN_ARGUMENT, RDB$ARGUMENT_POSITION fields and can write unexpected values into restored database when backup does not have data for ones.
See these two functions:
get_function https://github.com/FirebirdSQL/firebird/blob/cf98c6e97f6fa25eabe81b23b1a7ac6900e51be5/src/burp/restore.epp#L4947
get_function_arg https://github.com/FirebirdSQL/firebird/blob/cf98c6e97f6fa25eabe81b23b1a7ac6900e51be5/src/burp/restore.epp#L5333
I offer to add the initialization of these fields with NULL value.