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-12-10T08:57:09Z
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 Tue, Dec 9, 2025 at 11:39 AM jian he <jian.universality@gmail.com> wrote:
>
> On Mon, Dec 1, 2025 at 1:41 PM Corey Huinker <corey.huinker@gmail.com> wrote:
> >>
> > No, I meant implementing the syntax for being able to declare a custom CAST function as safe (or not). Basically adding the [SAFE] to
> >
> > CREATE CAST (source_type AS target_type)
> >     WITH [SAFE] FUNCTION function_name [ (argument_type [, ...]) ]
> >
> > I'm not tied to this syntax choice, but this one seemed the most obvious and least invasive.
> >

hi.
please see the attached v15.
the primary implementation of CAST DEFAULT is contained in V15-0021.

changes compared to v14.
1. separate patch (v15-0017) for float error.
-pg_noreturn extern void float_overflow_error(void);
-pg_noreturn extern void float_underflow_error(void);
-pg_noreturn extern void float_zero_divide_error(void);
+extern void float_overflow_error(struct Node *escontext);
+extern void float_underflow_error(struct Node *escontext);
+extern void float_zero_divide_error(struct Node *escontext);

2. separate patch (v15-0018) for newly added float8 functions:
float8_pl_safe
float8_mi_safe
float8_mul_safe
float8_div_safe
refactoring existing functions is too invasive, I choose not to.

3. refactor point_dt (v15-0019). This is necessary for making geometry data type
error-safe, separate from the main patch (v15-0020). I hope to make it easier to
review.
-static inline float8 point_dt(Point *pt1, Point *pt2);
+static inline float8 point_dt(Point *pt1, Point *pt2, Node *escontext);

4. skip compile DEFAULT expression (ExecInitExprRec) for binary coercion cast,
as mentioned before.  See ExecInitSafeTypeCastExpr.

5.  Support user-defined type cast error-safe, see v15-0022.
user-defined error-safe cast syntax:
CREATE CAST (source_type AS target_type)
    WITH [SAFE] FUNCTION function_name [ (argument_type [, ...]) ]
    [ AS ASSIGNMENT | AS IMPLICIT ]

this only adds a new keyword SAFE.
This works for C and internal language functions only now.
To make it really usable, I have made citext, hstore module castfunc error safe.
A new column: pg_cast.casterrorsafe was added, this is needed for
CREATE CAST WITH SAFE FUNCTION.

+select CAST(ARRAY['a','g','b','h',null,'i'] AS hstore
+       DEFAULT NULL ON CONVERSION ERROR);
+ array
+-------
+
+(1 row)
+

6. slightly polished the doc.


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