NULL
<=> non-NULL
conversions you didn’t ask for
Teaching you how to declare, use, and write UDFs is outside the scope of this guide.However, we must warn you that UDFs can occasionally perform unexpected NULL
conversions.This will sometimes result in NULL
input being converted to a regular value, and other times in the nullification of valid input like ''
(an empty string).
The main cause of this problem is that with “old style” UDF calling (inherited from InterBase), it is not possible to pass NULL
as input to the function.When a UDF like LTRIM
(left trim) is called with a NULL
argument, the argument is passed to the function as an empty string.(Note: in Firebird 2 and up, it can also be passed as a null pointer.We’ll get to that later.)From inside the function there is no way of telling if this argument represents a real empty string or a NULL
.So what does the function implementor do?He has to make a choice: either take the argument at face value, or assume it was originally a NULL
and treat it accordingly.
If the function result type is a pointer, returning NULL
is possible even if receiving NULL
isn’t.Thus, the following unexpected things can happen:
-
You call a UDF with a
NULL
argument.It is passed as a value, e.g.0
or''
.Within the function, this argument is not changed back toNULL
;a non-NULL
result is returned. -
You call a UDF with a valid argument like
0
or''
.It is passed as-is (obviously).But the function code supposes that this value really represents aNULL
, treats it as a black hole, and returnsNULL
to the caller.
Both conversions are usually unwanted, but the second probably more so than the first (better validate something NULL
than wreck something valid).To get back to our LTRIM
example: in Firebird 1.0, this function returns NULL
if you feed it an empty string.This is wrong.In 1.5 it never returns NULL
: even NULL
strings (passed by the engine as ''
) are “trimmed” to empty strings.This is also wrong, but it’s considered the lesser of two evils.Firebird 2 has finally got it right: a NULL
string gives a NULL
result, an empty string is trimmed to an empty string — at least if you declare the function in the right way.