BUG #2490: '||' and type casting for user defined types

Started by Nikolay Samokhvalovalmost 20 years ago2 messagesbugs
Jump to latest
#1Nikolay Samokhvalov
pg-bugs@samokhvalov.com

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...

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Nikolay Samokhvalov (#1)
Re: BUG #2490: '||' and type casting for user defined types

"Nikolay Samokhvalov" <pg-bugs@samokhvalov.com> writes:

CREATE CAST (aaa AS text) WITHOUT FUNCTION
AS IMPLICIT;
CREATE CAST (text AS aaa) WITHOUT FUNCTION
AS IMPLICIT;

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...

Well, sure. You declared the text to aaa cast as WITHOUT FUNCTION; that
says the system can relabel any legal text value as an aaa. If you want
to enforce a length limit on the cast result, you need to write a cast
function that does it.

regards, tom lane