The following bug has been logged online:

Bug reference:      2490
Logged by:          Nikolay Samokhvalov
Email address:      [EMAIL PROTECTED]
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...

---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

Reply via email to