Thread: Making cstring type less pseudo and more real

Making cstring type less pseudo and more real

From
Tom Lane
Date:
The original problem with "opaque" is gone in CVS tip:

regression=# select cash_out(2);
ERROR:  Function cash_out(integer) does not exist       Unable to identify a function that satisfies the given argument
types      You may need to add explicit typecasts
 

However, I'm not entirely satisfied with it.  In particular, the type
system will still allow you to pass the result of an output function to
another input function:

regression=# select textin(inet_out('123.123.123.123'));textin
--------

(1 row)

I should have gotten '123.123.123.123' here, but didn't, and in other
cases I get garbage.  (I'm not sure that a crash is possible, but I'm
not sure one isn't, either.)  This seems like a reasonable operation
in many cases, so I don't really want to put in a kluge to disallow it.

The problem comes down to the fact that the system can't really cope
with Datums of type cstring: it doesn't know how to copy them.  We have
cstring declared as a pass-by-value type, which it isn't, and so the
pointer gets pushed around without concern for copying the pointed-to
string.

I am thinking about declaring type cstring in pg_type as
pass-by-reference with typlen set to -2, and altering the places that
interpret typlen to understand -2 as meaning null-terminated string.
(Currently, typlen > 0 means a fixed-length type, typlen = -1 is used
for varlena values which have a length word, and there's no meaning
assigned to other negative typlen values.)

I haven't really looked to see how many places would need to change,
but if it's not too many then this seems reasonable to do --- it would
make the cstring feature a lot more robust than it is now.

Comments?
        regards, tom lane


Re: Making cstring type less pseudo and more real

From
Alvaro Herrera
Date:
En Thu, 22 Aug 2002 11:52:08 -0400
Tom Lane <tgl@sss.pgh.pa.us> escribió:

> The original problem with "opaque" is gone in CVS tip:
> 
> regression=# select cash_out(2);
> ERROR:  Function cash_out(integer) does not exist
>         Unable to identify a function that satisfies the given argument types
>         You may need to add explicit typecasts

Yes, but how does it work?

alvh=> CREATE TABLE money_test (a money);
CREATE TABLE
alvh=> INSERT INTO money_test VALUES (2);
ERROR:  column "a" is of type 'money' but expression is of type 'integer'You will need to rewrite or cast the
expression
alvh=> INSERT INTO money_test VALUES ('2');
ERROR:  Bad money external representation 2
alvh=> INSERT INTO money_test VALUES ('2.00');
ERROR:  Bad money external representation 2.00
alvh=> INSERT INTO money_test VALUES ('$2.00');
ERROR:  Bad money external representation $2.00
alvh=> INSERT INTO money_test VALUES ('2'::money);
ERROR:  Bad money external representation 2
alvh=> INSERT INTO money_test VALUES (money(2));
ERROR:  Function money(integer) does not existUnable to identify a function that satisfies the given argument typesYou
mayneed to add explicit typecasts
 


> I am thinking about declaring type cstring in pg_type as
> pass-by-reference with typlen set to -2, and altering the places that
> interpret typlen to understand -2 as meaning null-terminated string.
> (Currently, typlen > 0 means a fixed-length type, typlen = -1 is used
> for varlena values which have a length word, and there's no meaning
> assigned to other negative typlen values.)

Sounds good.

> I haven't really looked to see how many places would need to change,
> but if it's not too many then this seems reasonable to do --- it would
> make the cstring feature a lot more robust than it is now.

At least all places that call get_typlenbyval() and get_typlen() or get
the typlen directly, it seems.  They are not too much, AFAICS...

-- 
Alvaro Herrera (<alvherre[a]atentus.com>)
Si no sabes adonde vas, es muy probable que acabes en otra parte.


Re: Making cstring type less pseudo and more real

From
Tom Lane
Date:
Alvaro Herrera <alvherre@atentus.com> writes:
> alvh=> CREATE TABLE money_test (a money);
> CREATE TABLE
> alvh=> INSERT INTO money_test VALUES (2);
> ERROR:  column "a" is of type 'money' but expression is of type 'integer'
>     You will need to rewrite or cast the expression
> alvh=> INSERT INTO money_test VALUES ('2');
> ERROR:  Bad money external representation 2
> alvh=> INSERT INTO money_test VALUES ('2.00');
> ERROR:  Bad money external representation 2.00
> alvh=> INSERT INTO money_test VALUES ('$2.00');
> ERROR:  Bad money external representation $2.00
> alvh=> INSERT INTO money_test VALUES ('2'::money);
> ERROR:  Bad money external representation 2

What does "show lc_monetary" say?  I think you may be in a non-US locale.
        regards, tom lane