From af7b37d2eff942e4a3a9563a9340fd3d7853e5ba Mon Sep 17 00:00:00 2001 From: Vaibhav Dalvi Date: Tue, 11 Nov 2025 04:58:59 +0000 Subject: [PATCH v4 1/2] Use list of C strings for publications Currently, the structure Subscription has member publications and it is list of String node rather than a list of C strings. Subscription is not a not a node, so this seems wasteful and pointless. This patch tries to get rid of the String node around Subscription->publications. Vaibhav Dalvi --- src/backend/catalog/pg_subscription.c | 15 ++++++++----- src/backend/commands/subscriptioncmds.c | 21 +++++++++++++++---- .../libpqwalreceiver/libpqwalreceiver.c | 4 ++-- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c index 1945627ed88..09e9dc98167 100644 --- a/src/backend/catalog/pg_subscription.c +++ b/src/backend/catalog/pg_subscription.c @@ -32,7 +32,7 @@ #include "utils/rel.h" #include "utils/syscache.h" -static List *textarray_to_stringlist(ArrayType *textarray); +static List *textarray_to_cstringlist(ArrayType *textarray); /* * Add a comma-separated list of publication names to the 'dest' string. @@ -47,7 +47,12 @@ GetPublicationsStr(List *publications, StringInfo dest, bool quote_literal) foreach(lc, publications) { - char *pubname = strVal(lfirst(lc)); + char *pubname; + + if (IsA((Node *) lfirst(lc), String)) + pubname = strVal(lfirst(lc)); + else + pubname = (char *) lfirst(lc); if (first) first = false; @@ -133,7 +138,7 @@ GetSubscription(Oid subid, bool missing_ok) datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID, tup, Anum_pg_subscription_subpublications); - sub->publications = textarray_to_stringlist(DatumGetArrayTypeP(datum)); + sub->publications = textarray_to_cstringlist(DatumGetArrayTypeP(datum)); /* Get origin */ datum = SysCacheGetAttrNotNull(SUBSCRIPTIONOID, @@ -241,7 +246,7 @@ DisableSubscription(Oid subid) * Note: the resulting list of strings is pallocated here. */ static List * -textarray_to_stringlist(ArrayType *textarray) +textarray_to_cstringlist(ArrayType *textarray) { Datum *elems; int nelems, @@ -254,7 +259,7 @@ textarray_to_stringlist(ArrayType *textarray) return NIL; for (i = 0; i < nelems; i++) - res = lappend(res, makeString(TextDatumGetCString(elems[i]))); + res = lappend(res, TextDatumGetCString(elems[i])); return res; } diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index 3d29818badd..f55230292a6 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -3043,6 +3043,9 @@ ReportSlotConnectionError(List *rstates, Oid subid, char *slotname, char *err) * Check for duplicates in the given list of publications and error out if * found one. Add publications to datums as text datums, if datums is not * NULL. + * + * Note that publications can be either list of string nodes or list of the + * C strings. */ static void check_duplicates_in_publist(List *publist, Datum *datums) @@ -3052,12 +3055,22 @@ check_duplicates_in_publist(List *publist, Datum *datums) foreach(cell, publist) { - char *name = strVal(lfirst(cell)); + char *name; ListCell *pcell; + if (IsA((Node *) lfirst(cell), String)) + name = strVal(lfirst(cell)); + else + name = (char *) lfirst(cell); + foreach(pcell, publist) { - char *pname = strVal(lfirst(pcell)); + char *pname; + + if (IsA((Node *) lfirst(pcell), String)) + pname = strVal(lfirst(pcell)); + else + pname = (char *) lfirst(pcell); if (pcell == cell) break; @@ -3101,7 +3114,7 @@ merge_publications(List *oldpublist, List *newpublist, bool addpub, const char * foreach(lc2, oldpublist) { - char *pubname = strVal(lfirst(lc2)); + char *pubname = (char *) (lfirst(lc2)); if (strcmp(name, pubname) == 0) { @@ -3119,7 +3132,7 @@ merge_publications(List *oldpublist, List *newpublist, bool addpub, const char * } if (addpub && !found) - oldpublist = lappend(oldpublist, makeString(name)); + oldpublist = lappend(oldpublist, name); else if (!addpub && !found) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c index 239641bfbb6..8b97619db5c 100644 --- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c +++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c @@ -1172,7 +1172,7 @@ libpqrcv_exec(WalReceiverConn *conn, const char *query, } /* - * Given a List of strings, return it as single comma separated + * Given a List of C strings, return it as single comma separated * string, quoting identifiers as needed. * * This is essentially the reverse of SplitIdentifierString. @@ -1190,7 +1190,7 @@ stringlist_to_identifierstr(PGconn *conn, List *strings) foreach(lc, strings) { - char *val = strVal(lfirst(lc)); + char *val = (char *) (lfirst(lc)); char *val_escaped; if (first) -- 2.43.0