Обсуждение: BUG #4362: Casts from base types to composite types don't work.

Поиск
Список
Период
Сортировка

BUG #4362: Casts from base types to composite types don't work.

От
"Andrej Podzimek"
Дата:
The following bug has been logged online:

Bug reference:      4362
Logged by:          Andrej Podzimek
Email address:      andrej@podzimek.org
PostgreSQL version: 8.3
Operating system:   Linux
Description:        Casts from base types to composite types don't work.
Details:

CREATE TYPE pxgt_xid AS (xid bigint, xname text);

CREATE FUNCTION pxgt_xid(text) RETURNS pxgt_xid AS
$BODY$ select cast ( null as bigint ), $1; $BODY$
LANGUAGE 'sql' IMMUTABLE;

CREATE CAST (text AS pxgt_xid) WITH FUNCTION pxgt_xid(bigint) AS IMPLICIT;

select cast (text 'blabla' as pxgt_xid);
ERROR:  malformed record literal: "blabla"
DETAIL:  Missing left parenthesis.

When I create a similar cast for bigint->pxgt_xid, it seems to work. But in
fact an implicit cast works here, not the defined one... So as long as the
first field is a bigint, a default cast is used and the second field is just
set to null automatically. So implicit casts bigint->pxgt_xid and
(bigint)->pxgt_xid (with bigint in a simple record) work fine. But the cast
defined above is simply ignored.

AFAIK, the documentation does not mention that casts between base and
composite types are discouraged, prohibited or impossible.

Theoretically, it should be possible to create a function that accepts the
type pxgt_xid, which contains either a text or a numeric identifier. By
adding just one "is null" condition, one could have the code for both
identifier types in one function, without function overloading. That would
be great ... if the implicit cast above worked.

Re: BUG #4362: Casts from base types to composite types don't work.

От
Tom Lane
Дата:
"Andrej Podzimek" <andrej@podzimek.org> writes:
> select cast (text 'blabla' as pxgt_xid);
> ERROR:  malformed record literal: "blabla"
> DETAIL:  Missing left parenthesis.

Works for me, after fixing the obvious typo in your CREATE CAST command:

regression=# CREATE TYPE pxgt_xid AS (xid bigint, xname text);
CREATE TYPE
regression=# CREATE FUNCTION pxgt_xid(text) RETURNS pxgt_xid AS
$BODY$ select cast ( null as bigint ), $1; $BODY$
LANGUAGE 'sql' IMMUTABLE;
CREATE FUNCTION
regression=# CREATE CAST (text AS pxgt_xid) WITH FUNCTION pxgt_xid(text) AS IMPLICIT;
CREATE CAST
regression=# select cast (text 'blabla' as pxgt_xid);
 pxgt_xid
-----------
 (,blabla)
(1 row)


            regards, tom lane