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-11-11T03:06:11Z
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
- v10-0016-error-safe-for-casting-timestamp-to-other-types-per-pg_cast.patch (text/x-patch) patch v10-0016
- v10-0018-error-safe-for-casting-geometry-data-type.patch (text/x-patch) patch v10-0018
- v10-0019-invent-some-error-safe-functions.patch (text/x-patch) patch v10-0019
- v10-0017-error-safe-for-casting-jsonb-to-other-types-per-pg_cast.patch (text/x-patch) patch v10-0017
- v10-0020-CAST-expr-AS-newtype-DEFAULT-ON-ERROR.patch (text/x-patch) patch v10-0020
- v10-0015-error-safe-for-casting-timestamptz-to-other-types-per-pg_cast.patch (text/x-patch) patch v10-0015
- v10-0014-error-safe-for-casting-interval-to-other-types-per-pg_cast.patch (text/x-patch) patch v10-0014
- v10-0012-error-safe-for-casting-float8-to-other-types-per-pg_cast.patch (text/x-patch) patch v10-0012
- v10-0013-error-safe-for-casting-date-to-other-types-per-pg_cast.patch (text/x-patch) patch v10-0013
- v10-0011-error-safe-for-casting-float4-to-other-types-per-pg_cast.patch (text/x-patch) patch v10-0011
- v10-0009-error-safe-for-casting-bigint-to-other-types-per-pg_cast.patch (text/x-patch) patch v10-0009
- v10-0007-error-safe-for-casting-macaddr8-to-other-types-per-pg_cast.patch (text/x-patch) patch v10-0007
- v10-0006-error-safe-for-casting-inet-to-other-types-per-pg_cast.patch (text/x-patch) patch v10-0006
- v10-0010-error-safe-for-casting-numeric-to-other-types-per-pg_cast.patch (text/x-patch) patch v10-0010
- v10-0008-error-safe-for-casting-integer-to-other-types-per-pg_cast.patch (text/x-patch) patch v10-0008
- v10-0004-error-safe-for-casting-text-to-other-types-per-pg_cast.patch (text/x-patch) patch v10-0004
- v10-0005-error-safe-for-casting-character-varying-to-other-types-per-pg_c.patch (text/x-patch) patch v10-0005
- v10-0002-error-safe-for-casting-bit-varbit-to-other-types-per-pg_cast.patch (text/x-patch) patch v10-0002
- v10-0003-error-safe-for-casting-character-to-other-types-per-pg_cast.patch (text/x-patch) patch v10-0003
- v10-0001-error-safe-for-casting-bytea-to-other-types-per-pg_cast.patch (text/x-patch) patch v10-0001
On Thu, Nov 6, 2025 at 6:00 AM Corey Huinker <corey.huinker@gmail.com> wrote:
>
> Issue 5:
>
> I think 0019 is a bit big for a committer to digest all in one sitting. Currently it:
>
> - introduces the type-safe cast node
> - introduces the cast on default syntax
> - redefines
> - adds in test cases for all safe functions defined in patches 1-18.
>
> As tedious as it might be, I think we want to move this patch to the front, move all pg_cast.dat changes to their respective patches that introduce that datatype's safe typecast function, as well as the test cases that are made possible by that new safe typecast. That will make it easier to ensure that each new cast has test coverage.
>
> Yes, that's going to be a lot of catversion bumps, requiring somebody to fudge the dates as we presently only allow for 10 catversion bumps in a day, but the committer will either combine a few of the patches or spread the work out over a few days.
>
Currently, patches v9-0001 through v9-0018 focus solely on refactoring
pg_cast.castfunc. This refactoring is already valuable on its own because it
establishes the infrastructure needed for error safe type casts.
As mentioned before, to make
CAST(source_expr AS target_type DEFAULT expr ON CONVERSION ERROR);
work,
we cannot just simply replace casting FuncExpr nodes with CoerceViaIO, since
type modifiers behave differently in these two Nodes.
(e.g., casting numeric 1.11 to integer is not equivalent to casting the literal
"1.11" to integer).
Also, are we settled on this new pg_cast column name (pg_cast.casterrorsafe)?
Overall, I think it's better not to touch pg_cast.dat in each of these
refactoring patches.
Without first refactoring pg_cast.castfunc (01 to 18), making CAST ...
DEFAULT as the first patch (0001)
won't work, since pg_cast.castfunc itself is not error safe yet, and we
have no way to test the CAST DEFAULT syntax.
So we have to *first* refactor pg_cast.castfunc, make it error safe
then implement CAST DEFAULT.
--------------------------------------------------
The CAST DEFAULT patch is large, I tried to split some newly created function
into a seperate patch.
see v10-0019-invent-some-error-safe-functions.patch.
SELECT CAST('five' AS INTEGER DEFAULT 6 ON CONVERSION ERROR);
is not hard to make it error safe. ('five' is a simple Cons node)
However, I found out, to make
SELECT CAST('five'::INTEGER AS INTEGER DEFAULT 6 ON CONVERSION ERROR);
error safe is hard.
('five'::INTEGER) is a TypeCast node, normally it will error out in
transformTypeCast->
coerce_to_target_type->coerce_type ```(if (inputTypeId == UNKNOWNOID
&& IsA(node, Const)))```
If we do not error out, then we need a Node to represent the failed cast, mainly
for deparse purposes.
that means for CAST(source_expr .... DEFAULT defexpr ON CONVERSION ERROR);
The only corner case we handle is when source_expr is a simple Const node.
In all other cases, source_expr is processed through transformExpr,
which does all
the normal parse analysis for a node.
--
jian
https://www.enterprisedb.com/