Re: CAST(... ON DEFAULT) - WIP build on top of Error-Safe User Functions

From: jian he <jian(dot)universality(at)gmail(dot)com>
To: assam258(at)gmail(dot)com
Cc: corey(dot)huinker(at)gmail(dot)com, peter(at)eisentraut(dot)org, vik(at)postgresfriends(dot)org, sulamul(at)gmail(dot)com, reshkekirill(at)gmail(dot)com, isaac(dot)morland(at)gmail(dot)com, pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: CAST(... ON DEFAULT) - WIP build on top of Error-Safe User Functions
Date: 2026-07-07 06:12:17
Message-ID: CACJufxHPB2Ep-7KgtLBaSOSfKPBDjKwSr23d=Vx7ks4w0em44w@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Thu, Jul 2, 2026 at 10:06 PM Henson Choi <assam258(at)gmail(dot)com> wrote:
>>
>>
>> E. User-defined types reached via I/O coercion: reject, or support?
>>
>> The documentation says only built-in casts are supported, and a
>> user-defined WITH FUNCTION cast is rejected at parse time:
>>
>> CREATE FUNCTION int_to_point(int) RETURNS point
>> AS 'SELECT point($1, $1)' LANGUAGE sql IMMUTABLE;
>> CREATE CAST (int AS point) WITH FUNCTION int_to_point(int);
>> SELECT CAST(1 AS point DEFAULT NULL ON CONVERSION ERROR);
>> -- ERROR: cannot cast type integer to point with DEFAULT expression
>> -- in CAST ... ON CONVERSION ERROR
>> -- DETAIL: Safe type casts for user-defined types are not yet supported.
>>
>> But a user-defined type reached through I/O coercion (a WITH INOUT
>> cast, or a plain text->type explicit cast) is accepted, and a
>> hard-erroring input function then leaks straight through
>> ON CONVERSION ERROR instead of being rejected or folding into the
>> DEFAULT. widget_in/widget_out below are the deliberately hard-erroring
>> I/O functions from the regression suite (src/test/regress/regress.c),
>> with :regresslib set to the regression shared library as in
>> test_setup.sql:
>>
>> CREATE TYPE hardtype;
>> CREATE FUNCTION hardtype_in(cstring) RETURNS hardtype
>> AS :'regresslib', 'widget_in' LANGUAGE C STRICT IMMUTABLE;
>> CREATE FUNCTION hardtype_out(hardtype) RETURNS cstring
>> AS :'regresslib', 'widget_out' LANGUAGE C STRICT IMMUTABLE;
>> CREATE TYPE hardtype (internallength = 24, input = hardtype_in,
>> output = hardtype_out, alignment = double);
>> CREATE CAST (text AS hardtype) WITH INOUT;
>>
>> SELECT CAST('bad'::text AS hardtype DEFAULT NULL ON CONVERSION ERROR);
>> -- ERROR: invalid input syntax for type widget: "bad" (leaked, not DEFAULT/NULL;
>> -- the error says "widget" because the reused widget_in reports its own name)
>>
>> So the "not supported" rule is enforced for one path but not the other.
>>

But src/test/regress/regress.c have below comments:
/*
* Note: DON'T convert this error to "soft" style (errsave/ereturn). We
* want this data type to stay permanently in the hard-error world so that
* it can be used for testing that such cases still work reasonably.
*/

That means
SELECT CAST('bad'::text AS hardtype DEFAULT NULL ON CONVERSION ERROR);
is bound to error out.

SELECT pg_input_is_valid('bad', 'widget');
will also error out.

User-defined types coerced through I/O functions are assumed to be error-safe.
If the input function is implemented to support error-safe execution, the
coercion can also be evaluated in an error-safe manner; see EEOP_IOCOERCE_SAFE.
That's our current status, so I don't think we need to do anything special.

----------------------------------------------------------------------------------------------------
Since not all functions support error-safe execution, scenario A is
unavoidable. Scenarios C and D are explained in [1], while scenario B
mentioned in [2] is a bug.

[1] https://www.postgresql.org/message-id/CACJufxEawrK%2BFhFzyWMPKZ_r11jEqbzq4soUM2ZRBNSintQ%2BAQ%40mail.gmail.com
[2] https://www.postgresql.org/message-id/CAAAe_zDMjcFgZJoS%3DzQn5VdetZ5qQcoHiZmLriAdrYLGPTsPZg%40mail.gmail.com

--
jian
https://www.enterprisedb.com/

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Michael Paquier 2026-07-07 06:14:29 Re: Don't use the deprecated and insecure PQcancel in our frontend tools anymore
Previous Message Ashutosh Bapat 2026-07-07 05:47:04 Re: Replace pg_atomic_flag with pg_atomic_bool