Firebird Documentation Index → Firebird 2.5 Language Ref. Update → Notes → A note on CSTRING parameters |
External functions involving strings often use the type
CSTRING(n
) in their declarations. This type
represents a zero-terminated string of maximum length n
. Most of
the functions handling CSTRINGs are programmed in such a way that they
can accept and return zero-terminated strings of any length. So why the
n
? Because the Firebird engine has to set up space to process the
input an output parameters, and convert them to and from SQL data types. Most strings used in
databases are only dozens to hundreds of bytes long; it would be a waste to reserve 32 KB of
memory each time such a string is processed. Therefore, the standard
declarations of most CSTRING functions – as found in the file
ib_udf.sql
– specify a length of 255 bytes. (In Firebird 1.5.1 and below,
this default length is 80 bytes.) As an example, here's the SQL declaration of
lpad
:
DECLARE EXTERNAL FUNCTION lpad CSTRING(255), INTEGER, CSTRING(1) RETURNS CSTRING(255) FREE_IT ENTRY_POINT 'IB_UDF_lpad' MODULE_NAME 'ib_udf'
Once you've declared a CSTRING parameter with a certain length, you cannot call the function with a longer input string, or cause it to return a string longer than the declared output length. But the standard declarations are just reasonable defaults; they're not cast in concrete, and you can change them if you want to. If you have to left-pad strings of up to 500 bytes long, then it's perfectly OK to change both 255's in the declaration to 500 or more.
A special case is when you usually operate on short strings (say less then 100 bytes) but occasionally have to call the function with a huge (VAR)CHAR argument. Declaring CSTRING(32000) makes sure that all the calls will be successful, but it will also cause 32000 bytes per parameter to be reserved, even in that majority of cases where the strings are under 100 bytes. In that situation you may consider declaring the function twice, with different names and different string lengths:
DECLARE EXTERNAL FUNCTION lpad CSTRING(100), INTEGER, CSTRING(1) RETURNS CSTRING(100) FREE_IT ENTRY_POINT 'IB_UDF_lpad' MODULE_NAME 'ib_udf'; DECLARE EXTERNAL FUNCTION lpadbig CSTRING(32000), INTEGER, CSTRING(1) RETURNS CSTRING(32000) FREE_IT ENTRY_POINT 'IB_UDF_lpad' MODULE_NAME 'ib_udf';
Now you can call lpad()
for all the small strings and
lpadbig()
for the occasional monster. Notice how the declared names in
the first line differ (they determine how you call the functions from within your SQL), but
the entry point (the function name in the library) is the same in both cases.
Firebird Documentation Index → Firebird 2.5 Language Ref. Update → Notes → A note on CSTRING parameters |