From 81d55a818799816c45782afa86b6c8b4e23a2fbe Mon Sep 17 00:00:00 2001
From: Nazir Bilal Yavuz <byavuz81@gmail.com>
Date: Tue, 21 Jul 2026 17:42:06 +0300
Subject: [PATCH v2] Add PG_TEST_SERVER_POSTGRES_OPTS to inject server GUCs in
 tests

Unlike PG_TEST_INITDB_EXTRA_OPTS, this only appends name=value settings
to postgresql.conf without disabling the initdb template mechanism.
This speeds up CI, which sets such options in most jobs and previously
paid the full initdb cost per test cluster.
---
 .github/workflows/pg-ci.yml              | 16 ++++++++--------
 doc/src/sgml/regress.sgml                | 10 ++++++++++
 src/test/perl/PostgreSQL/Test/Cluster.pm | 18 ++++++++++++++++++
 src/test/regress/pg_regress.c            | 24 ++++++++++++++++++++++++
 4 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/.github/workflows/pg-ci.yml b/.github/workflows/pg-ci.yml
index a2629c8335a..88c12c3b35f 100644
--- a/.github/workflows/pg-ci.yml
+++ b/.github/workflows/pg-ci.yml
@@ -488,7 +488,7 @@ jobs:
           echo "CXX=${CXX}" >> "$GITHUB_ENV"
 
           echo "PG_TEST_PG_UPGRADE_MODE=${PG_TEST_PG_UPGRADE_MODE}" >> "$GITHUB_ENV"
-          echo "PG_TEST_INITDB_EXTRA_OPTS=${PG_TEST_INITDB_EXTRA_OPTS}" >> "$GITHUB_ENV"
+          echo "PG_TEST_SERVER_POSTGRES_OPTS=${PG_TEST_SERVER_POSTGRES_OPTS}" >> "$GITHUB_ENV"
           echo "PG_TEST_PG_COMBINEBACKUP_MODE=${PG_TEST_PG_COMBINEBACKUP_MODE}" >> "$GITHUB_ENV"
 
       - *nix_sysinfo_step
@@ -548,7 +548,7 @@ jobs:
       - name: Update Environment
         env:
           SANITIZER_FLAGS: -fsanitize=alignment,undefined
-          PG_TEST_INITDB_EXTRA_OPTS: -c io_method=io_uring
+          PG_TEST_SERVER_POSTGRES_OPTS: io_method=io_uring
           CC: ccache gcc -m32
           CXX: ccache g++ -m32
         run: *linux_update_config_cmd
@@ -640,7 +640,7 @@ jobs:
       - name: Update Environment
         env:
           SANITIZER_FLAGS: -fsanitize=address
-          PG_TEST_INITDB_EXTRA_OPTS: -c io_method=io_uring
+          PG_TEST_SERVER_POSTGRES_OPTS: io_method=io_uring
         run: *linux_update_config_cmd
 
       - *nix_sysinfo_step
@@ -724,11 +724,11 @@ jobs:
       # Several buildfarm animals enable these options. Without testing them
       # during CI, it would be easy to cause breakage on the buildfarm with CI
       # passing.
-      PG_TEST_INITDB_EXTRA_OPTS: >-
-        -c debug_copy_parse_plan_trees=on
-        -c debug_write_read_parse_plan_trees=on
-        -c debug_raw_expression_coverage_test=on
-        -c debug_parallel_query=regress
+      PG_TEST_SERVER_POSTGRES_OPTS: >-
+        debug_copy_parse_plan_trees=on
+        debug_write_read_parse_plan_trees=on
+        debug_raw_expression_coverage_test=on
+        debug_parallel_query=regress
 
     steps:
       - *nix_sysinfo_step
diff --git a/doc/src/sgml/regress.sgml b/doc/src/sgml/regress.sgml
index c74941bfbf2..be121a4ab90 100644
--- a/doc/src/sgml/regress.sgml
+++ b/doc/src/sgml/regress.sgml
@@ -554,6 +554,16 @@ make check PG_TEST_INITDB_EXTRA_OPTS='-k --wal-segsize=4 -c work_mem=50MB'
 </screen>
    </para>
 
+   <para>
+    Run-time server settings can be added to the
+    <filename>postgresql.conf</filename> using the environment variable
+    <envar>PG_TEST_SERVER_POSTGRES_OPTS</envar>.  The settings are given as
+    whitespace-separated <literal>name=value</literal> pairs.  For example:
+<screen>
+make check PG_TEST_SERVER_POSTGRES_OPTS='work_mem=50MB debug_discard_caches=1'
+</screen>
+   </para>
+
    <para>
     For the core regression test suite and other tests driven by
     <command>pg_regress</command>, custom run-time server settings can also be
diff --git a/src/test/perl/PostgreSQL/Test/Cluster.pm b/src/test/perl/PostgreSQL/Test/Cluster.pm
index 3eae4cf6281..7a29cb84efc 100644
--- a/src/test/perl/PostgreSQL/Test/Cluster.pm
+++ b/src/test/perl/PostgreSQL/Test/Cluster.pm
@@ -749,6 +749,24 @@ sub init
 		print $conf "max_wal_senders = 0\n";
 	}
 
+	# PG_TEST_SERVER_POSTGRES_OPTS allows adding server settings via an
+	# environment variable.  Unlike PG_TEST_INITDB_EXTRA_OPTS, it does not
+	# disable the initdb template mechanism, as the options are only added to
+	# postgresql.conf and not passed to initdb.  The options are given as
+	# whitespace-separated "name=value" pairs.
+	#
+	# There's very similar code in pg_regress.c.
+	my $server_opts_env = $ENV{PG_TEST_SERVER_POSTGRES_OPTS};
+	if (defined $server_opts_env)
+	{
+		print $conf "# options from PG_TEST_SERVER_POSTGRES_OPTS\n";
+		foreach my $opt (split(/\s+/, $server_opts_env))
+		{
+			print $conf "$opt\n" if $opt ne '';
+		}
+		print $conf "# end of options from PG_TEST_SERVER_POSTGRES_OPTS\n";
+	}
+
 	print $conf "port = $port\n";
 	if ($use_tcp)
 	{
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index 21d00f792d2..d6c1521bfaf 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -2372,6 +2372,7 @@ regression_main(int argc, char *argv[],
 		const char *values[4];
 		PGPing		rv;
 		const char *initdb_extra_opts_env;
+		const char *server_opts_env;
 
 		/*
 		 * Prepare the temp instance
@@ -2500,6 +2501,29 @@ regression_main(int argc, char *argv[],
 			fclose(extra_conf);
 		}
 
+		/*
+		 * PG_TEST_SERVER_POSTGRES_OPTS allows adding server settings via an
+		 * environment variable.  Unlike PG_TEST_INITDB_EXTRA_OPTS, it does
+		 * not disable the initdb template mechanism, as the options are only
+		 * added to postgresql.conf and not passed to initdb.  The options are
+		 * given as whitespace-separated "name=value" pairs.
+		 *
+		 * There's very similar code in Cluster.pm.
+		 */
+		server_opts_env = getenv("PG_TEST_SERVER_POSTGRES_OPTS");
+		if (server_opts_env != NULL)
+		{
+			char	   *opts = pg_strdup(server_opts_env);
+			char	   *tok;
+
+			fputs("# options from PG_TEST_SERVER_POSTGRES_OPTS\n", pg_conf);
+			for (tok = strtok(opts, " \t\n"); tok != NULL;
+				 tok = strtok(NULL, " \t\n"))
+				fprintf(pg_conf, "%s\n", tok);
+			free(opts);
+			fputs("# end of options from PG_TEST_SERVER_POSTGRES_OPTS\n", pg_conf);
+		}
+
 		fclose(pg_conf);
 
 #ifdef ENABLE_SSPI
-- 
2.47.3

