Re: CAST(... ON DEFAULT) - WIP build on top of Error-Safe User Functions
jian he <jian.universality@gmail.com>
From: jian he <jian.universality@gmail.com>
To: Corey Huinker <corey.huinker@gmail.com>
Cc: Vik Fearing <vik@postgresfriends.org>,
Isaac Morland <isaac.morland@gmail.com>, pgsql-hackers@lists.postgresql.org
Date: 2025-08-01T05:55:44Z
Lists: pgsql-hackers
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Make cast functions to type money error safe
- b36b95640487 19 (unreleased) landed
-
Make cast function from circle to polygon error safe
- 26f9012beecf 19 (unreleased) landed
-
Make geometry cast functions error safe
- 45cdaf3665be 19 (unreleased) landed
-
Make cast functions from jsonb error safe
- 10e4d8aaf46f 19 (unreleased) landed
-
Make many cast functions error safe
- e2f289e5b9b8 19 (unreleased) landed
-
Add SQL/JSON query functions
- 6185c9737cf4 17.0 cited
-
Add soft error handling to some expression nodes
- aaaf9449ec6b 17.0 cited
Attachments
- v3-0002-make-ArrayCoerceExpr-error-safe.patch (text/x-patch) patch v3-0002
- v3-0001-make-some-numeric-cast-function-error-safe.patch (text/x-patch) patch v3-0001
- v3-0003-CAST-expr-AS-newtype-DEFAULT-ON-ERROR.patch (text/x-patch) patch v3-0003
On Thu, Jul 31, 2025 at 3:15 AM Corey Huinker <corey.huinker@gmail.com> wrote:
>
>
> Question about this:
>
> +/*
> + * Push steps to evaluate a SafeTypeCastExpr and its various subsidiary expressions.
> + * We already handle CoerceViaIO, CoerceToDomain, and ArrayCoerceExpr error
> + * softly. However, FuncExpr (e.g., int84) cannot be made error-safe.
> + * In such cases, we wrap the source expression and target type information into
> + * a CoerceViaIO node instead.
> + */
>
> I'm not sure we _can_ just fall back to the CoerceViaIO if there is a defined cast from TypeA -> TypeB. I seem to recall there was some reason we couldn't do that, possibly to do with how it handled rounding, but I have no clear memory of it.
>
indeed.
select ('11.1'::numeric::int);
return 11, but '11.1' string can not coerce to int 11. So in this
case, we can not use CoerceViaIO.
so we need to handle numeric source types with fractional points with
special care.
currently, this applies only to numeric, float4, and float8.
(hope this is all the corner case we need to catch...)
select castsource::regtype, casttarget::regtype, castfunc::regproc, castcontext
from pg_cast pc
where castsource::regtype = ANY('{numeric, float4, float8}'::regtype[])
and castmethod = 'f';
only return 17 rows. one row is cast numreic to money, function numeric_cash.
numeric_cash seems more trickly to be error safe, because it will call
numeric_mul.
so I made these 16 function errors safe.
see v3-0001-make-some-numeric-cast-function-error-safe.patch