Subject | String arguments in functions -- cont'd from dev-list |
---|---|
Author | paulruizendaal |
Post date | 2004-02-11T19:42:56Z |
From the dev-list:
lower, lpad, ltrim, rpad, rtrim, substr, substrlen are declared with
CSTRING(80) parameters. After a discussion we've agreed to change
declarations to CSTRING(1024). It was suggested by Ann as a
compromise between the current length and Helen's suggestion of
32767.
And Jim commented:
As soon as FB 1.5 gets out the door, somebody should have a good long
think. The design is obviously intractible. Somebody, almost
certainly me, screwed up. Somebody, please, find a way to create
UDFs that don't have arbitrary limits and don't consume arbitrarily
large amounts of memory. This sort of tradeoff is unacceptable. Just
don't fix it in 1.5!
Sergio Samayoa wrote:
In Oracle you declare just the type of the parameters (CHAR, VARCHAR,
VARCHAR2, etc) without size. It will be nice if fb2 (or Vulcan?) can
declare UDF as Oracle did. Even nive if UDF can be external functions
(as it is now) or PL code:
CREATE FUNCTION JUST_AN_EXAMPLE (P_VARCHAR_PARAM VARCHAR)
RETURNS VARCHAR
AS
BEGIN
/* Do something... */
RETURN V_SOME_VARCHAR_VALUE;
END
I would like to add the following:
Jim and Sergio are right: in a programming language, it is design
mistake to make the size of an (character) array part of the array
data type; Dennis Ritchie argued this well, back in '81:
http://www.lysator.liu.se/c/bwk-on-pascal.html
The Oracle solution seems practical to me. I have implemented it in
the PL/SQL-runtime that is part of the Compiere/FB project and have
not come across significant problems. I'm sure we can do UDF's in a
similar fashion.
Within the PL/SQL runtime, there are only a few basic datatypes, int,
float, the usual. Beyond the usual, one of the basic types
is 'object'. This can be a string, a cursor, a blob etc. The string
object has no predefined size: it just flexes with actual content.
There is however one issue that I have no solution for -- partly
because I haven't studied the OSRI design well enough to oversee all
potential complications. Let me explain:
Building on Sergio's example, if we issue a request like
SELECT JUST_AN_EXAMPLE('X') FROM RDB$RELATIONS
the sql-compiler needs to decide on the size of the result column
when the statement is prepared. It cannot defer the choice, because
it must set the size of the relevant message port. Reading the first
row and baseing the choice on the size of that element is no option,
because each row can be of different size.
I've thought about solving this by making undetermined-size string
result columns like a text blob: the message port is sized for a 64-
bit guid and this guid is used to get the string back segment-by-
segment. Strings with known sizes would be handled the usual way. I'm
not sure at all that this would be The Right Thing.
For the current Compiere/FB prototype I've used a quick fix: the
compiler says that undetermined-size strings are CSTRING(4096) :^(
The floor is open for suggestions. Anyone??
Paul
lower, lpad, ltrim, rpad, rtrim, substr, substrlen are declared with
CSTRING(80) parameters. After a discussion we've agreed to change
declarations to CSTRING(1024). It was suggested by Ann as a
compromise between the current length and Helen's suggestion of
32767.
And Jim commented:
As soon as FB 1.5 gets out the door, somebody should have a good long
think. The design is obviously intractible. Somebody, almost
certainly me, screwed up. Somebody, please, find a way to create
UDFs that don't have arbitrary limits and don't consume arbitrarily
large amounts of memory. This sort of tradeoff is unacceptable. Just
don't fix it in 1.5!
Sergio Samayoa wrote:
In Oracle you declare just the type of the parameters (CHAR, VARCHAR,
VARCHAR2, etc) without size. It will be nice if fb2 (or Vulcan?) can
declare UDF as Oracle did. Even nive if UDF can be external functions
(as it is now) or PL code:
CREATE FUNCTION JUST_AN_EXAMPLE (P_VARCHAR_PARAM VARCHAR)
RETURNS VARCHAR
AS
BEGIN
/* Do something... */
RETURN V_SOME_VARCHAR_VALUE;
END
I would like to add the following:
Jim and Sergio are right: in a programming language, it is design
mistake to make the size of an (character) array part of the array
data type; Dennis Ritchie argued this well, back in '81:
http://www.lysator.liu.se/c/bwk-on-pascal.html
The Oracle solution seems practical to me. I have implemented it in
the PL/SQL-runtime that is part of the Compiere/FB project and have
not come across significant problems. I'm sure we can do UDF's in a
similar fashion.
Within the PL/SQL runtime, there are only a few basic datatypes, int,
float, the usual. Beyond the usual, one of the basic types
is 'object'. This can be a string, a cursor, a blob etc. The string
object has no predefined size: it just flexes with actual content.
There is however one issue that I have no solution for -- partly
because I haven't studied the OSRI design well enough to oversee all
potential complications. Let me explain:
Building on Sergio's example, if we issue a request like
SELECT JUST_AN_EXAMPLE('X') FROM RDB$RELATIONS
the sql-compiler needs to decide on the size of the result column
when the statement is prepared. It cannot defer the choice, because
it must set the size of the relevant message port. Reading the first
row and baseing the choice on the size of that element is no option,
because each row can be of different size.
I've thought about solving this by making undetermined-size string
result columns like a text blob: the message port is sized for a 64-
bit guid and this guid is used to get the string back segment-by-
segment. Strings with known sizes would be handled the usual way. I'm
not sure at all that this would be The Right Thing.
For the current Compiere/FB prototype I've used a quick fix: the
compiler says that undetermined-size strings are CSTRING(4096) :^(
The floor is open for suggestions. Anyone??
Paul