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

From jian he
Subject Re: CAST(... ON DEFAULT) - WIP build on top of Error-Safe User Functions
Date
Msg-id CACJufxHGox47X4zNtVeNw7H=SZ7ATAAD5SEYpvxa2o5mPV0XCA@mail.gmail.com
Whole thread
In response to Re: CAST(... ON DEFAULT) - WIP build on top of Error-Safe User Functions  (jian he <jian.universality@gmail.com>)
Responses Re: CAST(... ON DEFAULT) - WIP build on top of Error-Safe User Functions
List pgsql-hackers
On Thu, Mar 26, 2026 at 4:59 PM jian he <jian.universality@gmail.com> wrote:
>
> Currently, when a valid ErrorSaveContext is passed to state->escontext
> (ExprState->escontext),
> ExecInitExprRec is designed to compile the entire expression tree
> using soft errors.
> Consider the following example:
>     create table t1(a text, b text, c int, d int8);
>     create domain d2 as text check (value <> 'a');
>     insert into t1(a, d) values('a', 2147483648);
>     select cast (cast(d as int) as text default null on conversion
> error) from t1;  -- queryA
>     select cast (cast(a as d2) as text default null on conversion
> error) from t1;   -- queryB
>     select cast (cast(a as int) as text default null on conversion
> error) from t1;  -- queryC
>

In ATExecAddColumn, we have:

exprState = ExecPrepareExprWithContext(defval, estate, (Node *) &escontext);

The entire defval expression tree (including all the potential FuncExpr node
subexpression) must be marked as error-safe (all the
FuncExpr->errorsafe must be set to true).
If they aren't, ExecPrepareExprWithContext won't work.
In that scarenio, we need a walker function to set FuncExpr->errorsafe
to true for the above defval, overall feels very ugly.

Therefore, the previous approach (v24) of simply adding an errorsafe boolean to
FuncExpr will not work.
IMHO, it is not feasible to mark only part of an expression tree as error-safe.
Because of this, we should try to make queryA, queryB, queryC return NULL.

However, some inconsistency remains, for example:
SELECT CAST (CAST('a' AS int) AS text DEFAULT NULL ON CONVERSION
ERROR) FROM tcast1;  -- error
SELECT CAST (CAST('a'::text AS int) AS text DEFAULT NULL ON CONVERSION
ERROR) FROM tcast1; -- ok

V24: There is a segfault because of eval_const_expressions_mutator,
T_ArrayCoerceExpr handling,
You can invoke it via:
select cast (cast('{a}'::text[] as int[]) as text[] default null on
conversion error) from t2;

In V24, there were no nested type cast regress tests, now I have added some.

I removed the errorsafe boolean from FuncExpr. As mentioned previously, it is
difficult to make ExecInitExprRec compile expression partically eror safe.

refactoring on transformArrayExpr,  transformTypeCast, ExecInitSafeTypeCastExpr.



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

Attachment

pgsql-hackers by date:

Previous
From: Peter Geoghegan
Date:
Subject: Re: index prefetching
Next
From: Michael Paquier
Date:
Subject: Re: Refactor query normalization into core query jumbling