public inbox for [email protected]
help / color / mirror / Atom feedFrom: Chao Li <[email protected]>
To: Postgres hackers <[email protected]>
Cc: Álvaro Herrera <[email protected]>
Cc: David Rowley <[email protected]>
Subject: Re: quoteOneName() inconsistency with quote_all_identifiers — replacement API proposed
Date: Mon, 13 Apr 2026 10:53:26 +0800
Message-ID: <[email protected]> (raw)
In-Reply-To: <CAEoWx2m0v=n2CgonU3Tz1GOj1=dFWu9YcBPc6v-pJi2LYxG9Zw@mail.gmail.com>
References: <CAEoWx2=vRfws6C2svUWdmNA10no+g71HABDqqKdbL43adC-VuQ@mail.gmail.com>
<[email protected]>
<CAEoWx2nPbikvjp0JBsHzbpE=u7aMkiVy-WCmPim2iX5hDF9fBw@mail.gmail.com>
<CAEoWx2m0v=n2CgonU3Tz1GOj1=dFWu9YcBPc6v-pJi2LYxG9Zw@mail.gmail.com>
> On Nov 21, 2025, at 18:03, Chao Li <[email protected]> wrote:
>
> Fixed a compile warning in v4.
>
> Best regards,
> Chao Li (Evan)
> ---------------------
> HighGo Software Co., Ltd.
> https://www.highgo.com/
>
>
> On Fri, Nov 21, 2025 at 1:52 PM Chao Li <[email protected]> wrote:
>
> On Thu, Nov 20, 2025 at 8:28 PM Álvaro Herrera <[email protected]> wrote:
> Hi,
>
> > - appendStringInfo(&buffer, _("text search configuration %s"),
> > - quote_qualified_identifier(nspname,
> > - NameStr(cfgForm->cfgname)));
> > + appendStringInfoQualifiedIdentifier(&buffer,
> > + _("text search configuration "),
> > + nspname, NameStr(cfgForm->cfgname), NULL);
> > ReleaseSysCache(tup);
> > break;
> > }
>
> This doesn't work from a i18n point of view. In the original
> formulation, the translator is free to place the %s wherever it suits
> the language. In the new one there's no such freedom: the name will be
> appended at the end. Some existing translations:
>
> ko.po:msgid "text search configuration %s"
> ko.po-msgstr "%s 전문 검색 구성"
>
> tr.po:msgid "text search configuration %s"
> tr.po-msgstr "%s metin arama yapılandırması"
>
> Thanks for the feedback. I reverted that piece of change in v3.
>
> Best regards,
> Chao Li (Evan)
> ---------------------
> HighGo Software Co., Ltd.
> https://www.highgo.com/
Rebased.
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/
Attachments:
[application/octet-stream] v5-0001-Add-appendStringInfoIdentifier-to-avoid-intermedi.patch (11.6K, 2-v5-0001-Add-appendStringInfoIdentifier-to-avoid-intermedi.patch)
download | inline diff:
From 595526adbdc845c0f1701753a99af8335e1c7495 Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <[email protected]>
Date: Fri, 14 Nov 2025 21:44:29 +0800
Subject: [PATCH v5 1/4] Add appendStringInfoIdentifier() to avoid intermediate
quoting buffers
Introduce appendStringInfoIdentifier() and
appendStringInfoQualifiedIdentifier(), helper functions that append an SQL
identifier directly to a StringInfo while applying quoting rules when
necessary. This avoids allocating and copying through temporary palloc
buffers, as currently happens with quote_identifier() when used together
with appendStringInfoString().
The new functions improve both readability and efficiency of call sites that
construct SQL fragments, especially those that need to build qualified
names such as schema.table.
Convert several existing callers in objectaddress.c, explain.c and
ruleutils.c to use appendStringInfoIdentifier() /
appendStringInfoQualifiedIdentifier() as examples.
No functional behavior change is intended.
Author: Chao Li <[email protected]>
Discussion: https://postgr.es/m/CAEoWx2=g2RVkxXB=JzWphgfg4QGV+spaA3PQ1rBM2iMehrVvjg@mail.gmail.com
---
src/backend/catalog/objectaddress.c | 14 +--
src/backend/commands/explain.c | 3 +-
src/backend/utils/adt/ri_triggers.c | 8 +-
src/backend/utils/adt/ruleutils.c | 150 +++++++++++++++++++++++-----
src/include/utils/builtins.h | 6 ++
5 files changed, 137 insertions(+), 44 deletions(-)
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 9771c6a9b63..88556339dd9 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -5150,8 +5150,7 @@ getObjectIdentityParts(const ObjectAddress *object,
if (attr)
{
- appendStringInfo(&buffer, ".%s",
- quote_identifier(attr));
+ appendStringInfoIdentifier(&buffer, ".", attr, NULL);
if (objname)
*objname = lappend(*objname, attr);
}
@@ -5662,8 +5661,7 @@ getObjectIdentityParts(const ObjectAddress *object,
object->objectId);
break;
}
- appendStringInfoString(&buffer,
- quote_identifier(nspname));
+ appendStringInfoIdentifier(&buffer, NULL, nspname, NULL);
if (objname)
*objname = list_make1(nspname);
break;
@@ -6006,16 +6004,12 @@ getObjectIdentityParts(const ObjectAddress *object,
defacl = (Form_pg_default_acl) GETSTRUCT(tup);
username = GetUserNameFromId(defacl->defaclrole, false);
- appendStringInfo(&buffer,
- "for role %s",
- quote_identifier(username));
+ appendStringInfoIdentifier(&buffer, "for role ", username, NULL);
if (OidIsValid(defacl->defaclnamespace))
{
schema = get_namespace_name_or_temp(defacl->defaclnamespace);
- appendStringInfo(&buffer,
- " in schema %s",
- quote_identifier(schema));
+ appendStringInfoIdentifier(&buffer, " in schema ", schema, NULL);
}
else
schema = NULL;
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 112c17b0d64..67ee6696e0a 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -1712,8 +1712,7 @@ ExplainNode(PlanState *planstate, List *ancestors,
explain_get_index_name(bitmapindexscan->indexid);
if (es->format == EXPLAIN_FORMAT_TEXT)
- appendStringInfo(es->str, " on %s",
- quote_identifier(indexname));
+ appendStringInfoIdentifier(es->str, " on ", indexname, NULL);
else
ExplainPropertyText("Index Name", indexname, es);
}
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index e060280fcd4..dc8f40eff12 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -528,7 +528,6 @@ RI_FKey_check(TriggerData *trigdata)
{
quoteOneName(attname,
RIAttName(pk_rel, riinfo->pk_attnums[riinfo->nkeys - 1]));
-
appendStringInfo(&querybuf,
"SELECT 1 FROM (SELECT %s AS r FROM %s%s x",
attname, pk_only, pkrelname);
@@ -2228,7 +2227,6 @@ ri_GenerateQualCollation(StringInfo buf, Oid collation)
HeapTuple tp;
Form_pg_collation colltup;
char *collname;
- char onename[MAX_QUOTED_NAME_LEN];
/* Nothing to do if it's a noncollatable data type */
if (!OidIsValid(collation))
@@ -2244,10 +2242,8 @@ ri_GenerateQualCollation(StringInfo buf, Oid collation)
* We qualify the name always, for simplicity and to ensure the query is
* not search-path-dependent.
*/
- quoteOneName(onename, get_namespace_name(colltup->collnamespace));
- appendStringInfo(buf, " COLLATE %s", onename);
- quoteOneName(onename, collname);
- appendStringInfo(buf, ".%s", onename);
+ appendStringInfoIdentifier(buf, " COLLATE ", get_namespace_name(colltup->collnamespace), NULL);
+ appendStringInfoIdentifier(buf, ".", collname, NULL);
ReleaseSysCache(tp);
}
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 090e8cc28c1..af4a56f7bd7 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -10683,8 +10683,8 @@ get_rule_expr(Node *node, deparse_context *context,
}
if (xexpr->name)
{
- appendStringInfo(buf, "NAME %s",
- quote_identifier(map_xml_name_to_sql_identifier(xexpr->name)));
+ appendStringInfoIdentifier(buf, "NAME ",
+ map_xml_name_to_sql_identifier(xexpr->name), NULL);
needcomma = true;
}
if (xexpr->named_args)
@@ -10704,8 +10704,8 @@ get_rule_expr(Node *node, deparse_context *context,
if (needcomma)
appendStringInfoString(buf, ", ");
get_rule_expr(e, context, true);
- appendStringInfo(buf, " AS %s",
- quote_identifier(map_xml_name_to_sql_identifier(argname)));
+ appendStringInfoIdentifier(buf, " AS ",
+ map_xml_name_to_sql_identifier(argname), NULL);
needcomma = true;
}
if (xexpr->op != IS_XMLFOREST)
@@ -13672,25 +13672,17 @@ printSubscripts(SubscriptingRef *sbsref, deparse_context *context)
}
}
-/*
- * quote_identifier - Quote an identifier only if needed
- *
- * When quotes are needed, we palloc the required space; slightly
- * space-wasteful but well worth it for notational simplicity.
- */
-const char *
-quote_identifier(const char *ident)
+static inline bool
+is_identifier_safe(const char *ident, int *nquotes)
{
/*
* Can avoid quoting if ident starts with a lowercase letter or underscore
* and contains only lowercase letters, digits, and underscores, *and* is
* not any SQL keyword. Otherwise, supply quotes.
*/
- int nquotes = 0;
bool safe;
- const char *ptr;
- char *result;
- char *optr;
+
+ *nquotes = 0;
/*
* would like to use <ctype.h> macros here, but they might yield unwanted
@@ -13698,7 +13690,7 @@ quote_identifier(const char *ident)
*/
safe = ((ident[0] >= 'a' && ident[0] <= 'z') || ident[0] == '_');
- for (ptr = ident; *ptr; ptr++)
+ for (const char *ptr = ident; *ptr; ptr++)
{
char ch = *ptr;
@@ -13712,7 +13704,7 @@ quote_identifier(const char *ident)
{
safe = false;
if (ch == '"')
- nquotes++;
+ (*nquotes)++;
}
}
@@ -13735,14 +13727,20 @@ quote_identifier(const char *ident)
safe = false;
}
- if (safe)
- return ident; /* no change needed */
+ return safe;
+}
+
+static inline const char *
+quote_identifier_internal(const char *ident, int nquotes, char **result)
+{
+ char *optr;
- result = (char *) palloc(strlen(ident) + nquotes + 2 + 1);
+ if (*result == NULL)
+ *result = (char *) palloc(strlen(ident) + nquotes + 2 + 1);
- optr = result;
+ optr = *result;
*optr++ = '"';
- for (ptr = ident; *ptr; ptr++)
+ for (const char *ptr = ident; *ptr; ptr++)
{
char ch = *ptr;
@@ -13753,7 +13751,107 @@ quote_identifier(const char *ident)
*optr++ = '"';
*optr = '\0';
- return result;
+ return *result;
+}
+
+/*
+ * quote_identifier - Quote an identifier only if needed
+ *
+ * When quotes are needed, we palloc the required space; slightly
+ * space-wasteful but well worth it for notational simplicity.
+ */
+const char *
+quote_identifier(const char *ident)
+{
+ int nquotes;
+ bool safe;
+ char *result = NULL;
+
+ safe = is_identifier_safe(ident, &nquotes);
+ if (safe)
+ return ident; /* no change needed */
+
+ return quote_identifier_internal(ident, nquotes, &result);
+}
+
+/*
+ * appendStringInfoIdentifier
+ * Append an SQL identifier to a StringInfo, quoting if required.
+ *
+ * This behaves like writing prefix + quote_identifier(ident) + suffix into
+ * the StringInfo, but emits the identifier directly into the buffer to avoid
+ * an intermediate palloc. prefix and suffix may be NULL.
+ *
+ * The identifier is copied verbatim if it is safe to leave unquoted; otherwise
+ * it is written with double quotes and embedded double quotes are doubled.
+ * Quoting rules are local to ruleutils, so this helper is defined here rather
+ * than in stringinfo.c.
+ */
+
+void
+appendStringInfoIdentifier(StringInfo str, const char *prefix,
+ const char *ident, const char *suffix)
+{
+ int nquotes;
+ bool safe;
+ int ident_len;
+ int prefix_len = 0;
+ int suffix_len = 0;
+
+ safe = is_identifier_safe(ident, &nquotes);
+ if (safe)
+ ident_len = strlen(ident);
+ else
+ ident_len = strlen(ident) + nquotes + 2; /* quotes + possible
+ * escapes */
+
+ if (prefix != NULL)
+ prefix_len = strlen(prefix);
+
+ if (suffix != NULL)
+ suffix_len = strlen(suffix);
+
+ enlargeStringInfo(str, ident_len + prefix_len + suffix_len);
+
+ if (prefix != NULL)
+ appendBinaryStringInfo(str, prefix, prefix_len);
+
+ if (safe)
+ appendBinaryStringInfo(str, ident, ident_len);
+ else
+ {
+ char *result = str->data + str->len;
+
+ (void) quote_identifier_internal(ident, nquotes, &result);
+ str->len += ident_len;
+ str->data[str->len] = '\0';
+ }
+
+ if (suffix != NULL)
+ appendBinaryStringInfo(str, suffix, suffix_len);
+}
+
+/*
+ * appendStringInfoQualifiedIdentifier
+ * Append a (possibly) qualified SQL identifier to a StringInfo.
+ *
+ * Writes prefix + qualifier + '.' + ident + suffix, quoting each identifier
+ * component if needed. If no qualifier is given, only ident (plus optional
+ * prefix/suffix) is appended. prefix and suffix may be NULL.
+ *
+ * This is a convenience wrapper around appendStringInfoIdentifier().
+ */
+void
+appendStringInfoQualifiedIdentifier(StringInfo str, const char *prefix,
+ const char *qualifier, const char *ident,
+ const char *suffix)
+{
+ if (qualifier)
+ {
+ appendStringInfoIdentifier(str, prefix, qualifier, ".");
+ prefix = NULL;
+ }
+ appendStringInfoIdentifier(str, prefix, ident, suffix);
}
/*
@@ -13770,8 +13868,8 @@ quote_qualified_identifier(const char *qualifier,
initStringInfo(&buf);
if (qualifier)
- appendStringInfo(&buf, "%s.", quote_identifier(qualifier));
- appendStringInfoString(&buf, quote_identifier(ident));
+ appendStringInfoIdentifier(&buf, NULL, qualifier, ".");
+ appendStringInfoIdentifier(&buf, NULL, ident, NULL);
return buf.data;
}
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index b6a11bfa288..7dbbb4c7c7f 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -85,6 +85,12 @@ extern void generate_operator_clause(StringInfo buf,
const char *leftop, Oid leftoptype,
Oid opoid,
const char *rightop, Oid rightoptype);
+extern void appendStringInfoIdentifier(StringInfo str, const char *prefix, const char *ident, const char *suffix);
+extern void appendStringInfoQualifiedIdentifier(StringInfo str,
+ const char *prefix,
+ const char *qualifier,
+ const char *ident,
+ const char *suffix);
/* varchar.c */
extern int bpchartruelen(char *s, int len);
--
2.50.1 (Apple Git-155)
[application/octet-stream] v5-0002-Use-appendStringInfoIdentifier-throughout-ri_trig.patch (21.9K, 3-v5-0002-Use-appendStringInfoIdentifier-throughout-ri_trig.patch)
download | inline diff:
From 10f4505cb302df59e74446104e21bf6ca2e72609 Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <[email protected]>
Date: Mon, 17 Nov 2025 12:09:12 +0800
Subject: [PATCH v5 2/4] Use appendStringInfoIdentifier() throughout
ri_triggers.c
Replace most uses of quoteOneName() and manual stack buffers in
ri_triggers.c with appendStringInfoIdentifier() and related infrastructure.
This simplifies the construction of SQL queries generated by RI triggers and
eliminates the need for MAX_QUOTED_NAME_LEN / stack-allocated intermediate
buffers. It also removes several code paths where identifiers were quoted
manually, making the quoting rules consistent with ruleutils.c and the GUC
quote_all_identifiers.
This commit also adjusts generate_operator_clause() to support prefixed
arguments and identifier quoting directly, reducing the number of places
where callers need to inject string concatenation logic.
No user-visible behavior change is intended; the generated SQL should be
equivalent to the previous version.
Author: Chao Li <[email protected]>
Discussion: https://postgr.es/m/CAEoWx2=g2RVkxXB=JzWphgfg4QGV+spaA3PQ1rBM2iMehrVvjg@mail.gmail.com
---
src/backend/commands/matview.c | 4 +-
src/backend/utils/adt/ri_triggers.c | 188 +++++++++++++---------------
src/backend/utils/adt/ruleutils.c | 31 +++--
src/include/utils/builtins.h | 4 +-
4 files changed, 115 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index f7d8007f796..96aa4553168 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -797,9 +797,9 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner,
NameStr(attr->attname));
generate_operator_clause(&querybuf,
- leftop, attrtype,
+ NULL, leftop, attrtype, false,
op,
- rightop, attrtype);
+ NULL, rightop, attrtype, false);
foundUniqueIndex = true;
}
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index dc8f40eff12..e55fa8c6574 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -274,9 +274,9 @@ static void quoteOneName(char *buffer, const char *name);
static void quoteRelationName(char *buffer, Relation rel);
static void ri_GenerateQual(StringInfo buf,
const char *sep,
- const char *leftop, Oid leftoptype,
+ const char *leftopprefix, const char *leftop, Oid leftoptype, bool quoteleftop,
Oid opoid,
- const char *rightop, Oid rightoptype);
+ const char *rightopprefix, const char *rightop, Oid rightoptype, bool quoterightop);
static void ri_GenerateQualCollation(StringInfo buf, Oid collation);
static int ri_NullCheck(TupleDesc tupDesc, TupleTableSlot *slot,
const RI_ConstraintInfo *riinfo, bool rel_is_pk);
@@ -491,7 +491,7 @@ RI_FKey_check(TriggerData *trigdata)
{
StringInfoData querybuf;
char pkrelname[MAX_QUOTED_REL_NAME_LEN];
- char attname[MAX_QUOTED_NAME_LEN];
+ const char *attname;
char paramname[16];
const char *querysep;
Oid queryoids[RI_MAX_NUMKEYS];
@@ -526,11 +526,11 @@ RI_FKey_check(TriggerData *trigdata)
quoteRelationName(pkrelname, pk_rel);
if (riinfo->hasperiod)
{
- quoteOneName(attname,
- RIAttName(pk_rel, riinfo->pk_attnums[riinfo->nkeys - 1]));
+ attname = RIAttName(pk_rel, riinfo->pk_attnums[riinfo->nkeys - 1]);
+ appendStringInfoIdentifier(&querybuf, "SELECT 1 FROM (SELECT ", attname, " AS r FROM ");
appendStringInfo(&querybuf,
- "SELECT 1 FROM (SELECT %s AS r FROM %s%s x",
- attname, pk_only, pkrelname);
+ "%s%s x",
+ pk_only, pkrelname);
}
else
{
@@ -543,13 +543,12 @@ RI_FKey_check(TriggerData *trigdata)
Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]);
Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]);
- quoteOneName(attname,
- RIAttName(pk_rel, riinfo->pk_attnums[i]));
+ attname = RIAttName(pk_rel, riinfo->pk_attnums[i]);
sprintf(paramname, "$%d", i + 1);
ri_GenerateQual(&querybuf, querysep,
- attname, pk_type,
+ NULL, attname, pk_type, true,
riinfo->pf_eq_oprs[i],
- paramname, fk_type);
+ NULL, paramname, fk_type, false);
querysep = "AND";
queryoids[i] = fk_type;
}
@@ -561,9 +560,9 @@ RI_FKey_check(TriggerData *trigdata)
appendStringInfoString(&querybuf, ") x1 HAVING ");
sprintf(paramname, "$%d", riinfo->nkeys);
ri_GenerateQual(&querybuf, "",
- paramname, fk_type,
+ NULL, paramname, fk_type, false,
riinfo->agged_period_contained_by_oper,
- "pg_catalog.range_agg", ANYMULTIRANGEOID);
+ NULL, "pg_catalog.range_agg", ANYMULTIRANGEOID, false);
appendStringInfoString(&querybuf, "(x1.r)");
}
@@ -661,7 +660,7 @@ ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel,
{
StringInfoData querybuf;
char pkrelname[MAX_QUOTED_REL_NAME_LEN];
- char attname[MAX_QUOTED_NAME_LEN];
+ const char *attname;
char paramname[16];
const char *querysep;
const char *pk_only;
@@ -696,11 +695,11 @@ ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel,
quoteRelationName(pkrelname, pk_rel);
if (riinfo->hasperiod)
{
- quoteOneName(attname, RIAttName(pk_rel, riinfo->pk_attnums[riinfo->nkeys - 1]));
-
+ attname = RIAttName(pk_rel, riinfo->pk_attnums[riinfo->nkeys - 1]);
+ appendStringInfoIdentifier(&querybuf, "SELECT 1 FROM (SELECT ", attname, " AS r FROM ");
appendStringInfo(&querybuf,
- "SELECT 1 FROM (SELECT %s AS r FROM %s%s x",
- attname, pk_only, pkrelname);
+ "%s%s x",
+ pk_only, pkrelname);
}
else
{
@@ -712,13 +711,12 @@ ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel,
{
Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]);
- quoteOneName(attname,
- RIAttName(pk_rel, riinfo->pk_attnums[i]));
+ attname = RIAttName(pk_rel, riinfo->pk_attnums[i]);
sprintf(paramname, "$%d", i + 1);
ri_GenerateQual(&querybuf, querysep,
- attname, pk_type,
+ NULL, attname, pk_type, true,
riinfo->pp_eq_oprs[i],
- paramname, pk_type);
+ NULL, paramname, pk_type, false);
querysep = "AND";
queryoids[i] = pk_type;
}
@@ -730,9 +728,9 @@ ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel,
appendStringInfoString(&querybuf, ") x1 HAVING ");
sprintf(paramname, "$%d", riinfo->nkeys);
ri_GenerateQual(&querybuf, "",
- paramname, fk_type,
+ NULL, paramname, fk_type, false,
riinfo->agged_period_contained_by_oper,
- "pg_catalog.range_agg", ANYMULTIRANGEOID);
+ NULL, "pg_catalog.range_agg", ANYMULTIRANGEOID, false);
appendStringInfoString(&querybuf, "(x1.r)");
}
@@ -890,7 +888,7 @@ ri_restrict(TriggerData *trigdata, bool is_no_action)
StringInfoData querybuf;
char pkrelname[MAX_QUOTED_REL_NAME_LEN];
char fkrelname[MAX_QUOTED_REL_NAME_LEN];
- char attname[MAX_QUOTED_NAME_LEN];
+ const char *attname;
char periodattname[MAX_QUOTED_NAME_LEN];
char paramname[16];
const char *querysep;
@@ -917,13 +915,12 @@ ri_restrict(TriggerData *trigdata, bool is_no_action)
Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]);
Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]);
- quoteOneName(attname,
- RIAttName(fk_rel, riinfo->fk_attnums[i]));
+ attname = RIAttName(fk_rel, riinfo->fk_attnums[i]);
sprintf(paramname, "$%d", i + 1);
ri_GenerateQual(&querybuf, querysep,
- paramname, pk_type,
+ NULL, paramname, pk_type, false,
riinfo->pf_eq_oprs[i],
- attname, fk_type);
+ NULL, attname, fk_type, true);
querysep = "AND";
queryoids[i] = pk_type;
}
@@ -961,7 +958,7 @@ ri_restrict(TriggerData *trigdata, bool is_no_action)
char *pk_only = pk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
- quoteOneName(attname, RIAttName(fk_rel, riinfo->fk_attnums[riinfo->nkeys - 1]));
+ attname = RIAttName(fk_rel, riinfo->fk_attnums[riinfo->nkeys - 1]);
sprintf(paramname, "$%d", riinfo->nkeys);
appendStringInfoString(&querybuf, " AND NOT coalesce(");
@@ -970,9 +967,9 @@ ri_restrict(TriggerData *trigdata, bool is_no_action)
initStringInfo(&intersectbuf);
appendStringInfoChar(&intersectbuf, '(');
ri_GenerateQual(&intersectbuf, "",
- attname, fk_period_type,
+ NULL, attname, fk_period_type, true,
riinfo->period_intersect_oper,
- paramname, pk_period_type);
+ NULL, paramname, pk_period_type, false);
appendStringInfoChar(&intersectbuf, ')');
/* Find the remaining history */
@@ -990,22 +987,21 @@ ri_restrict(TriggerData *trigdata, bool is_no_action)
{
Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]);
- quoteOneName(attname,
- RIAttName(pk_rel, riinfo->pk_attnums[i]));
+ attname = RIAttName(pk_rel, riinfo->pk_attnums[i]);
sprintf(paramname, "$%d", i + 1);
ri_GenerateQual(&replacementsbuf, querysep,
- paramname, pk_type,
+ NULL, paramname, pk_type, false,
riinfo->pp_eq_oprs[i],
- attname, pk_type);
+ NULL, attname, pk_type, true);
querysep = "AND";
queryoids[i] = pk_type;
}
appendStringInfoString(&replacementsbuf, " FOR KEY SHARE OF y) y2)");
ri_GenerateQual(&querybuf, "",
- intersectbuf.data, fk_period_type,
+ NULL, intersectbuf.data, fk_period_type, false,
riinfo->agged_period_contained_by_oper,
- replacementsbuf.data, ANYMULTIRANGEOID);
+ NULL, replacementsbuf.data, ANYMULTIRANGEOID, false);
/* end of coalesce: */
appendStringInfoString(&querybuf, ", false)");
}
@@ -1077,7 +1073,7 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS)
{
StringInfoData querybuf;
char fkrelname[MAX_QUOTED_REL_NAME_LEN];
- char attname[MAX_QUOTED_NAME_LEN];
+ const char *attname;
char paramname[16];
const char *querysep;
Oid queryoids[RI_MAX_NUMKEYS];
@@ -1102,13 +1098,12 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS)
Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]);
Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]);
- quoteOneName(attname,
- RIAttName(fk_rel, riinfo->fk_attnums[i]));
+ attname = RIAttName(fk_rel, riinfo->fk_attnums[i]);
sprintf(paramname, "$%d", i + 1);
ri_GenerateQual(&querybuf, querysep,
- paramname, pk_type,
+ NULL, paramname, pk_type, false,
riinfo->pf_eq_oprs[i],
- attname, fk_type);
+ NULL, attname, fk_type, true);
querysep = "AND";
queryoids[i] = pk_type;
}
@@ -1183,7 +1178,7 @@ RI_FKey_cascade_upd(PG_FUNCTION_ARGS)
StringInfoData querybuf;
StringInfoData qualbuf;
char fkrelname[MAX_QUOTED_REL_NAME_LEN];
- char attname[MAX_QUOTED_NAME_LEN];
+ const char *attname;
char paramname[16];
const char *querysep;
const char *qualsep;
@@ -1214,16 +1209,15 @@ RI_FKey_cascade_upd(PG_FUNCTION_ARGS)
Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]);
Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]);
- quoteOneName(attname,
- RIAttName(fk_rel, riinfo->fk_attnums[i]));
- appendStringInfo(&querybuf,
- "%s %s = $%d",
- querysep, attname, i + 1);
+ attname = RIAttName(fk_rel, riinfo->fk_attnums[i]);
+ appendStringInfoString(&querybuf, querysep);
+ appendStringInfoIdentifier(&querybuf, " ", attname, " = ");
+ appendStringInfo(&querybuf, "$%d", i + 1);
sprintf(paramname, "$%d", j + 1);
ri_GenerateQual(&qualbuf, qualsep,
- paramname, pk_type,
+ NULL, paramname, pk_type, false,
riinfo->pf_eq_oprs[i],
- attname, fk_type);
+ NULL, attname, fk_type, true);
querysep = ",";
qualsep = "AND";
queryoids[i] = pk_type;
@@ -1372,7 +1366,7 @@ ri_set(TriggerData *trigdata, bool is_set_null, int tgkind)
{
StringInfoData querybuf;
char fkrelname[MAX_QUOTED_REL_NAME_LEN];
- char attname[MAX_QUOTED_NAME_LEN];
+ const char *attname;
char paramname[16];
const char *querysep;
const char *qualsep;
@@ -1430,11 +1424,10 @@ ri_set(TriggerData *trigdata, bool is_set_null, int tgkind)
querysep = "";
for (int i = 0; i < num_cols_to_set; i++)
{
- quoteOneName(attname, RIAttName(fk_rel, set_cols[i]));
- appendStringInfo(&querybuf,
- "%s %s = %s",
- querysep, attname,
- is_set_null ? "NULL" : "DEFAULT");
+ attname = RIAttName(fk_rel, set_cols[i]);
+ appendStringInfoString(&querybuf, querysep);
+ appendStringInfoIdentifier(&querybuf, " ", attname, " = ");
+ appendStringInfoString(&querybuf, is_set_null ? "NULL" : "DEFAULT");
querysep = ",";
}
@@ -1447,14 +1440,13 @@ ri_set(TriggerData *trigdata, bool is_set_null, int tgkind)
Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]);
Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]);
- quoteOneName(attname,
- RIAttName(fk_rel, riinfo->fk_attnums[i]));
+ attname = RIAttName(fk_rel, riinfo->fk_attnums[i]);
sprintf(paramname, "$%d", i + 1);
ri_GenerateQual(&querybuf, qualsep,
- paramname, pk_type,
+ NULL, paramname, pk_type, false,
riinfo->pf_eq_oprs[i],
- attname, fk_type);
+ NULL, attname, fk_type, true);
qualsep = "AND";
queryoids[i] = pk_type;
}
@@ -1652,8 +1644,8 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
StringInfoData querybuf;
char pkrelname[MAX_QUOTED_REL_NAME_LEN];
char fkrelname[MAX_QUOTED_REL_NAME_LEN];
- char pkattname[MAX_QUOTED_NAME_LEN + 3];
- char fkattname[MAX_QUOTED_NAME_LEN + 3];
+ const char *pkattname;
+ const char *fkattname;
RangeTblEntry *rte;
RTEPermissionInfo *pk_perminfo;
RTEPermissionInfo *fk_perminfo;
@@ -1748,9 +1740,9 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
sep = "";
for (int i = 0; i < riinfo->nkeys; i++)
{
- quoteOneName(fkattname,
- RIAttName(fk_rel, riinfo->fk_attnums[i]));
- appendStringInfo(&querybuf, "%sfk.%s", sep, fkattname);
+ fkattname = RIAttName(fk_rel, riinfo->fk_attnums[i]);
+ appendStringInfoString(&querybuf, sep);
+ appendStringInfoIdentifier(&querybuf, "fk.", fkattname, NULL);
sep = ", ";
}
@@ -1764,8 +1756,6 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
" FROM %s%s fk LEFT OUTER JOIN %s%s pk ON",
fk_only, fkrelname, pk_only, pkrelname);
- strcpy(pkattname, "pk.");
- strcpy(fkattname, "fk.");
sep = "(";
for (int i = 0; i < riinfo->nkeys; i++)
{
@@ -1774,14 +1764,12 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
Oid pk_coll = RIAttCollation(pk_rel, riinfo->pk_attnums[i]);
Oid fk_coll = RIAttCollation(fk_rel, riinfo->fk_attnums[i]);
- quoteOneName(pkattname + 3,
- RIAttName(pk_rel, riinfo->pk_attnums[i]));
- quoteOneName(fkattname + 3,
- RIAttName(fk_rel, riinfo->fk_attnums[i]));
+ pkattname = RIAttName(pk_rel, riinfo->pk_attnums[i]);
+ fkattname = RIAttName(fk_rel, riinfo->fk_attnums[i]);
ri_GenerateQual(&querybuf, sep,
- pkattname, pk_type,
+ "pk.", pkattname, pk_type, true,
riinfo->pf_eq_oprs[i],
- fkattname, fk_type);
+ "fk.", fkattname, fk_type, true);
if (pk_coll != fk_coll)
ri_GenerateQualCollation(&querybuf, pk_coll);
sep = "AND";
@@ -1791,16 +1779,15 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
* It's sufficient to test any one pk attribute for null to detect a join
* failure.
*/
- quoteOneName(pkattname, RIAttName(pk_rel, riinfo->pk_attnums[0]));
- appendStringInfo(&querybuf, ") WHERE pk.%s IS NULL AND (", pkattname);
+ pkattname = RIAttName(pk_rel, riinfo->pk_attnums[0]);
+ appendStringInfoIdentifier(&querybuf, ") WHERE pk.", pkattname, " IS NULL AND (");
sep = "";
for (int i = 0; i < riinfo->nkeys; i++)
{
- quoteOneName(fkattname, RIAttName(fk_rel, riinfo->fk_attnums[i]));
- appendStringInfo(&querybuf,
- "%sfk.%s IS NOT NULL",
- sep, fkattname);
+ fkattname = RIAttName(fk_rel, riinfo->fk_attnums[i]);
+ appendStringInfoString(&querybuf, sep);
+ appendStringInfoIdentifier(&querybuf, "fk.", fkattname, " IS NOT NULL");
switch (riinfo->confmatchtype)
{
case FKCONSTR_MATCH_SIMPLE:
@@ -1947,8 +1934,8 @@ RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
char *constraintDef;
char pkrelname[MAX_QUOTED_REL_NAME_LEN];
char fkrelname[MAX_QUOTED_REL_NAME_LEN];
- char pkattname[MAX_QUOTED_NAME_LEN + 3];
- char fkattname[MAX_QUOTED_NAME_LEN + 3];
+ const char *pkattname;
+ const char *fkattname;
const char *sep;
const char *fk_only;
int save_nestlevel;
@@ -1985,9 +1972,9 @@ RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
sep = "";
for (i = 0; i < riinfo->nkeys; i++)
{
- quoteOneName(fkattname,
- RIAttName(fk_rel, riinfo->fk_attnums[i]));
- appendStringInfo(&querybuf, "%sfk.%s", sep, fkattname);
+ fkattname = RIAttName(fk_rel, riinfo->fk_attnums[i]);
+ appendStringInfoString(&querybuf, sep);
+ appendStringInfoIdentifier(&querybuf, "fk.", fkattname, NULL);
sep = ", ";
}
@@ -1998,8 +1985,8 @@ RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
appendStringInfo(&querybuf,
" FROM %s%s fk JOIN %s pk ON",
fk_only, fkrelname, pkrelname);
- strcpy(pkattname, "pk.");
- strcpy(fkattname, "fk.");
+ /* strcpy(pkattname, "pk."); */
+ /* strcpy(fkattname, "fk."); */
sep = "(";
for (i = 0; i < riinfo->nkeys; i++)
{
@@ -2008,14 +1995,12 @@ RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
Oid pk_coll = RIAttCollation(pk_rel, riinfo->pk_attnums[i]);
Oid fk_coll = RIAttCollation(fk_rel, riinfo->fk_attnums[i]);
- quoteOneName(pkattname + 3,
- RIAttName(pk_rel, riinfo->pk_attnums[i]));
- quoteOneName(fkattname + 3,
- RIAttName(fk_rel, riinfo->fk_attnums[i]));
+ pkattname = RIAttName(pk_rel, riinfo->pk_attnums[i]);
+ fkattname = RIAttName(fk_rel, riinfo->fk_attnums[i]);
ri_GenerateQual(&querybuf, sep,
- pkattname, pk_type,
+ "pk.", pkattname, pk_type, true,
riinfo->pf_eq_oprs[i],
- fkattname, fk_type);
+ "fk.", fkattname, fk_type, true);
if (pk_coll != fk_coll)
ri_GenerateQualCollation(&querybuf, pk_coll);
sep = "AND";
@@ -2036,10 +2021,9 @@ RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
sep = "";
for (i = 0; i < riinfo->nkeys; i++)
{
- quoteOneName(fkattname, RIAttName(fk_rel, riinfo->fk_attnums[i]));
- appendStringInfo(&querybuf,
- "%sfk.%s IS NOT NULL",
- sep, fkattname);
+ fkattname = RIAttName(fk_rel, riinfo->fk_attnums[i]);
+ appendStringInfoString(&querybuf, sep);
+ appendStringInfoIdentifier(&querybuf, "fk.", fkattname, " IS NOT NULL");
switch (riinfo->confmatchtype)
{
case FKCONSTR_MATCH_SIMPLE:
@@ -2197,13 +2181,15 @@ quoteRelationName(char *buffer, Relation rel)
static void
ri_GenerateQual(StringInfo buf,
const char *sep,
- const char *leftop, Oid leftoptype,
+ const char *leftopprefix, const char *leftop, Oid leftoptype, bool quoteleftop,
Oid opoid,
- const char *rightop, Oid rightoptype)
+ const char *rightopprefix, const char *rightop, Oid rightoptype, bool quoterightop)
{
appendStringInfo(buf, " %s ", sep);
- generate_operator_clause(buf, leftop, leftoptype, opoid,
- rightop, rightoptype);
+ generate_operator_clause(buf,
+ leftopprefix, leftop, leftoptype, quoteleftop,
+ opoid,
+ rightopprefix, rightop, rightoptype, quoterightop);
}
/*
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index af4a56f7bd7..8dcab752ca5 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -14190,9 +14190,9 @@ generate_operator_name(Oid operid, Oid arg1, Oid arg2)
*/
void
generate_operator_clause(StringInfo buf,
- const char *leftop, Oid leftoptype,
+ const char *leftopprefix, const char *leftop, Oid leftoptype, bool quoteleftop,
Oid opoid,
- const char *rightop, Oid rightoptype)
+ const char *rightopprefix, const char *rightop, Oid rightoptype, bool quoterightop)
{
HeapTuple opertup;
Form_pg_operator operform;
@@ -14205,15 +14205,32 @@ generate_operator_clause(StringInfo buf,
operform = (Form_pg_operator) GETSTRUCT(opertup);
Assert(operform->oprkind == 'b');
oprname = NameStr(operform->oprname);
-
nspname = get_namespace_name(operform->oprnamespace);
- appendStringInfoString(buf, leftop);
+ if (quoteleftop)
+ appendStringInfoIdentifier(buf, leftopprefix, leftop, NULL);
+ else
+ {
+ if (leftopprefix)
+ appendStringInfoString(buf, leftopprefix);
+ appendStringInfoString(buf, leftop);
+ }
+
if (leftoptype != operform->oprleft)
add_cast_to(buf, operform->oprleft);
- appendStringInfo(buf, " OPERATOR(%s.", quote_identifier(nspname));
- appendStringInfoString(buf, oprname);
- appendStringInfo(buf, ") %s", rightop);
+
+ appendStringInfoIdentifier(buf, " OPERATOR(", nspname, ".");
+ appendStringInfo(buf, "%s) ", oprname);
+
+ if (quoterightop)
+ appendStringInfoIdentifier(buf, rightopprefix, rightop, NULL);
+ else
+ {
+ if (rightopprefix)
+ appendStringInfoString(buf, rightopprefix);
+ appendStringInfoString(buf, rightop);
+ }
+
if (rightoptype != operform->oprright)
add_cast_to(buf, operform->oprright);
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 7dbbb4c7c7f..adb1f51768f 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -82,9 +82,9 @@ extern const char *quote_identifier(const char *ident);
extern char *quote_qualified_identifier(const char *qualifier,
const char *ident);
extern void generate_operator_clause(StringInfo buf,
- const char *leftop, Oid leftoptype,
+ const char *leftopprefix, const char *leftop, Oid leftoptype, bool quoteleftop,
Oid opoid,
- const char *rightop, Oid rightoptype);
+ const char *rightopprefix, const char *rightop, Oid rightoptype, bool quoterightop);
extern void appendStringInfoIdentifier(StringInfo str, const char *prefix, const char *ident, const char *suffix);
extern void appendStringInfoQualifiedIdentifier(StringInfo str,
const char *prefix,
--
2.50.1 (Apple Git-155)
[application/octet-stream] v5-0003-Remove-quoteOneName-and-related-buffer-sizing-mac.patch (11.5K, 4-v5-0003-Remove-quoteOneName-and-related-buffer-sizing-mac.patch)
download | inline diff:
From 10c7438f070f827cb4115bb912b59e1a3a7410f2 Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <[email protected]>
Date: Tue, 18 Nov 2025 17:13:07 +0800
Subject: [PATCH v5 3/4] Remove quoteOneName() and related buffer-sizing macros
from ri_triggers.c
After the previous refactoring, quoteOneName() and its callers are no longer
needed. Remove the function along with MAX_QUOTED_NAME_LEN,
MAX_QUOTED_REL_NAME_LEN, and quoteRelationName(), and introduce
appendRelationName() as the remaining helper for writing qualified relation
names using appendStringInfoQualifiedIdentifier().
This reduces redundant quoting code and centralizes identifier handling in
appendStringInfoIdentifier() / appendStringInfoQualifiedIdentifier(), making
RI triggers consistent with other code that generates SQL fragments.
No functional behavior change is expected.
Author: Chao Li <[email protected]>
Discussion: https://postgr.es/m/CAEoWx2=g2RVkxXB=JzWphgfg4QGV+spaA3PQ1rBM2iMehrVvjg@mail.gmail.com
---
src/backend/utils/adt/ri_triggers.c | 112 ++++++++--------------------
1 file changed, 30 insertions(+), 82 deletions(-)
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index e55fa8c6574..9e14da86ca6 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -86,9 +86,6 @@
#define RI_PLAN_SETDEFAULT_ONDELETE 9
#define RI_PLAN_SETDEFAULT_ONUPDATE 10
-#define MAX_QUOTED_NAME_LEN (NAMEDATALEN*2+3)
-#define MAX_QUOTED_REL_NAME_LEN (MAX_QUOTED_NAME_LEN*2)
-
#define RIAttName(rel, attnum) NameStr(*attnumAttName(rel, attnum))
#define RIAttType(rel, attnum) attnumTypeId(rel, attnum)
#define RIAttCollation(rel, attnum) attnumCollationId(rel, attnum)
@@ -270,8 +267,7 @@ static bool ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel,
const RI_ConstraintInfo *riinfo);
static Datum ri_restrict(TriggerData *trigdata, bool is_no_action);
static Datum ri_set(TriggerData *trigdata, bool is_set_null, int tgkind);
-static void quoteOneName(char *buffer, const char *name);
-static void quoteRelationName(char *buffer, Relation rel);
+static void appendRelationName(StringInfo buffer, Relation rel, const char *prefix, const char *suffix);
static void ri_GenerateQual(StringInfo buf,
const char *sep,
const char *leftopprefix, const char *leftop, Oid leftoptype, bool quoteleftop,
@@ -490,7 +486,6 @@ RI_FKey_check(TriggerData *trigdata)
if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL)
{
StringInfoData querybuf;
- char pkrelname[MAX_QUOTED_REL_NAME_LEN];
const char *attname;
char paramname[16];
const char *querysep;
@@ -523,19 +518,16 @@ RI_FKey_check(TriggerData *trigdata)
initStringInfo(&querybuf);
pk_only = pk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
- quoteRelationName(pkrelname, pk_rel);
if (riinfo->hasperiod)
{
attname = RIAttName(pk_rel, riinfo->pk_attnums[riinfo->nkeys - 1]);
appendStringInfoIdentifier(&querybuf, "SELECT 1 FROM (SELECT ", attname, " AS r FROM ");
- appendStringInfo(&querybuf,
- "%s%s x",
- pk_only, pkrelname);
+ appendRelationName(&querybuf, pk_rel, pk_only, " x");
}
else
{
- appendStringInfo(&querybuf, "SELECT 1 FROM %s%s x",
- pk_only, pkrelname);
+ appendStringInfoString(&querybuf, "SELECT 1 FROM ");
+ appendRelationName(&querybuf, pk_rel, pk_only, " x");
}
querysep = "WHERE";
for (int i = 0; i < riinfo->nkeys; i++)
@@ -659,7 +651,6 @@ ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel,
if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL)
{
StringInfoData querybuf;
- char pkrelname[MAX_QUOTED_REL_NAME_LEN];
const char *attname;
char paramname[16];
const char *querysep;
@@ -692,19 +683,16 @@ ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel,
initStringInfo(&querybuf);
pk_only = pk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
- quoteRelationName(pkrelname, pk_rel);
if (riinfo->hasperiod)
{
attname = RIAttName(pk_rel, riinfo->pk_attnums[riinfo->nkeys - 1]);
appendStringInfoIdentifier(&querybuf, "SELECT 1 FROM (SELECT ", attname, " AS r FROM ");
- appendStringInfo(&querybuf,
- "%s%s x",
- pk_only, pkrelname);
+ appendRelationName(&querybuf, pk_rel, pk_only, " x");
}
else
{
- appendStringInfo(&querybuf, "SELECT 1 FROM %s%s x",
- pk_only, pkrelname);
+ appendStringInfoString(&querybuf, "SELECT 1 FROM ");
+ appendRelationName(&querybuf, pk_rel, pk_only, " x");
}
querysep = "WHERE";
for (int i = 0; i < riinfo->nkeys; i++)
@@ -886,10 +874,7 @@ ri_restrict(TriggerData *trigdata, bool is_no_action)
if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL)
{
StringInfoData querybuf;
- char pkrelname[MAX_QUOTED_REL_NAME_LEN];
- char fkrelname[MAX_QUOTED_REL_NAME_LEN];
const char *attname;
- char periodattname[MAX_QUOTED_NAME_LEN];
char paramname[16];
const char *querysep;
Oid queryoids[RI_MAX_NUMKEYS];
@@ -906,9 +891,8 @@ ri_restrict(TriggerData *trigdata, bool is_no_action)
initStringInfo(&querybuf);
fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
- quoteRelationName(fkrelname, fk_rel);
- appendStringInfo(&querybuf, "SELECT 1 FROM %s%s x",
- fk_only, fkrelname);
+ appendStringInfoString(&querybuf, "SELECT 1 FROM ");
+ appendRelationName(&querybuf, fk_rel, fk_only, " x");
querysep = "WHERE";
for (int i = 0; i < riinfo->nkeys; i++)
{
@@ -976,10 +960,8 @@ ri_restrict(TriggerData *trigdata, bool is_no_action)
initStringInfo(&replacementsbuf);
appendStringInfoString(&replacementsbuf, "(SELECT pg_catalog.range_agg(r) FROM ");
- quoteOneName(periodattname, RIAttName(pk_rel, riinfo->pk_attnums[riinfo->nkeys - 1]));
- quoteRelationName(pkrelname, pk_rel);
- appendStringInfo(&replacementsbuf, "(SELECT y.%s r FROM %s%s y",
- periodattname, pk_only, pkrelname);
+ appendStringInfoIdentifier(&replacementsbuf, "(SELECT y.", RIAttName(pk_rel, riinfo->pk_attnums[riinfo->nkeys - 1]), " r FROM ");
+ appendRelationName(&replacementsbuf, pk_rel, pk_only, " y");
/* Restrict pk rows to what matches */
querysep = "WHERE";
@@ -1072,7 +1054,6 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS)
if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL)
{
StringInfoData querybuf;
- char fkrelname[MAX_QUOTED_REL_NAME_LEN];
const char *attname;
char paramname[16];
const char *querysep;
@@ -1089,9 +1070,8 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS)
initStringInfo(&querybuf);
fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
- quoteRelationName(fkrelname, fk_rel);
- appendStringInfo(&querybuf, "DELETE FROM %s%s",
- fk_only, fkrelname);
+ appendStringInfoString(&querybuf, "DELETE FROM ");
+ appendRelationName(&querybuf, fk_rel, fk_only, NULL);
querysep = "WHERE";
for (int i = 0; i < riinfo->nkeys; i++)
{
@@ -1177,7 +1157,6 @@ RI_FKey_cascade_upd(PG_FUNCTION_ARGS)
{
StringInfoData querybuf;
StringInfoData qualbuf;
- char fkrelname[MAX_QUOTED_REL_NAME_LEN];
const char *attname;
char paramname[16];
const char *querysep;
@@ -1199,9 +1178,8 @@ RI_FKey_cascade_upd(PG_FUNCTION_ARGS)
initStringInfo(&qualbuf);
fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
- quoteRelationName(fkrelname, fk_rel);
- appendStringInfo(&querybuf, "UPDATE %s%s SET",
- fk_only, fkrelname);
+ appendStringInfoString(&querybuf, "UPDATE ");
+ appendRelationName(&querybuf, fk_rel, fk_only, " SET");
querysep = "";
qualsep = "WHERE";
for (int i = 0, j = riinfo->nkeys; i < riinfo->nkeys; i++, j++)
@@ -1365,7 +1343,6 @@ ri_set(TriggerData *trigdata, bool is_set_null, int tgkind)
if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL)
{
StringInfoData querybuf;
- char fkrelname[MAX_QUOTED_REL_NAME_LEN];
const char *attname;
char paramname[16];
const char *querysep;
@@ -1414,9 +1391,8 @@ ri_set(TriggerData *trigdata, bool is_set_null, int tgkind)
initStringInfo(&querybuf);
fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
- quoteRelationName(fkrelname, fk_rel);
- appendStringInfo(&querybuf, "UPDATE %s%s SET",
- fk_only, fkrelname);
+ appendStringInfo(&querybuf, "UPDATE ");
+ appendRelationName(&querybuf, fk_rel, fk_only, " SET");
/*
* Add assignment clauses
@@ -1642,8 +1618,6 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
{
const RI_ConstraintInfo *riinfo;
StringInfoData querybuf;
- char pkrelname[MAX_QUOTED_REL_NAME_LEN];
- char fkrelname[MAX_QUOTED_REL_NAME_LEN];
const char *pkattname;
const char *fkattname;
RangeTblEntry *rte;
@@ -1746,15 +1720,13 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
sep = ", ";
}
- quoteRelationName(pkrelname, pk_rel);
- quoteRelationName(fkrelname, fk_rel);
fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
pk_only = pk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
- appendStringInfo(&querybuf,
- " FROM %s%s fk LEFT OUTER JOIN %s%s pk ON",
- fk_only, fkrelname, pk_only, pkrelname);
+ appendStringInfoString(&querybuf, " FROM ");
+ appendRelationName(&querybuf, fk_rel, fk_only, " fk LEFT OUTER JOIN ");
+ appendRelationName(&querybuf, pk_rel, pk_only, " pk ON");
sep = "(";
for (int i = 0; i < riinfo->nkeys; i++)
@@ -1932,8 +1904,6 @@ RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
const RI_ConstraintInfo *riinfo;
StringInfoData querybuf;
char *constraintDef;
- char pkrelname[MAX_QUOTED_REL_NAME_LEN];
- char fkrelname[MAX_QUOTED_REL_NAME_LEN];
const char *pkattname;
const char *fkattname;
const char *sep;
@@ -1978,13 +1948,12 @@ RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
sep = ", ";
}
- quoteRelationName(pkrelname, pk_rel);
- quoteRelationName(fkrelname, fk_rel);
fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ?
"" : "ONLY ";
- appendStringInfo(&querybuf,
- " FROM %s%s fk JOIN %s pk ON",
- fk_only, fkrelname, pkrelname);
+ appendStringInfoString(&querybuf, " FROM ");
+ appendRelationName(&querybuf, fk_rel, fk_only, " fk JOIN ");
+ appendRelationName(&querybuf, pk_rel, NULL, " pk ON");
+
/* strcpy(pkattname, "pk."); */
/* strcpy(fkattname, "fk."); */
sep = "(";
@@ -2137,37 +2106,16 @@ RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
/*
- * quoteOneName --- safely quote a single SQL name
- *
- * buffer must be MAX_QUOTED_NAME_LEN long (includes room for \0)
- */
-static void
-quoteOneName(char *buffer, const char *name)
-{
- /* Rather than trying to be smart, just always quote it. */
- *buffer++ = '"';
- while (*name)
- {
- if (*name == '"')
- *buffer++ = '"';
- *buffer++ = *name++;
- }
- *buffer++ = '"';
- *buffer = '\0';
-}
+ * appendRelationName --- safely append a quoted fully qualified relation name
-/*
- * quoteRelationName --- safely quote a fully qualified relation name
- *
- * buffer must be MAX_QUOTED_REL_NAME_LEN long (includes room for \0)
*/
static void
-quoteRelationName(char *buffer, Relation rel)
+appendRelationName(StringInfo buffer, Relation rel,
+ const char *prefix, const char *suffix)
{
- quoteOneName(buffer, get_namespace_name(RelationGetNamespace(rel)));
- buffer += strlen(buffer);
- *buffer++ = '.';
- quoteOneName(buffer, RelationGetRelationName(rel));
+ appendStringInfoQualifiedIdentifier(buffer, prefix,
+ get_namespace_name(RelationGetNamespace(rel)),
+ RelationGetRelationName(rel), suffix);
}
/*
--
2.50.1 (Apple Git-155)
[application/octet-stream] v5-0004-Use-appendStringInfoIdentifier-in-more-places.patch (34.9K, 5-v5-0004-Use-appendStringInfoIdentifier-in-more-places.patch)
download | inline diff:
From 7ca12d18f5551184266e530d20eff48c5e12dafa Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <[email protected]>
Date: Wed, 19 Nov 2025 15:55:23 +0800
Subject: [PATCH v5 4/4] Use appendStringInfoIdentifier() in more places.
Author: Chao Li <[email protected]>
Discussion: https://postgr.es/m/CAEoWx2=g2RVkxXB=JzWphgfg4QGV+spaA3PQ1rBM2iMehrVvjg@mail.gmail.com
---
src/backend/catalog/namespace.c | 6 +-
src/backend/catalog/objectaddress.c | 64 +++----
src/backend/utils/adt/ri_triggers.c | 8 +-
src/backend/utils/adt/ruleutils.c | 252 ++++++++++++----------------
4 files changed, 143 insertions(+), 187 deletions(-)
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 56b87d878e8..948d0f428e8 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -3701,14 +3701,14 @@ NameListToQuotedString(const List *names)
{
StringInfoData string;
ListCell *l;
+ const char *sep = "";
initStringInfo(&string);
foreach(l, names)
{
- if (l != list_head(names))
- appendStringInfoChar(&string, '.');
- appendStringInfoString(&string, quote_identifier(strVal(lfirst(l))));
+ appendStringInfoIdentifier(&string, sep, strVal(lfirst(l)), NULL);
+ sep = ".";
}
return string.data;
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 88556339dd9..f759a9dcf13 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -5271,8 +5271,7 @@ getObjectIdentityParts(const ObjectAddress *object,
if (OidIsValid(con->conrelid))
{
- appendStringInfo(&buffer, "%s on ",
- quote_identifier(NameStr(con->conname)));
+ appendStringInfoIdentifier(&buffer, NULL, NameStr(con->conname), " on ");
getRelationIdentity(&buffer, con->conrelid, objname,
false);
if (objname)
@@ -5287,10 +5286,10 @@ getObjectIdentityParts(const ObjectAddress *object,
domain.objectId = con->contypid;
domain.objectSubId = 0;
- appendStringInfo(&buffer, "%s on %s",
- quote_identifier(NameStr(con->conname)),
- getObjectIdentityParts(&domain, objname,
- objargs, false));
+ appendStringInfoIdentifier(&buffer, NULL, NameStr(con->conname), " on ");
+ appendStringInfoString(&buffer,
+ getObjectIdentityParts(&domain, objname,
+ objargs, false));
if (objname)
*objargs = lappend(*objargs, pstrdup(NameStr(con->conname)));
@@ -5363,8 +5362,8 @@ getObjectIdentityParts(const ObjectAddress *object,
break;
}
langForm = (Form_pg_language) GETSTRUCT(langTup);
- appendStringInfoString(&buffer,
- quote_identifier(NameStr(langForm->lanname)));
+ appendStringInfoIdentifier(&buffer, NULL,
+ NameStr(langForm->lanname), NULL);
if (objname)
*objname = list_make1(pstrdup(NameStr(langForm->lanname)));
ReleaseSysCache(langTup);
@@ -5422,10 +5421,11 @@ getObjectIdentityParts(const ObjectAddress *object,
opcForm->opcmethod);
amForm = (Form_pg_am) GETSTRUCT(amTup);
- appendStringInfo(&buffer, "%s USING %s",
- quote_qualified_identifier(schema,
- NameStr(opcForm->opcname)),
- quote_identifier(NameStr(amForm->amname)));
+ appendStringInfoQualifiedIdentifier(&buffer, NULL,
+ schema, NameStr(opcForm->opcname),
+ " USING ");
+ appendStringInfoIdentifier(&buffer, NULL,
+ NameStr(amForm->amname), NULL);
if (objname)
*objname = list_make3(pstrdup(NameStr(amForm->amname)),
schema,
@@ -5453,7 +5453,7 @@ getObjectIdentityParts(const ObjectAddress *object,
object->objectId);
break;
}
- appendStringInfoString(&buffer, quote_identifier(amname));
+ appendStringInfoIdentifier(&buffer, NULL, amname, NULL);
if (objname)
*objname = list_make1(amname);
}
@@ -5606,8 +5606,7 @@ getObjectIdentityParts(const ObjectAddress *object,
rule = (Form_pg_rewrite) GETSTRUCT(tup);
- appendStringInfo(&buffer, "%s on ",
- quote_identifier(NameStr(rule->rulename)));
+ appendStringInfoIdentifier(&buffer, NULL, NameStr(rule->rulename), " on ");
getRelationIdentity(&buffer, rule->ev_class, objname, false);
if (objname)
*objname = lappend(*objname, pstrdup(NameStr(rule->rulename)));
@@ -5639,8 +5638,7 @@ getObjectIdentityParts(const ObjectAddress *object,
trig = (Form_pg_trigger) GETSTRUCT(tup);
- appendStringInfo(&buffer, "%s on ",
- quote_identifier(NameStr(trig->tgname)));
+ appendStringInfoIdentifier(&buffer, NULL, NameStr(trig->tgname), " on ");
getRelationIdentity(&buffer, trig->tgrelid, objname, false);
if (objname)
*objname = lappend(*objname, pstrdup(NameStr(trig->tgname)));
@@ -5811,8 +5809,7 @@ getObjectIdentityParts(const ObjectAddress *object,
break;
if (objname)
*objname = list_make1(username);
- appendStringInfoString(&buffer,
- quote_identifier(username));
+ appendStringInfoIdentifier(&buffer, NULL, username, NULL);
break;
}
@@ -5873,8 +5870,7 @@ getObjectIdentityParts(const ObjectAddress *object,
}
if (objname)
*objname = list_make1(datname);
- appendStringInfoString(&buffer,
- quote_identifier(datname));
+ appendStringInfoIdentifier(&buffer, NULL, datname, NULL);
break;
}
@@ -5892,8 +5888,7 @@ getObjectIdentityParts(const ObjectAddress *object,
}
if (objname)
*objname = list_make1(tblspace);
- appendStringInfoString(&buffer,
- quote_identifier(tblspace));
+ appendStringInfoIdentifier(&buffer, NULL, tblspace, NULL);
break;
}
@@ -5905,7 +5900,7 @@ getObjectIdentityParts(const ObjectAddress *object,
missing_ok);
if (fdw)
{
- appendStringInfoString(&buffer, quote_identifier(fdw->fdwname));
+ appendStringInfoIdentifier(&buffer, NULL, fdw->fdwname, NULL);
if (objname)
*objname = list_make1(pstrdup(fdw->fdwname));
}
@@ -5920,8 +5915,7 @@ getObjectIdentityParts(const ObjectAddress *object,
missing_ok);
if (srv)
{
- appendStringInfoString(&buffer,
- quote_identifier(srv->servername));
+ appendStringInfoIdentifier(&buffer, NULL, srv->servername, NULL);
if (objname)
*objname = list_make1(pstrdup(srv->servername));
}
@@ -5962,9 +5956,8 @@ getObjectIdentityParts(const ObjectAddress *object,
*objargs = list_make1(pstrdup(srv->servername));
}
- appendStringInfo(&buffer, "%s on server %s",
- quote_identifier(usename),
- srv->servername);
+ appendStringInfoIdentifier(&buffer, NULL, usename, " on server ");
+ appendStringInfoString(&buffer, srv->servername);
break;
}
@@ -6067,7 +6060,7 @@ getObjectIdentityParts(const ObjectAddress *object,
object->objectId);
break;
}
- appendStringInfoString(&buffer, quote_identifier(extname));
+ appendStringInfoIdentifier(&buffer, NULL, extname, NULL);
if (objname)
*objname = list_make1(extname);
break;
@@ -6090,7 +6083,7 @@ getObjectIdentityParts(const ObjectAddress *object,
}
trigForm = (Form_pg_event_trigger) GETSTRUCT(tup);
evtname = pstrdup(NameStr(trigForm->evtname));
- appendStringInfoString(&buffer, quote_identifier(evtname));
+ appendStringInfoIdentifier(&buffer, NULL, evtname, NULL);
if (objname)
*objname = list_make1(evtname);
ReleaseSysCache(tup);
@@ -6145,8 +6138,7 @@ getObjectIdentityParts(const ObjectAddress *object,
policy = (Form_pg_policy) GETSTRUCT(tup);
- appendStringInfo(&buffer, "%s on ",
- quote_identifier(NameStr(policy->polname)));
+ appendStringInfoIdentifier(&buffer, NULL, NameStr(policy->polname), " on ");
getRelationIdentity(&buffer, policy->polrelid, objname, false);
if (objname)
*objname = lappend(*objname, pstrdup(NameStr(policy->polname)));
@@ -6229,8 +6221,7 @@ getObjectIdentityParts(const ObjectAddress *object,
pubname = get_publication_name(object->objectId, missing_ok);
if (pubname)
{
- appendStringInfoString(&buffer,
- quote_identifier(pubname));
+ appendStringInfoIdentifier(&buffer, NULL, pubname, NULL);
if (objname)
*objname = list_make1(pubname);
}
@@ -6297,8 +6288,7 @@ getObjectIdentityParts(const ObjectAddress *object,
subname = get_subscription_name(object->objectId, missing_ok);
if (subname)
{
- appendStringInfoString(&buffer,
- quote_identifier(subname));
+ appendStringInfoIdentifier(&buffer, NULL, subname, NULL);
if (objname)
*objname = list_make1(subname);
}
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index 9e14da86ca6..c03d7b46d14 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -958,9 +958,11 @@ ri_restrict(TriggerData *trigdata, bool is_no_action)
/* Find the remaining history */
initStringInfo(&replacementsbuf);
- appendStringInfoString(&replacementsbuf, "(SELECT pg_catalog.range_agg(r) FROM ");
- appendStringInfoIdentifier(&replacementsbuf, "(SELECT y.", RIAttName(pk_rel, riinfo->pk_attnums[riinfo->nkeys - 1]), " r FROM ");
+ appendStringInfoIdentifier(&replacementsbuf,
+ "(SELECT pg_catalog.range_agg(r) FROM (SELECT y.",
+ RIAttName(pk_rel, riinfo->pk_attnums[riinfo->nkeys - 1]),
+ " r FROM ");
appendRelationName(&replacementsbuf, pk_rel, pk_only, " y");
/* Restrict pk rows to what matches */
@@ -1954,8 +1956,6 @@ RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
appendRelationName(&querybuf, fk_rel, fk_only, " fk JOIN ");
appendRelationName(&querybuf, pk_rel, NULL, " pk ON");
- /* strcpy(pkattname, "pk."); */
- /* strcpy(fkattname, "fk."); */
sep = "(";
for (i = 0; i < riinfo->nkeys; i++)
{
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 8dcab752ca5..6126da4d4bd 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -990,18 +990,17 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
/* tgattr is first var-width field, so OK to access directly */
if (trigrec->tgattr.dim1 > 0)
{
- int i;
+ const char *sep = "";
appendStringInfoString(&buf, " OF ");
- for (i = 0; i < trigrec->tgattr.dim1; i++)
+ for (int i = 0; i < trigrec->tgattr.dim1; i++)
{
char *attname;
- if (i > 0)
- appendStringInfoString(&buf, ", ");
attname = get_attname(trigrec->tgrelid,
trigrec->tgattr.values[i], false);
- appendStringInfoString(&buf, quote_identifier(attname));
+ appendStringInfoIdentifier(&buf, sep, attname, NULL);
+ sep = ", ";
}
}
}
@@ -1053,11 +1052,9 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
{
appendStringInfoString(&buf, "REFERENCING ");
if (tgoldtable != NULL)
- appendStringInfo(&buf, "OLD TABLE AS %s ",
- quote_identifier(tgoldtable));
+ appendStringInfoIdentifier(&buf, "OLD TABLE AS ", tgoldtable, " ");
if (tgnewtable != NULL)
- appendStringInfo(&buf, "NEW TABLE AS %s ",
- quote_identifier(tgnewtable));
+ appendStringInfoIdentifier(&buf, "NEW TABLE AS ", tgnewtable, " ");
}
if (TRIGGER_FOR_ROW(trigrec->tgtype))
@@ -1398,8 +1395,7 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
generate_qualified_relation_name(indrelid),
quote_identifier(NameStr(amrec->amname)));
else /* currently, must be EXCLUDE constraint */
- appendStringInfo(&buf, "EXCLUDE USING %s (",
- quote_identifier(NameStr(amrec->amname)));
+ appendStringInfoIdentifier(&buf, "EXCLUDE USING ", NameStr(amrec->amname), " (");
}
/*
@@ -1437,7 +1433,7 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
attname = get_attname(indrelid, attnum, false);
if (!colno || colno == keyno + 1)
- appendStringInfoString(&buf, quote_identifier(attname));
+ appendStringInfoIdentifier(&buf, NULL, attname, NULL);
get_atttypetypmodcoll(indrelid, attnum,
&keycoltype, &keycoltypmod,
&keycolcollation);
@@ -1547,8 +1543,8 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
{
if (isConstraint)
appendStringInfoString(&buf, " USING INDEX");
- appendStringInfo(&buf, " TABLESPACE %s",
- quote_identifier(get_tablespace_name(tblspc)));
+ appendStringInfoIdentifier(&buf, " TABLESPACE ",
+ get_tablespace_name(tblspc), NULL);
}
}
@@ -2153,7 +2149,7 @@ pg_get_statisticsobj_worker(Oid statextid, bool columns_only, bool missing_ok)
attname = get_attname(statextrec->stxrelid, attnum, false);
- appendStringInfoString(&buf, quote_identifier(attname));
+ appendStringInfoIdentifier(&buf, NULL, attname, NULL);
}
context = deparse_context_for(get_relation_name(statextrec->stxrelid),
@@ -2397,7 +2393,7 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags,
int32 keycoltypmod;
attname = get_attname(relid, attnum, false);
- appendStringInfoString(&buf, quote_identifier(attname));
+ appendStringInfoIdentifier(&buf, NULL, attname, NULL);
get_atttypetypmodcoll(relid, attnum,
&keycoltype, &keycoltypmod,
&keycolcollation);
@@ -2605,17 +2601,19 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
* we might need to let callers specify whether to put ONLY in the
* command.
*/
- appendStringInfo(&buf, "ALTER TABLE %s ADD CONSTRAINT %s ",
- generate_qualified_relation_name(conForm->conrelid),
- quote_identifier(NameStr(conForm->conname)));
+ appendStringInfo(&buf, "ALTER TABLE %s ",
+ generate_qualified_relation_name(conForm->conrelid));
+ appendStringInfoIdentifier(&buf, "ADD CONSTRAINT ",
+ NameStr(conForm->conname), " ");
}
else
{
/* Must be a domain constraint */
Assert(OidIsValid(conForm->contypid));
- appendStringInfo(&buf, "ALTER DOMAIN %s ADD CONSTRAINT %s ",
- generate_qualified_type_name(conForm->contypid),
- quote_identifier(NameStr(conForm->conname)));
+ appendStringInfo(&buf, "ALTER DOMAIN %s ",
+ generate_qualified_type_name(conForm->contypid));
+ appendStringInfoIdentifier(&buf, "ADD CONSTRAINT ",
+ NameStr(conForm->conname), " ");
}
}
@@ -2782,6 +2780,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
Datum *keys;
int nKeys;
int j;
+ const char *sep = "";
appendStringInfoString(&buf, " INCLUDE (");
@@ -2797,9 +2796,8 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
colName = get_attname(conForm->conrelid,
DatumGetInt16(keys[j]), false);
- if (j > keyatts)
- appendStringInfoString(&buf, ", ");
- appendStringInfoString(&buf, quote_identifier(colName));
+ appendStringInfoIdentifier(&buf, sep, colName, NULL);
+ sep = ", ";
}
appendStringInfoChar(&buf, ')');
@@ -2826,8 +2824,8 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
*/
tblspc = get_rel_tablespace(indexId);
if (OidIsValid(tblspc))
- appendStringInfo(&buf, " USING INDEX TABLESPACE %s",
- quote_identifier(get_tablespace_name(tblspc)));
+ appendStringInfoIdentifier(&buf, " USING INDEX TABLESPACE ",
+ get_tablespace_name(tblspc), NULL);
}
break;
@@ -2888,9 +2886,9 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
attnum = extractNotNullColumn(tup);
- appendStringInfo(&buf, "NOT NULL %s",
- quote_identifier(get_attname(conForm->conrelid,
- attnum, false)));
+ appendStringInfoIdentifier(&buf, "NOT NULL ",
+ get_attname(conForm->conrelid,
+ attnum, false), NULL);
if (((Form_pg_constraint) GETSTRUCT(tup))->connoinherit)
appendStringInfoString(&buf, " NO INHERIT");
}
@@ -2994,11 +2992,14 @@ decompile_column_index_array(Datum column_index_array, Oid relId,
colName = get_attname(relId, DatumGetInt16(keys[j]), false);
if (j == 0)
- appendStringInfoString(buf, quote_identifier(colName));
+ appendStringInfoIdentifier(buf, NULL, colName, NULL);
else
- appendStringInfo(buf, ", %s%s",
- (withPeriod && j == nKeys - 1) ? "PERIOD " : "",
- quote_identifier(colName));
+ {
+ appendStringInfoString(buf, ", ");
+ appendStringInfoIdentifier(buf,
+ (withPeriod && j == nKeys - 1) ? "PERIOD " : "",
+ colName, NULL);
+ }
}
return nKeys;
@@ -3334,8 +3335,8 @@ pg_get_functiondef(PG_FUNCTION_ARGS)
print_function_trftypes(&buf, proctup);
- appendStringInfo(&buf, " LANGUAGE %s\n",
- quote_identifier(get_language_name(proc->prolang, false)));
+ appendStringInfoIdentifier(&buf, " LANGUAGE ",
+ get_language_name(proc->prolang, false), "\n");
/* Emit some miscellaneous options on one line */
oldlen = buf.len;
@@ -3434,8 +3435,7 @@ pg_get_functiondef(PG_FUNCTION_ARGS)
continue;
*pos++ = '\0';
- appendStringInfo(&buf, " SET %s TO ",
- quote_identifier(configitem));
+ appendStringInfoIdentifier(&buf, " SET ", configitem, " TO ");
/*
* Variables that are marked GUC_LIST_QUOTE were already fully
@@ -3777,7 +3777,7 @@ print_function_arguments(StringInfo buf, HeapTuple proctup,
appendStringInfoString(buf, modename);
if (argname && argname[0])
- appendStringInfo(buf, "%s ", quote_identifier(argname));
+ appendStringInfoIdentifier(buf, NULL, argname, " ");
appendStringInfoString(buf, format_type_be(argtype));
if (print_defaults && isinput && inputargno > nlackdefaults)
{
@@ -5761,8 +5761,7 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
/*
* Build the rules definition text
*/
- appendStringInfo(buf, "CREATE RULE %s AS",
- quote_identifier(rulename));
+ appendStringInfoIdentifier(buf, "CREATE RULE ", rulename, " AS");
if (prettyFlags & PRETTYFLAG_INDENT)
appendStringInfoString(buf, "\n ON ");
@@ -6153,21 +6152,18 @@ get_with_clause(Query *query, deparse_context *context)
CommonTableExpr *cte = (CommonTableExpr *) lfirst(l);
appendStringInfoString(buf, sep);
- appendStringInfoString(buf, quote_identifier(cte->ctename));
+ appendStringInfoIdentifier(buf, NULL, cte->ctename, NULL);
if (cte->aliascolnames)
{
- bool first = true;
ListCell *col;
+ const char *colsep = "";
appendStringInfoChar(buf, '(');
foreach(col, cte->aliascolnames)
{
- if (first)
- first = false;
- else
- appendStringInfoString(buf, ", ");
- appendStringInfoString(buf,
- quote_identifier(strVal(lfirst(col))));
+ appendStringInfoIdentifier(buf, colsep,
+ strVal(lfirst(col)), NULL);
+ colsep = ", ";
}
appendStringInfoChar(buf, ')');
}
@@ -6196,43 +6192,35 @@ get_with_clause(Query *query, deparse_context *context)
if (cte->search_clause)
{
- bool first = true;
ListCell *lc;
+ const char *colsep = "";
appendStringInfo(buf, " SEARCH %s FIRST BY ",
cte->search_clause->search_breadth_first ? "BREADTH" : "DEPTH");
foreach(lc, cte->search_clause->search_col_list)
{
- if (first)
- first = false;
- else
- appendStringInfoString(buf, ", ");
- appendStringInfoString(buf,
- quote_identifier(strVal(lfirst(lc))));
+ appendStringInfoIdentifier(buf, colsep, strVal(lfirst(lc)), NULL);
+ colsep = ", ";
}
- appendStringInfo(buf, " SET %s", quote_identifier(cte->search_clause->search_seq_column));
+ appendStringInfoIdentifier(buf, " SET ", cte->search_clause->search_seq_column, NULL);
}
if (cte->cycle_clause)
{
- bool first = true;
ListCell *lc;
+ const char *colsep = "";
appendStringInfoString(buf, " CYCLE ");
foreach(lc, cte->cycle_clause->cycle_col_list)
{
- if (first)
- first = false;
- else
- appendStringInfoString(buf, ", ");
- appendStringInfoString(buf,
- quote_identifier(strVal(lfirst(lc))));
+ appendStringInfoIdentifier(buf, colsep, strVal(lfirst(lc)), NULL);
+ colsep = ", ";
}
- appendStringInfo(buf, " SET %s", quote_identifier(cte->cycle_clause->cycle_mark_column));
+ appendStringInfoIdentifier(buf, " SET ", cte->cycle_clause->cycle_mark_column, NULL);
{
Const *cmv = castNode(Const, cte->cycle_clause->cycle_mark_value);
@@ -6248,7 +6236,7 @@ get_with_clause(Query *query, deparse_context *context)
}
}
- appendStringInfo(buf, " USING %s", quote_identifier(cte->cycle_clause->cycle_path_column));
+ appendStringInfoIdentifier(buf, " USING ", cte->cycle_clause->cycle_path_column, NULL);
}
sep = ", ";
@@ -6363,9 +6351,7 @@ get_select_query_def(Query *query, deparse_context *context)
get_lock_clause_strength(rc->strength),
-PRETTYINDENT_STD, PRETTYINDENT_STD, 0);
- appendStringInfo(buf, " OF %s",
- quote_identifier(get_rtable_name(rc->rti,
- context)));
+ appendStringInfoIdentifier(buf, " OF ", get_rtable_name(rc->rti, context), NULL);
if (rc->waitPolicy == LockWaitError)
appendStringInfoString(buf, " NOWAIT");
else if (rc->waitPolicy == LockWaitSkip)
@@ -6680,7 +6666,7 @@ get_target_list(List *targetList, deparse_context *context)
if (colname) /* resname could be NULL */
{
if (attname == NULL || strcmp(attname, colname) != 0)
- appendStringInfo(&targetbuf, " AS %s", quote_identifier(colname));
+ appendStringInfoIdentifier(&targetbuf, " AS ", colname, NULL);
}
/* Restore context's output buffer */
@@ -6754,19 +6740,16 @@ get_returning_clause(Query *query, deparse_context *context)
/* Add WITH (OLD/NEW) options, if they're not the defaults */
if (query->returningOldAlias && strcmp(query->returningOldAlias, "old") != 0)
{
- appendStringInfo(buf, " WITH (OLD AS %s",
- quote_identifier(query->returningOldAlias));
+ appendStringInfoIdentifier(buf, " WITH (OLD AS ", query->returningOldAlias, NULL);
have_with = true;
}
if (query->returningNewAlias && strcmp(query->returningNewAlias, "new") != 0)
{
if (have_with)
- appendStringInfo(buf, ", NEW AS %s",
- quote_identifier(query->returningNewAlias));
+ appendStringInfoIdentifier(buf, ", NEW AS ", query->returningNewAlias, NULL);
else
{
- appendStringInfo(buf, " WITH (NEW AS %s",
- quote_identifier(query->returningNewAlias));
+ appendStringInfoIdentifier(buf, " WITH (NEW AS ", query->returningNewAlias, NULL);
have_with = true;
}
}
@@ -7134,7 +7117,7 @@ get_rule_windowclause(Query *query, deparse_context *context)
else
appendStringInfoString(buf, sep);
- appendStringInfo(buf, "%s AS ", quote_identifier(wc->name));
+ appendStringInfoIdentifier(buf, NULL, wc->name, " AS ");
get_rule_windowspec(wc, query->targetList, context);
@@ -7157,7 +7140,7 @@ get_rule_windowspec(WindowClause *wc, List *targetList,
appendStringInfoChar(buf, '(');
if (wc->refname)
{
- appendStringInfoString(buf, quote_identifier(wc->refname));
+ appendStringInfoIdentifier(buf, NULL, wc->refname, NULL);
needspace = true;
}
/* partition clauses are always inherited, so only print if no refname */
@@ -7384,10 +7367,8 @@ get_insert_query_def(Query *query, deparse_context *context)
* Put out name of target column; look in the catalogs, not at
* tle->resname, since resname will fail to track RENAME.
*/
- appendStringInfoString(buf,
- quote_identifier(get_attname(rte->relid,
- tle->resno,
- false)));
+ appendStringInfoIdentifier(buf, NULL,
+ get_attname(rte->relid, tle->resno, false), NULL);
/*
* Print any indirection needed (subfields or subscripts), and strip
@@ -7480,8 +7461,7 @@ get_insert_query_def(Query *query, deparse_context *context)
if (!constraint)
elog(ERROR, "cache lookup failed for constraint %u",
confl->constraint);
- appendStringInfo(buf, " ON CONSTRAINT %s",
- quote_identifier(constraint));
+ appendStringInfoIdentifier(buf, " ON CONSTRAINT ", constraint, NULL);
}
if (confl->action == ONCONFLICT_NOTHING)
@@ -7703,10 +7683,7 @@ get_update_query_targetlist_def(Query *query, List *targetList,
* Put out name of target column; look in the catalogs, not at
* tle->resname, since resname will fail to track RENAME.
*/
- appendStringInfoString(buf,
- quote_identifier(get_attname(rte->relid,
- tle->resno,
- false)));
+ appendStringInfoIdentifier(buf, NULL, get_attname(rte->relid, tle->resno, false), NULL);
/*
* Print any indirection needed (subfields or subscripts), and strip
@@ -7897,10 +7874,10 @@ get_merge_query_def(Query *query, deparse_context *context)
appendStringInfoString(buf, sep);
sep = ", ";
- appendStringInfoString(buf,
- quote_identifier(get_attname(rte->relid,
- tle->resno,
- false)));
+ appendStringInfoIdentifier(buf, NULL,
+ get_attname(rte->relid,
+ tle->resno,
+ false), NULL);
strippedexprs = lappend(strippedexprs,
processIndirection((Node *) tle->expr,
context));
@@ -7959,8 +7936,8 @@ get_utility_query_def(Query *query, deparse_context *context)
appendContextKeyword(context, "",
0, PRETTYINDENT_STD, 1);
- appendStringInfo(buf, "NOTIFY %s",
- quote_identifier(stmt->conditionname));
+ appendStringInfoIdentifier(buf, "NOTIFY ",
+ stmt->conditionname, NULL);
if (stmt->payload)
{
appendStringInfoString(buf, ", ");
@@ -8416,11 +8393,11 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
if (refname && need_prefix)
{
- appendStringInfoString(buf, quote_identifier(refname));
+ appendStringInfoIdentifier(buf, NULL, refname, NULL);
appendStringInfoChar(buf, '.');
}
if (attname)
- appendStringInfoString(buf, quote_identifier(attname));
+ appendStringInfoIdentifier(buf, NULL, attname, NULL);
else
{
appendStringInfoChar(buf, '*');
@@ -9358,11 +9335,10 @@ get_parameter(Param *param, deparse_context *context)
}
if (should_qualify)
{
- appendStringInfoString(context->buf, quote_identifier(dpns->funcname));
- appendStringInfoChar(context->buf, '.');
+ appendStringInfoIdentifier(context->buf, NULL, dpns->funcname, ".");
}
- appendStringInfoString(context->buf, quote_identifier(argname));
+ appendStringInfoIdentifier(context->buf, NULL, argname, NULL);
return;
}
}
@@ -9943,7 +9919,7 @@ get_rule_expr(Node *node, deparse_context *context,
{
NamedArgExpr *na = (NamedArgExpr *) node;
- appendStringInfo(buf, "%s => ", quote_identifier(na->name));
+ appendStringInfoIdentifier(buf, NULL, na->name, " => ");
get_rule_expr((Node *) na->arg, context, showimplicit);
}
break;
@@ -10231,7 +10207,7 @@ get_rule_expr(Node *node, deparse_context *context,
*/
fieldname = get_name_for_var_field((Var *) arg, fno,
0, context);
- appendStringInfo(buf, ".%s", quote_identifier(fieldname));
+ appendStringInfoIdentifier(buf, ".", fieldname, NULL);
}
break;
@@ -10921,8 +10897,8 @@ get_rule_expr(Node *node, deparse_context *context,
CurrentOfExpr *cexpr = (CurrentOfExpr *) node;
if (cexpr->cursor_name)
- appendStringInfo(buf, "CURRENT OF %s",
- quote_identifier(cexpr->cursor_name));
+ appendStringInfoIdentifier(buf, "CURRENT OF ",
+ cexpr->cursor_name, NULL);
else
appendStringInfo(buf, "CURRENT OF $%d",
cexpr->cursor_param);
@@ -11156,8 +11132,8 @@ get_rule_expr(Node *node, deparse_context *context,
needcomma = true;
get_rule_expr((Node *) lfirst(lc2), context, showimplicit);
- appendStringInfo(buf, " AS %s",
- quote_identifier(lfirst_node(String, lc1)->sval));
+ appendStringInfoIdentifier(buf, " AS ",
+ lfirst_node(String, lc1)->sval, NULL);
}
}
@@ -11695,7 +11671,7 @@ get_windowfunc_expr_helper(WindowFunc *wfunc, deparse_context *context,
if (wc->winref == wfunc->winref)
{
if (wc->name)
- appendStringInfoString(buf, quote_identifier(wc->name));
+ appendStringInfoIdentifier(buf, NULL, wc->name, NULL);
else
get_rule_windowspec(wc, context->targetList, context);
break;
@@ -11721,7 +11697,7 @@ get_windowfunc_expr_helper(WindowFunc *wfunc, deparse_context *context,
if (wagg->winref == wfunc->winref)
{
- appendStringInfoString(buf, quote_identifier(wagg->winname));
+ appendStringInfoIdentifier(buf, NULL, wagg->winname, NULL);
break;
}
}
@@ -12559,8 +12535,8 @@ get_xmltable(TableFunc *tf, deparse_context *context, bool showimplicit)
if (ns_node != NULL)
{
get_rule_expr(expr, context, showimplicit);
- appendStringInfo(buf, " AS %s",
- quote_identifier(strVal(ns_node)));
+ appendStringInfoIdentifier(buf, " AS ",
+ strVal(ns_node), NULL);
}
else
{
@@ -12646,7 +12622,7 @@ get_json_table_nested_columns(TableFunc *tf, JsonTablePlan *plan,
appendStringInfoChar(context->buf, ' ');
appendContextKeyword(context, "NESTED PATH ", 0, 0, 0);
get_const_expr(scan->path->value, context, -1);
- appendStringInfo(context->buf, " AS %s", quote_identifier(scan->path->name));
+ appendStringInfoIdentifier(context->buf, " AS ", scan->path->name, NULL);
get_json_table_columns(tf, scan, context, showimplicit);
}
else if (IsA(plan, JsonTableSiblingJoin))
@@ -12789,7 +12765,7 @@ get_json_table(TableFunc *tf, deparse_context *context, bool showimplicit)
get_const_expr(root->path->value, context, -1);
- appendStringInfo(buf, " AS %s", quote_identifier(root->path->name));
+ appendStringInfoIdentifier(buf, " AS ", root->path->name, NULL);
if (jexpr->passing_values)
{
@@ -12813,9 +12789,7 @@ get_json_table(TableFunc *tf, deparse_context *context, bool showimplicit)
appendContextKeyword(context, "", 0, 0, 0);
get_rule_expr((Node *) lfirst(lc2), context, false);
- appendStringInfo(buf, " AS %s",
- quote_identifier((lfirst_node(String, lc1))->sval)
- );
+ appendStringInfoIdentifier(buf, " AS ", lfirst_node(String, lc1)->sval, NULL);
}
if (PRETTY_INDENT(context))
@@ -13120,7 +13094,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
appendStringInfoChar(buf, ')');
break;
case RTE_CTE:
- appendStringInfoString(buf, quote_identifier(rte->ctename));
+ appendStringInfoIdentifier(buf, NULL, rte->ctename, NULL);
break;
default:
elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind);
@@ -13207,7 +13181,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
if (j->usingClause)
{
ListCell *lc;
- bool first = true;
+ const char *sep = "";
appendStringInfoString(buf, " USING (");
/* Use the assigned names, not what's in usingClause */
@@ -13215,17 +13189,13 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
{
char *colname = (char *) lfirst(lc);
- if (first)
- first = false;
- else
- appendStringInfoString(buf, ", ");
- appendStringInfoString(buf, quote_identifier(colname));
+ appendStringInfoIdentifier(buf, sep, colname, NULL);
+ sep = ", ";
}
appendStringInfoChar(buf, ')');
if (j->join_using_alias)
- appendStringInfo(buf, " AS %s",
- quote_identifier(j->join_using_alias->aliasname));
+ appendStringInfoIdentifier(buf, " AS ", j->join_using_alias->aliasname, NULL);
}
else if (j->quals)
{
@@ -13255,9 +13225,9 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
* subtleties we don't want. However, we might print a different
* alias name than was there originally.
*/
- appendStringInfo(buf, " %s",
- quote_identifier(get_rtable_name(j->rtindex,
- context)));
+ appendStringInfoIdentifier(buf, " ",
+ get_rtable_name(j->rtindex,
+ context), NULL);
get_column_alias_list(colinfo, context);
}
}
@@ -13332,9 +13302,9 @@ get_rte_alias(RangeTblEntry *rte, int varno, bool use_as,
}
if (printalias)
- appendStringInfo(context->buf, "%s%s",
- use_as ? " AS " : " ",
- quote_identifier(refname));
+ appendStringInfoIdentifier(context->buf,
+ use_as ? " AS " : " ",
+ refname, NULL);
}
/*
@@ -13397,7 +13367,7 @@ get_column_alias_list(deparse_columns *colinfo, deparse_context *context)
}
else
appendStringInfoString(buf, ", ");
- appendStringInfoString(buf, quote_identifier(colname));
+ appendStringInfoIdentifier(buf, NULL, colname, NULL);
}
if (!first)
appendStringInfoChar(buf, ')');
@@ -13530,13 +13500,11 @@ get_opclass_name(Oid opclass, Oid actual_datatype,
/* Okay, we need the opclass name. Do we need to qualify it? */
opcname = NameStr(opcrec->opcname);
if (OpclassIsVisible(opclass))
- appendStringInfo(buf, " %s", quote_identifier(opcname));
+ appendStringInfoIdentifier(buf, " ", opcname, NULL);
else
{
nspname = get_namespace_name_or_temp(opcrec->opcnamespace);
- appendStringInfo(buf, " %s.%s",
- quote_identifier(nspname),
- quote_identifier(opcname));
+ appendStringInfoQualifiedIdentifier(buf, NULL, nspname, opcname, NULL);
}
}
ReleaseSysCache(ht_opc);
@@ -13600,7 +13568,7 @@ processIndirection(Node *node, deparse_context *context)
Assert(list_length(fstore->fieldnums) == 1);
fieldname = get_attname(typrelid,
linitial_int(fstore->fieldnums), false);
- appendStringInfo(buf, ".%s", quote_identifier(fieldname));
+ appendStringInfoIdentifier(buf, ".", fieldname, NULL);
/*
* We ignore arg since it should be an uninteresting reference to
@@ -14155,7 +14123,7 @@ generate_operator_name(Oid operid, Oid arg1, Oid arg2)
else
{
nspname = get_namespace_name_or_temp(operform->oprnamespace);
- appendStringInfo(&buf, "OPERATOR(%s.", quote_identifier(nspname));
+ appendStringInfoIdentifier(&buf, "OPERATOR(", nspname, ".");
}
appendStringInfoString(&buf, oprname);
@@ -14261,8 +14229,7 @@ add_cast_to(StringInfo buf, Oid typid)
typname = NameStr(typform->typname);
nspname = get_namespace_name_or_temp(typform->typnamespace);
- appendStringInfo(buf, "::%s.%s",
- quote_identifier(nspname), quote_identifier(typname));
+ appendStringInfoQualifiedIdentifier(buf, "::", nspname, typname, NULL);
ReleaseSysCache(typetup);
}
@@ -14359,12 +14326,12 @@ get_reloptions(StringInfo buf, Datum reloptions)
{
Datum *options;
int noptions;
- int i;
+ const char *sep = "";
deconstruct_array_builtin(DatumGetArrayTypeP(reloptions), TEXTOID,
&options, NULL, &noptions);
- for (i = 0; i < noptions; i++)
+ for (int i = 0; i < noptions; i++)
{
char *option = TextDatumGetCString(options[i]);
char *name;
@@ -14385,9 +14352,8 @@ get_reloptions(StringInfo buf, Datum reloptions)
else
value = "";
- if (i > 0)
- appendStringInfoString(buf, ", ");
- appendStringInfo(buf, "%s=", quote_identifier(name));
+ appendStringInfoIdentifier(buf, sep, name, "=");
+ sep = ", ";
/*
* In general we need to quote the value; but to avoid unnecessary
--
2.50.1 (Apple Git-155)
view thread (8+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected], [email protected], [email protected]
Subject: Re: quoteOneName() inconsistency with quote_all_identifiers — replacement API proposed
In-Reply-To: <[email protected]>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox