Thread: Making cstring type less pseudo and more real
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
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.
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