v6-0002-error-safe-for-casting-character-to-other-types-per-pg_ca.patch
text/x-patch
Filename: v6-0002-error-safe-for-casting-character-to-other-types-per-pg_ca.patch
Type: text/x-patch
Part: 17
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v6-0002
Subject: error safe for casting character to other types per pg_cast
| File | + | − |
|---|---|---|
| src/backend/executor/execExprInterp.c | 1 | 1 |
| src/backend/utils/adt/varchar.c | 1 | 1 |
| src/backend/utils/adt/xml.c | 8 | 4 |
| src/include/utils/xml.h | 1 | 1 |
From 4d0fc95b1fc9690b7a631b98d3d0f392a2a293bd Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Sat, 9 Aug 2025 17:49:04 +0800
Subject: [PATCH v6 02/18] error safe for casting character to other types per
pg_cast
select castsource::regtype, casttarget::regtype, castfunc,
castcontext,castmethod, pp.prosrc, pp.proname from pg_cast pc join pg_proc pp on
pp.oid = pc.castfunc and pc.castfunc > 0
and castsource::regtype ='character'::regtype
order by castsource::regtype;
castsource | casttarget | castfunc | castcontext | castmethod | prosrc | proname
------------+-------------------+----------+-------------+------------+-------------+---------
character | text | 401 | i | f | rtrim1 | text
character | character varying | 401 | i | f | rtrim1 | text
character | "char" | 944 | a | f | text_char | char
character | name | 409 | i | f | bpchar_name | name
character | xml | 2896 | e | f | texttoxml | xml
character | character | 668 | i | f | bpchar | bpchar
(6 rows)
only texttoxml, bpchar(PG_FUNCTION_ARGS) need take care of error handling.
other already error safe.
---
src/backend/executor/execExprInterp.c | 2 +-
src/backend/utils/adt/varchar.c | 2 +-
src/backend/utils/adt/xml.c | 12 ++++++++----
src/include/utils/xml.h | 2 +-
4 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 0e1a74976f7..67f4e00eac4 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -4542,7 +4542,7 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
*op->resvalue = PointerGetDatum(xmlparse(data,
xexpr->xmloption,
- preserve_whitespace));
+ preserve_whitespace, NULL));
*op->resnull = false;
}
break;
diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index 3f40c9da1a0..5cb5c8c46f9 100644
--- a/src/backend/utils/adt/varchar.c
+++ b/src/backend/utils/adt/varchar.c
@@ -307,7 +307,7 @@ bpchar(PG_FUNCTION_ARGS)
{
for (i = maxmblen; i < len; i++)
if (s[i] != ' ')
- ereport(ERROR,
+ ereturn(fcinfo->context, (Datum) 0,
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
errmsg("value too long for type character(%d)",
maxlen)));
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index 182e8f75db7..1d423e0f9a3 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -660,7 +660,7 @@ texttoxml(PG_FUNCTION_ARGS)
{
text *data = PG_GETARG_TEXT_PP(0);
- PG_RETURN_XML_P(xmlparse(data, xmloption, true));
+ PG_RETURN_XML_P(xmlparse(data, xmloption, true, fcinfo->context));
}
@@ -1029,14 +1029,18 @@ xmlelement(XmlExpr *xexpr,
xmltype *
-xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace)
+xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace, Node *escontext)
{
#ifdef USE_LIBXML
xmlDocPtr doc;
doc = xml_parse(data, xmloption_arg, preserve_whitespace,
- GetDatabaseEncoding(), NULL, NULL, NULL);
- xmlFreeDoc(doc);
+ GetDatabaseEncoding(), NULL, NULL, escontext);
+ if (doc)
+ xmlFreeDoc(doc);
+
+ if (SOFT_ERROR_OCCURRED(escontext))
+ return NULL;
return (xmltype *) data;
#else
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index 0d7a816b9f9..b3d3f11fac4 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -73,7 +73,7 @@ extern xmltype *xmlconcat(List *args);
extern xmltype *xmlelement(XmlExpr *xexpr,
Datum *named_argvalue, bool *named_argnull,
Datum *argvalue, bool *argnull);
-extern xmltype *xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace);
+extern xmltype *xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace, Node *escontext);
extern xmltype *xmlpi(const char *target, text *arg, bool arg_is_null, bool *result_is_null);
extern xmltype *xmlroot(xmltype *data, text *version, int standalone);
extern bool xml_is_document(xmltype *arg);
--
2.34.1