Firebird Documentation Index → Firebird 2.1 Language Ref. Update → Notes → Passing NULL to UDFs in Firebird 2 |
Table of Contents
If a pre-2.0 Firebird engine must pass an SQL NULL
argument to a
user-defined function, it always converts it to a zero-equivalent, e.g. a numerical 0 or an
empty string. The only exception to this rule are UDFs that make use of the
“BY DESCRIPTOR” mechanism introduced in Firebird 1. The
fbudf
library uses descriptors, but the vast majority
of UDFs, including those in Firebird's standard ib_udf
library, still use the old style of parameter passing,
inherited from InterBase.
As a consequence, most UDFs can't tell the difference between NULL
and zero input.
Firebird 2 comes with a somewhat improved calling mechanism for these old-style UDFs.
The engine will now pass NULL
input as a null pointer to the function,
if the function has been declared to the database with a
NULL keyword after the argument(s) in question, e.g. like this:
declare external function ltrim
cstring(255) null
returns cstring(255) free_it
entry_point 'IB_UDF_ltrim' module_name 'ib_udf';
This requirement ensures that existing databases and their applications can continue to function like before. Leave out the NULL keyword and the function will behave like it did under Firebird 1.5 and earlier.
Please note that you can't just add NULL keywords to your
declarations and then expect every function to handle NULL
input
correctly. Each function has to be (re)written in such a way that NULL
s
are dealt with correctly. Always look at the declarations provided by the function
implementor. For the functions in the ib_udf
library,
consult ib_udf2.sql
in the Firebird UDF
directory. Notice the 2
in the file name;
the old-style declarations are in ib_udf.sql
.
These are the ib_udf
functions that have been
updated to recognise NULL
input and handle it properly:
ascii_char
lower
lpad
and rpad
ltrim
and rtrim
substr
and substrlen
Most ib_udf
functions remain as they were; in
any case, passing NULL
to an old-style UDF is never possible if the
argument isn't of a referenced type.
On a side note: don't use lower
, .trim
and
substr*
in new code; use the internal functions
LOWER, TRIM and SUBSTRING
instead.
If you are using an existing database with one or more of the functions listed above
under Firebird 2, and you want to benefit from the improved NULL
handling, run the script ib_udf_upgrade.sql
against your database. It
is located in the Firebird misc\upgrade\ib_udf
directory.
Firebird Documentation Index → Firebird 2.1 Language Ref. Update → Notes → Passing NULL to UDFs in Firebird 2 |