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-10-14T02:00:26Z
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 →
  1. Make cast functions to type money error safe

  2. Make cast function from circle to polygon error safe

  3. Make geometry cast functions error safe

  4. Make cast functions from jsonb error safe

  5. Make many cast functions error safe

  6. Add SQL/JSON query functions

  7. Add soft error handling to some expression nodes

Attachments

On Fri, Oct 10, 2025 at 8:23 PM jian he <jian.universality@gmail.com> wrote:
> After applying the attached v7 patch patchset,
> the below are cast functions that I didn't refactor to error safe yet.
>
> select pc.castsource::regtype,
>        pc.casttarget::regtype, castfunc::regproc, pp.prosrc
> from pg_cast pc join pg_proc pp on pp.oid = pc.castfunc
> join pg_type pt on pt.oid = castsource
> join pg_type pt1 on pt1.oid = casttarget
> and pc.castfunc > 0 and pt.typnamespace = 'pg_catalog'::regnamespace
> and pt1.typnamespace = 'pg_catalog'::regnamespace and not pc.casterrorsafe;
>
>  castsource | casttarget |       castfunc       |    prosrc
> ------------+------------+----------------------+--------------
>  bigint     | money      | pg_catalog.money     | int8_cash
>  integer    | money      | pg_catalog.money     | int4_cash
>  numeric    | money      | pg_catalog.money     | numeric_cash
>  money      | numeric    | pg_catalog."numeric" | cash_numeric
> (4 rows)
>
> The reason I don't refactor these cast functions related to money data
> type  is because
> 1. I am not sure if the PGLC_localeconv() function is error safe or not.
> 2. refactoring such ``DirectFunctionCall1(numeric_int8, amount));``
> requires more effort.
>
> please check the attached v7 patch set:
> 01-error-safe-for-casting-bytea-to-other-types
> 02-error-safe-for-casting-bit-varbit-to-other-types
> 03-error-safe-for-casting-character-to-other-types
> 04-error-safe-for-casting-text-to-other-types
> 05-error-safe-for-casting-character-varying-to-other-types
> 06-error-safe-for-casting-inet-to-other-types
> 07-error-safe-for-casting-macaddr8-to-other-types
> 08-error-safe-for-casting-integer-to-other-types
> 09-error-safe-for-casting-bigint-to-other-types
> 10-error-safe-for-casting-numeric-to-other-types
> 11-error-safe-for-casting-float4-to-other-types
> 12-error-safe-for-casting-float8-to-other-types
> 13-error-safe-for-casting-date-to-other-types
> 14-error-safe-for-casting-interval-to-other-types
> 15-error-safe-for-casting-timestamptz-to-other-types
> 16-error-safe-for-casting-timestamp-to-other-types
> 17-error-safe-for-casting-jsonb-to-other-types
> 18-error-safe-for-casting-geometry-data-types
> 19-invent_some_error_safe_function.patch
> 20-CAST-expr-AS-newtype-DEFAULT-ON-ERROR.patch
>
> Each patch includes a commit message explaining which function is being
> refactored to be error-safe.
>

Summary of what this patch set is doing:
To implement the syntax:
CAST(source_expr AS target_type DEFAULT def_expr ON CONVERSION ERROR)

we need to ensure that the transformed cast expression is error-safe.
A transformed cast expression can be either a CoerceViaIO or a FuncExpr.
Since CoerceViaIO is already error-safe but FuncExpr cannot be
rewritten as CoerceViaIO
one of the example: SELECT ('11.1'::numeric::int)

So we need to refactor how pg_cast.castfunc works to make it error-safe.
We also need to query pg_cast to determine whether a given pg_cast.castfunc is
error-safe.  For this, a new field casterrorsafe is added to pg_cast.

Patches 01–18: Refactor all pg_cast.castfunc entries (except those with the
money data type) to be error-safe.
Patches 19–20: Implement support for CAST(... AS ... DEFAULT def_expr ON
CONVERSION ERROR)

Please check the attached v8.

It includes minor changes compared to v7:
mainly a small mistake fix in src/backend/jit/llvm/llvmjit_expr.c.
Additionally, one occurrence of NO_XML_SUPPORT(); was replaced with
errsave(escontext, …).