The following bug has been logged online:
Bug reference: 2490
Logged by: Nikolay Samokhvalov
Email address: pg-bugs@samokhvalov.com
PostgreSQL version: CVS
Operating system: fedora core 5
Description: '||' and type casting for user defined types
Details:
Assume that we are creating foolish type 'aaa', which works like
varchar(3),
or is simply 'string, which length is not more than 3'.
In/out functions for this type:
Datum
aaa_in(PG_FUNCTION_ARGS)
{
char *s = PG_GETARG_CSTRING(0);
int len = strlen(s);
VarChar *result;
if (len > 3)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
errmsg("too much chars: length=\"%d\"",
len)));
result = (VarChar *) palloc(len + VARHDRSZ);
VARATT_SIZEP(result) = len + VARHDRSZ;
memcpy(VARDATA(result), s, len);
PG_RETURN_VARCHAR_P(result);
}
Datum
aaa_out(PG_FUNCTION_ARGS)
{
VarChar *s = PG_GETARG_VARCHAR_P(0);
char *result;
int32 len;
/* copy and add null term */
len = VARSIZE(s) - VARHDRSZ;
result = palloc(len + 1);
memcpy(result, VARDATA(s), len);
result[len] = '\0';
PG_RETURN_CSTRING(result);
}
SQL code:
CREATE FUNCTION aaa_in(cstring)
RETURNS aaa
AS 'MODULE_PATHNAME'
LANGUAGE C RETURNS NULL ON NULL INPUT;
CREATE FUNCTION aaa_out(aaa)
RETURNS cstring
AS 'MODULE_PATHNAME'
LANGUAGE C RETURNS NULL ON NULL INPUT;
CREATE TYPE aaa (
INTERNALLENGTH = -1,
INPUT = aaa_in,
OUTPUT = aaa_out,
STORAGE = extended
);
CREATE CAST (aaa AS text) WITHOUT FUNCTION
AS IMPLICIT;
CREATE CAST (text AS aaa) WITHOUT FUNCTION
AS IMPLICIT;
Well, let's do some tests. After applying sql code in the database 'trash':
trash=# select 'asd'::aaa;
aaa
-----
asd
(1 row)
trash=# select 'asdf'::aaa;
ERROR: too much chars: length="4"
trash=# select ('as' || 'df')::aaa;
aaa
------
asdf
(1 row)
In the last case, function aaa_in() wasn't invoked at all and we obtained
the sting of type aaa with length > 3...