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 CACJufxH4LrCpL63SRYO3zVk46YdD4--VYQoBL7GmHmCm=NCAJQ@mail.gmail.com
Whole thread
In response to Re: CAST(... ON DEFAULT) - WIP build on top of Error-Safe User Functions  (Corey Huinker <corey.huinker@gmail.com>)
Responses Re: CAST(... ON DEFAULT) - WIP build on top of Error-Safe User Functions
List pgsql-hackers
On Mon, Mar 16, 2026 at 11:48 AM Corey Huinker <corey.huinker@gmail.com> wrote:
>
> LGTM.

Thanks for the review.
For the context of
v20-0022-CAST-expr-AS-newtype-DEFAULT-expr-ON-CONVERSION-ERROR.patch

+/*
+ * Check type coercion is error safe or not.  If not then report error
+ */
+static void
+CoercionErrorSafeCheck(ParseState *pstate, Node *castexpr, Node *source,
+   Oid inputType, Oid targetType)
+{
+ Oid inputBaseType;
+ Oid targetBaseType;
+ Oid inputElementType;
+ Oid inputElementBaseType;
+ Oid targetElementType;
+ Oid targetElementBaseType;
+ inputElementType = get_element_type(inputType);
+
+ if (OidIsValid(inputElementType))
+ inputElementBaseType = getBaseType(inputElementType);
+ else
+ {
+ inputBaseType = getBaseType(inputType);
+ inputElementBaseType = get_element_type(inputBaseType);
+
+ if (!OidIsValid(inputElementBaseType))
+ inputElementBaseType = inputBaseType;
+ }
+
+ targetElementType = get_element_type(targetType);
+
+ if (OidIsValid(targetElementType))
+ targetElementBaseType = getBaseType(targetElementType);
+ else
+ {
+ targetBaseType = getBaseType(targetType);
+ targetElementBaseType = get_element_type(targetBaseType);
+
+ if (!OidIsValid(targetElementBaseType))
+ targetElementBaseType = targetBaseType;
+ }
+
+ if (inputElementBaseType == MONEYOID ||
+ targetElementBaseType == MONEYOID ||
+ (inputElementBaseType == CIRCLEOID &&
+ targetElementBaseType == POLYGONOID))
+ {
+ errorsafe_coercion = false;
+ }
+

Inspired by https://commitfest.postgresql.org/patch/5759/
I found out the above code is wrong, because it failed to imagine
cases like domain over a domain array.
for example:
CREATE DOMAIN d_int42 as int check (value = 42) NOT NULL;
CREATE DOMAIN d_int42arr as d_int42[];
CREATE DOMAIN d_int42arr1 as d_int42arr;
select typname,typtype, typbasetype::regtype, typelem::regtype
from pg_type
where typname in ('d_int42', 'd_int42arr', 'd_int42arr1', '_d_int42');

Therefore we need a little bit of recursive to get the base elements type,
please check new function: CoercionErrorSafe_Internal in v21-0022.

Given the interaction with array and domain coercion, we need to think more
about error-safe type casts for user-defined range, multirange, and composite
types.  For now, we should disallow error-safe casting for these types.



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

Attachment

pgsql-hackers by date:

Previous
From: Michael Paquier
Date:
Subject: Re: Return pg_control from pg_backup_stop().
Next
From: Junwang Zhao
Date:
Subject: Re: SQL Property Graph Queries (SQL/PGQ)