Subject Re: [ib-support] Re: UDF Failure
Author Claudio Valderrama C.
""iananewby"" <ian@...> wrote in message
news:a7q7j1+h50m@......
> Hi Mirco,
>
> The "implementation limit exceeded" message only started to occur
> after I upgraded to Firebird 1 from RC2.

I don't think they are directly related (to your other issue).
Do you concatenate legally forbidden strings? The max length should have
been always 32767, but people keep going above that limit. Did you know what
happens inside the engine? Nice buffer overrun with obscure consequences
that I will explain someday.
The limit will be approx 65510 for FB1.1 but it's left to the user
judgement. If the programmer has no common sense, then he/she will enjoy the
fruits of his/her own inepcy.
It's safe to use declarations between 32K and 64K inside stored procedures,
but it's not safe to use those declaration if they are externally visible.
Examples:
- the API uses signed short ints for field lengths (XSQLVAR), just think a
bit what you get with values between 32K and 64K, a nice negative number if
your program or the package you are using doesn't treat them as unsigned.
- DSQL already limits field length to 32K, just try to define char(45000)
and it rejects the statement.
- However, you can cheat and create a computed field based on a
concatenation that produces a 50K field. This field will be like a thorn in
your throat if you define it. Worse yet, DSQL has no range check at all in
several paths of execution, hence... you may be imaginative here.
- When you are in the [32K-64K[ range, some counters may wrap. When you are
above 64K-1, all the unsigned counters wrap, too, but they are unsigned, you
can't notice the problem (if you get a negative value, at least you smell
problems).

In short, if you abused the range from the illegal to the plain impossible
values (starting at 64K), you won't be able to use them anymore until all
internal limits and counters in the engine are updated and this is a major
ODS change, just look at the system tables, they use signed shorts for
lengths and other duties.

SQL> create table flim(a char(32000), b computed by (a||a));
SQL> commit;
SQL> select rdb$field_length from rdb$fields f join rdb$relation_fields rf
on f.rdb$field_name=rf.rdb$field_source and rf.rdb$relation_name='FLIM';

RDB$FIELD_LENGTH
================
32000
-1536

Indeed, the API's XSQLVAR's sqllen shows -1536 unless you treat it as
unsigned.

C.
--
Claudio Valderrama C. - http://www.cvalde.com - http://www.firebirdSql.org
Independent developer
Owner of the Interbase® WebRing