From 7ef994fff05dd375dbcb6e4724f569273a47c1b8 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Tue, 30 Dec 2025 16:30:10 -0500
Subject: [PATCH v1 3/4] Adjust pg_dump and pg_dumpall for
 standard_conforming_strings change.

The change needed here is to force standard_conforming_strings = on
in the source server, so that any string literals it emits (while
dumping views, expressions, etc) will be correctly formatted for a
destination server that doesn't support the other setting.  We long
ago dropped support for source servers too old to accept that.

Both programs will always emit "SET standard_conforming_strings = on"
to ensure that the destination server is on board.  While that's a
no-op for v19 and later destinations, there's no reason to break
compatibility with older destinations.

This patch does not change the behavior of pg_restore, which will
continue to use and emit the standard_conforming_strings setting
it finds in the archive file.  An archive with that turned off
will not be safely restorable to >= v19 servers, but there's little
pg_restore can do about that.  We might as well preserve its
functionality of being able to extract data usable by older
destination servers.  (Eventually that functionality will no longer
be of interest to anyone, but I think that day is some ways off.)

Since we're preserving pg_restore's behavior, none of the internal
logic around AH->std_strings changes, and this patch is much
smaller than you might expect.

Author: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/3279216.1767072538@sss.pgh.pa.us
---
 src/bin/pg_dump/pg_dump.c    | 23 +++++++++++++++++------
 src/bin/pg_dump/pg_dumpall.c | 20 ++++++++++----------
 2 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 27f6be3f0f8..053053b8d09 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -1428,7 +1428,6 @@ setup_connection(Archive *AH, const char *dumpencoding,
 {
 	DumpOptions *dopt = AH->dopt;
 	PGconn	   *conn = GetConnection(AH);
-	const char *std_strings;
 
 	PQclear(ExecuteSqlQueryForSingleRow(AH, ALWAYS_SECURE_SEARCH_PATH_SQL));
 
@@ -1443,15 +1442,27 @@ setup_connection(Archive *AH, const char *dumpencoding,
 	}
 
 	/*
-	 * Get the active encoding and the standard_conforming_strings setting, so
-	 * we know how to escape strings.
+	 * Force standard_conforming_strings on, just in case we are dumping from
+	 * an old server that has it disabled.  Without this, literals in views,
+	 * expressions, etc, would be incorrect for modern servers.
+	 */
+	ExecuteSqlStatement(AH, "SET standard_conforming_strings = on");
+
+	/*
+	 * And reflect that to AH->std_strings.  You might think that we should
+	 * just delete that variable and the code that checks it, but that would
+	 * be problematic for pg_restore, which at least for now should still cope
+	 * with archives containing the other setting (cf. processStdStringsEntry
+	 * in pg_backup_archiver.c).
+	 */
+	AH->std_strings = true;
+
+	/*
+	 * Get the active encoding, so we know how to escape strings.
 	 */
 	AH->encoding = PQclientEncoding(conn);
 	setFmtEncoding(AH->encoding);
 
-	std_strings = PQparameterStatus(conn, "standard_conforming_strings");
-	AH->std_strings = (std_strings && strcmp(std_strings, "on") == 0);
-
 	/*
 	 * Set the role if requested.  In a parallel dump worker, we'll be passed
 	 * use_role == NULL, but AH->use_role is already set (if user specified it
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index 8fa04930399..ab435c4f4f5 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -204,7 +204,6 @@ main(int argc, char *argv[])
 	bool		tablespaces_only = false;
 	PGconn	   *conn;
 	int			encoding;
-	const char *std_strings;
 	int			c,
 				ret;
 	int			optindex;
@@ -568,14 +567,17 @@ main(int argc, char *argv[])
 	}
 
 	/*
-	 * Get the active encoding and the standard_conforming_strings setting, so
-	 * we know how to escape strings.
+	 * Force standard_conforming_strings on, just in case we are dumping from
+	 * an old server that has it disabled.  Without this, literals in views,
+	 * expressions, etc, would be incorrect for modern servers.
+	 */
+	executeCommand(conn, "SET standard_conforming_strings = on");
+
+	/*
+	 * Get the active encoding, so we know how to escape strings.
 	 */
 	encoding = PQclientEncoding(conn);
 	setFmtEncoding(encoding);
-	std_strings = PQparameterStatus(conn, "standard_conforming_strings");
-	if (!std_strings)
-		std_strings = "off";
 
 	/* Set the role if requested */
 	if (use_role)
@@ -615,12 +617,10 @@ main(int argc, char *argv[])
 	/* Restore will need to write to the target cluster */
 	fprintf(OPF, "SET default_transaction_read_only = off;\n\n");
 
-	/* Replicate encoding and std_strings in output */
+	/* Replicate encoding and standard_conforming_strings in output */
 	fprintf(OPF, "SET client_encoding = '%s';\n",
 			pg_encoding_to_char(encoding));
-	fprintf(OPF, "SET standard_conforming_strings = %s;\n", std_strings);
-	if (strcmp(std_strings, "off") == 0)
-		fprintf(OPF, "SET escape_string_warning = off;\n");
+	fprintf(OPF, "SET standard_conforming_strings = on;\n");
 	fprintf(OPF, "\n");
 
 	if (!data_only && !statistics_only && !no_schema)
-- 
2.43.7

