From bddf5fa9b910babc8209f788710955197dcfc72c Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <lic@highgo.com>
Date: Wed, 19 Nov 2025 15:55:23 +0800
Subject: [PATCH v3 4/4] Use appendStringInfoIdentifier() in more places.

Author: Chao Li <lic@highgo.com>
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   | 260 ++++++++++++----------------
 4 files changed, 147 insertions(+), 191 deletions(-)

diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index d23474da4fb..7c3b0bb7853 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -3699,14 +3699,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 70e05059f9f..fa8762db10d 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -5004,8 +5004,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)
@@ -5020,10 +5019,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)));
@@ -5096,8 +5095,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);
@@ -5155,10 +5154,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,
@@ -5186,7 +5186,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 							 object->objectId);
 					break;
 				}
-				appendStringInfoString(&buffer, quote_identifier(amname));
+				appendStringInfoIdentifier(&buffer, NULL, amname, NULL);
 				if (objname)
 					*objname = list_make1(amname);
 			}
@@ -5339,8 +5339,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)));
@@ -5372,8 +5371,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)));
@@ -5544,8 +5542,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 					break;
 				if (objname)
 					*objname = list_make1(username);
-				appendStringInfoString(&buffer,
-									   quote_identifier(username));
+				appendStringInfoIdentifier(&buffer, NULL, username, NULL);
 				break;
 			}
 
@@ -5606,8 +5603,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				}
 				if (objname)
 					*objname = list_make1(datname);
-				appendStringInfoString(&buffer,
-									   quote_identifier(datname));
+				appendStringInfoIdentifier(&buffer, NULL, datname, NULL);
 				break;
 			}
 
@@ -5625,8 +5621,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				}
 				if (objname)
 					*objname = list_make1(tblspace);
-				appendStringInfoString(&buffer,
-									   quote_identifier(tblspace));
+				appendStringInfoIdentifier(&buffer, NULL, tblspace, NULL);
 				break;
 			}
 
@@ -5638,7 +5633,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));
 				}
@@ -5653,8 +5648,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));
 				}
@@ -5695,9 +5689,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;
 			}
 
@@ -5800,7 +5793,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;
@@ -5823,7 +5816,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);
@@ -5878,8 +5871,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)));
@@ -5895,8 +5887,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);
 				}
@@ -5963,8 +5954,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 d676930aca2..5b1c6547519 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -825,9 +825,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 */
@@ -1821,8 +1823,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 b212a28d9be..a83cac7f03a 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -979,18 +979,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 = ", ";
 			}
 		}
 	}
@@ -1042,11 +1041,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))
@@ -1387,8 +1384,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), " (");
 	}
 
 	/*
@@ -1426,7 +1422,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);
@@ -1536,8 +1532,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);
 			}
 		}
 
@@ -1794,7 +1790,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),
@@ -2038,7 +2034,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);
@@ -2246,17 +2242,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), " ");
 		}
 	}
 
@@ -2423,6 +2421,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
 					Datum	   *keys;
 					int			nKeys;
 					int			j;
+					const char *sep = "";
 
 					appendStringInfoString(&buf, " INCLUDE (");
 
@@ -2438,9 +2437,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, ')');
@@ -2467,8 +2465,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;
@@ -2529,9 +2527,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");
 				}
@@ -2635,11 +2633,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;
@@ -2975,8 +2976,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;
@@ -3075,8 +3076,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
@@ -3418,7 +3418,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)
 		{
@@ -5402,8 +5402,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 ");
@@ -5791,21 +5790,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, ')');
 		}
@@ -5834,43 +5830,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 *sep = "";
 
 			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, sep, strVal(lfirst(lc)), NULL);
+				sep = ", ";
 			}
 
-			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);
@@ -5886,7 +5874,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 = ", ";
@@ -6022,9 +6010,7 @@ get_select_query_def(Query *query, deparse_context *context)
 					break;
 			}
 
-			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)
@@ -6317,7 +6303,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 */
@@ -6391,19 +6377,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;
 			}
 		}
@@ -6771,7 +6754,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);
 
@@ -6794,7 +6777,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 */
@@ -7021,10 +7004,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
@@ -7117,8 +7098,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)
@@ -7320,10 +7300,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
@@ -7511,10 +7488,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));
@@ -7573,8 +7550,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, ", ");
@@ -7865,11 +7842,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, '*');
@@ -8806,11 +8783,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;
 			}
 		}
@@ -9391,7 +9367,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;
@@ -9679,7 +9655,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;
 
@@ -10131,8 +10107,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)
@@ -10152,8 +10128,8 @@ get_rule_expr(Node *node, deparse_context *context,
 						if (needcomma)
 							appendStringInfoString(buf, ", ");
 						get_rule_expr((Node *) 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)
@@ -10369,8 +10345,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);
@@ -10604,8 +10580,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);
 					}
 				}
 
@@ -11135,7 +11111,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;
@@ -11161,7 +11137,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;
 				}
 			}
@@ -12001,8 +11977,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
 			{
@@ -12088,7 +12064,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))
@@ -12231,7 +12207,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)
 	{
@@ -12255,9 +12231,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))
@@ -12533,7 +12507,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);
@@ -12620,7 +12594,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 */
@@ -12628,17 +12602,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)
 		{
@@ -12668,9 +12638,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);
 		}
 	}
@@ -12745,9 +12715,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);
 }
 
 /*
@@ -12777,7 +12747,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, ')');
@@ -12910,13 +12880,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);
@@ -12980,7 +12948,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
@@ -13535,7 +13503,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);
@@ -13641,8 +13609,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);
 }
@@ -13739,12 +13706,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;
@@ -13765,9 +13732,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.39.5 (Apple Git-154)

