From 088520d9550a5dbb98c91381d1a489f02839d64d Mon Sep 17 00:00:00 2001
From: Anton Chumak <A.M.Chumak@yandex.com>
Date: Mon, 8 Sep 2025 10:10:10 +0700
Subject: [PATCH] added guc option for test purposes

The test_composite option has been added and the corresponding global variable
testComposite of type struct TestComposite has been added to the guc.h and
guc.c files. This option contains all possible atomic data types, it also
contains static and dynamic arrays. Using her example, you can understand how
to work with composite options and test the behavior of the new GUC module.
---
 contrib/test_guc/Makefile                     |  18 ++
 contrib/test_guc/test_guc--1.0.sql            |   0
 contrib/test_guc/test_guc.c                   | 119 ++++++++++
 contrib/test_guc/test_guc.control             |   5 +
 src/backend/replication/slot.c                |   3 +
 src/backend/replication/syncrep.c             |   3 +
 src/backend/utils/error/elog.c                |   2 +
 src/backend/utils/init/miscinit.c             |   3 +
 src/backend/utils/misc/guc.c                  |   1 -
 src/backend/utils/misc/guc_parameters.dat     |  28 +++
 src/backend/utils/misc/guc_tables.c           |   8 +
 src/backend/utils/misc/postgresql.conf.sample |   5 +
 src/include/miscadmin.h                       |   9 +
 src/include/replication/slot.h                |  10 +
 src/include/replication/syncrep.h             |  15 ++
 src/include/utils/elog.h                      |   2 +
 src/include/utils/guc.h                       |   1 +
 src/test/modules/test_misc/meson.build        |   1 +
 .../test_misc/t/009_test_guc_composite.pl     |  49 +++++
 src/test/regress/expected/guc_composite.out   | 203 ++++++++++++++++++
 src/test/regress/parallel_schedule            |   2 +-
 src/test/regress/sql/guc_composite.sql        |  55 +++++
 22 files changed, 540 insertions(+), 2 deletions(-)
 create mode 100644 contrib/test_guc/Makefile
 create mode 100644 contrib/test_guc/test_guc--1.0.sql
 create mode 100644 contrib/test_guc/test_guc.c
 create mode 100644 contrib/test_guc/test_guc.control
 create mode 100644 src/test/modules/test_misc/t/009_test_guc_composite.pl
 create mode 100644 src/test/regress/expected/guc_composite.out
 create mode 100644 src/test/regress/sql/guc_composite.sql

diff --git a/contrib/test_guc/Makefile b/contrib/test_guc/Makefile
new file mode 100644
index 0000000000..6e844776c6
--- /dev/null
+++ b/contrib/test_guc/Makefile
@@ -0,0 +1,18 @@
+# contrib/test_guc/Makefile
+MODULE_big = test_guc
+OBJS = \
+	$(WIN32RES) \
+	test_guc.o
+EXTENSION = test_guc
+DATA = test_guc--1.0.sql
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = contrib/test_guc
+top_builddir = ../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
\ No newline at end of file
diff --git a/contrib/test_guc/test_guc--1.0.sql b/contrib/test_guc/test_guc--1.0.sql
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/contrib/test_guc/test_guc.c b/contrib/test_guc/test_guc.c
new file mode 100644
index 0000000000..66d18b47e5
--- /dev/null
+++ b/contrib/test_guc/test_guc.c
@@ -0,0 +1,119 @@
+#include "postgres.h"
+#include "fmgr.h"
+#include "utils/guc.h"
+#include "utils/guc_tables.h"
+#include "utils/elog.h"
+#include "string.h"
+
+PG_MODULE_MAGIC;
+
+struct LogLevel
+{
+    char *name;
+    int level;
+};
+
+struct LogLevel logLevelsMapping[5];
+struct LogLevel logLevelsMappingBoot[5];
+
+
+struct NodeConfig
+{
+	char *name;
+	char *ip;
+	int port;
+	int max_connections;
+	bool enable_connections;
+};
+
+struct NodeArray
+{
+	struct NodeConfig *data;
+	int size;
+};
+
+struct ClusterConfig
+{
+	char *name;
+	char *leader;
+	struct NodeArray nodes;
+};
+
+struct ClusterConfig clusterConfig;
+struct ClusterConfig clusterConfigBoot;
+
+
+bool validateCluster(void *newValue, void **extra, GucSource source);
+
+void _PG_init(void);
+
+void
+_PG_init(void)
+{
+    DefineCustomCompositeType("ext.loglevelmap", "string name; int level");
+
+    DefineCustomCompositeVariable("ext.loglevels",
+							"Mapping between level names and values",
+							NULL,
+                            "ext.loglevelmap[5]",
+							&logLevelsMapping,
+							&logLevelsMappingBoot,
+							PGC_USERSET,
+							0,
+							NULL,
+							NULL,
+							NULL);
+
+
+
+	DefineCustomCompositeType("ext.nodeConfig", "string name; string ip; int port; int max_connections; bool enable_connections");
+	DefineCustomCompositeType("ext.clusterConfig", "string name; string leader; ext.nodeConfig[] nodes");
+
+	DefineCustomCompositeVariable("ext.cluster",
+							"Example of multi-level structure",
+							NULL,
+                            "ext.clusterConfig",
+							&clusterConfig,
+							&clusterConfigBoot,
+							PGC_USERSET,
+							0,
+							&validateCluster,
+							NULL,
+							NULL);
+
+
+	MarkGUCPrefixReserved("ext");
+}
+
+
+bool
+validateCluster(void *newValueRaw, void **extra, GucSource source)
+{
+	struct ClusterConfig *newValue = (struct ClusterConfig *)newValueRaw;
+	bool found_leader = false;
+	int  max_connections = 0;
+
+	if (newValue->name == NULL)
+		return true;
+
+	for (int i = 0; i < newValue->nodes.size; i++)
+	{
+		if (strcmp(newValue->leader, newValue->nodes.data[i].name) == 0)
+		{
+			found_leader = true;
+			max_connections = newValue->nodes.data[i].max_connections;
+			break;
+		}
+	}
+
+	if (!found_leader)
+		return false;
+
+	for (int i = 0; i < newValue->nodes.size; i++)
+	{
+		if (newValue->nodes.data[i].max_connections > max_connections)
+			return false;
+	}
+
+	return true;
+}
\ No newline at end of file
diff --git a/contrib/test_guc/test_guc.control b/contrib/test_guc/test_guc.control
new file mode 100644
index 0000000000..17f1864d38
--- /dev/null
+++ b/contrib/test_guc/test_guc.control
@@ -0,0 +1,5 @@
+# test_guc extension
+comment = 'Simple GUC extension with composite parameters'
+default_version = '1.0'
+module_pathname = '$libdir/test_guc'
+relocatable = true
\ No newline at end of file
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index fd0fdb96d4..61c00c0826 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -163,6 +163,9 @@ int			idle_replication_slot_timeout_secs = 0;
  */
 char	   *synchronized_standby_slots;
 
+struct ReplicaConfig replicaConfig;
+struct ReplicaConfig replicaConfigBoot;
+
 /* This is the parsed and cached configuration for synchronized_standby_slots */
 static SyncStandbySlotsConfigData *synchronized_standby_slots_config;
 
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index 32cf3a48b8..c45426afbb 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -89,6 +89,9 @@
 /* User-settable parameters for sync rep */
 char	   *SyncRepStandbyNames;
 
+struct SSNType ssn;
+struct SSNType ssnBoot;
+
 #define SyncStandbysDefined() \
 	(SyncRepStandbyNames != NULL && SyncRepStandbyNames[0] != '\0')
 
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index b7b9692f8c..d7c8c08617 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -112,6 +112,8 @@ int			Log_destination = LOG_DESTINATION_STDERR;
 char	   *Log_destination_string = NULL;
 bool		syslog_sequence_numbers = true;
 bool		syslog_split_messages = true;
+char *logLevelNames[5];
+char *logLevelNamesBoot[5] = {"TRACE","LOG","WARNING","ERROR","FATAL"};
 
 /* Processed form of backtrace_functions GUC */
 static char *backtrace_function_list;
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 545d1e90fb..e1c515b903 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -1833,6 +1833,9 @@ char	   *session_preload_libraries_string = NULL;
 char	   *shared_preload_libraries_string = NULL;
 char	   *local_preload_libraries_string = NULL;
 
+struct ShrLibArr sharedLibs;
+struct ShrLibArr sharedLibsBoot;
+
 /* Flag telling that we are loading shared_preload_libraries */
 bool		process_shared_preload_libraries_in_progress = false;
 bool		process_shared_preload_libraries_done = false;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index eac986a1c7..de1b278d97 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -81,7 +81,6 @@ char	   *GUC_check_errmsg_string;
 char	   *GUC_check_errdetail_string;
 char	   *GUC_check_errhint_string;
 
-
 /*
  * Unit conversion tables.
  *
diff --git a/src/backend/utils/misc/guc_parameters.dat b/src/backend/utils/misc/guc_parameters.dat
index c392d00972..c8409a5e9c 100644
--- a/src/backend/utils/misc/guc_parameters.dat
+++ b/src/backend/utils/misc/guc_parameters.dat
@@ -3481,4 +3481,32 @@
   assign_hook => 'assign_io_method',
 },
 
+{ name => 'replica', type => 'composite', context => 'PGC_USERSET', group => 'REPLICATION_PRIMARY',
+  short_desc => 'config of replica',
+  type_name => 'ReplicaConfigType',
+  variable => 'replicaConfig',
+  boot_val => '&replicaConfigBoot',
+},
+
+{ name => 'shared_preload_libraries_list',type => 'composite', context => 'PGC_USERSET', group => 'CLIENT_CONN_PRELOAD',
+  short_desc => 'list of shared preloaded libraries',
+  type_name => 'string[]',
+  variable => 'sharedLibs',
+  boot_val => '&sharedLibsBoot',
+},
+
+{ name => 'ssn', type => 'composite', context => 'PGC_USERSET', group => 'REPLICATION_PRIMARY',
+  short_desc => 'new synchronous_standby_names',
+  type_name => 'SSNType',
+  variable => 'ssn',
+  boot_val => '&ssnBoot',
+},
+
+{ name => 'log_level_names', type => 'composite', context => 'PGC_USERSET', group => 'LOGGING_WHAT',
+  short_desc => 'array of names for 5 log levels',
+  type_name => 'string[5]',
+  variable => 'logLevelNames',
+  boot_val => '&logLevelNamesBoot',
+},
+
 ]
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index c45be54f3e..2a60b9ae13 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -817,6 +817,14 @@ struct type_definition UserDefinedConfigureTypes[] = {
 		sizeof(char *),
 		NULL
 	},
+	{
+		"ReplicaConfigType",
+		"bool enable_connections; int max_delay; int max_slot_size"
+	},
+	{
+		"SSNType",
+		"string mode; int threshold; string[] names"
+	},
 	/* End-of-list marker */
 	{
 		NULL, NULL
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index c36fcb9ab6..cd508abb5d 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -882,4 +882,9 @@ autovacuum_worker_slots = 16	# autovacuum worker slots to allocate
 # CUSTOMIZED OPTIONS
 #------------------------------------------------------------------------------
 
+#replica = {}
+#shared_preload_libraries_list = []
+#ssn = {}
+#log_level_names = []
+
 # Add settings for extensions here
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 1bef98471c..01bab98f39 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -516,6 +516,15 @@ extern PGDLLIMPORT char *session_preload_libraries_string;
 extern PGDLLIMPORT char *shared_preload_libraries_string;
 extern PGDLLIMPORT char *local_preload_libraries_string;
 
+struct ShrLibArr
+{
+	char **libs;
+	int size;
+};
+
+extern PGDLLIMPORT struct ShrLibArr sharedLibs;
+extern PGDLLIMPORT struct ShrLibArr sharedLibsBoot;
+
 extern void CreateDataDirLockFile(bool amPostmaster);
 extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster,
 								 const char *socketDir);
diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h
index fe62162cde..7735fbd058 100644
--- a/src/include/replication/slot.h
+++ b/src/include/replication/slot.h
@@ -294,6 +294,16 @@ extern PGDLLIMPORT int max_replication_slots;
 extern PGDLLIMPORT char *synchronized_standby_slots;
 extern PGDLLIMPORT int idle_replication_slot_timeout_secs;
 
+struct ReplicaConfig
+{
+	bool enable_connections;
+	int max_delay;
+	int max_slots_size;
+};
+
+extern PGDLLIMPORT struct ReplicaConfig replicaConfig;
+extern PGDLLIMPORT struct ReplicaConfig replicaConfigBoot;
+
 /* shmem initialization functions */
 extern Size ReplicationSlotsShmemSize(void);
 extern void ReplicationSlotsShmemInit(void);
diff --git a/src/include/replication/syncrep.h b/src/include/replication/syncrep.h
index dc2b118b16..6d323264bd 100644
--- a/src/include/replication/syncrep.h
+++ b/src/include/replication/syncrep.h
@@ -76,6 +76,21 @@ extern PGDLLIMPORT SyncRepConfigData *SyncRepConfig;
 /* user-settable parameters for synchronous replication */
 extern PGDLLIMPORT char *SyncRepStandbyNames;
 
+struct DynArrStr
+{
+	char **data;
+	int size;
+};
+struct SSNType
+{
+	char *mode;
+	int threshold;
+	struct DynArrStr names;
+};
+
+extern PGDLLIMPORT struct SSNType ssn;
+extern PGDLLIMPORT struct SSNType ssnBoot;
+
 /* called by user backend */
 extern void SyncRepWaitForLSN(XLogRecPtr lsn, bool commit);
 
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index 675f4f5f46..2ee3eca956 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -493,6 +493,8 @@ extern PGDLLIMPORT int Log_destination;
 extern PGDLLIMPORT char *Log_destination_string;
 extern PGDLLIMPORT bool syslog_sequence_numbers;
 extern PGDLLIMPORT bool syslog_split_messages;
+extern PGDLLIMPORT char *logLevelNames[5];
+extern PGDLLIMPORT char *logLevelNamesBoot[5];
 
 /* Log destination bitmap */
 #define LOG_DESTINATION_STDERR	 1
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index b197a81f28..2b8928439d 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -199,6 +199,7 @@ typedef const char *(*GucShowHook) (void);
 /*
  * Miscellaneous
  */
+
 typedef enum
 {
 	/* Types of set_config_option actions */
diff --git a/src/test/modules/test_misc/meson.build b/src/test/modules/test_misc/meson.build
index 6b1e730bf4..31e2341f19 100644
--- a/src/test/modules/test_misc/meson.build
+++ b/src/test/modules/test_misc/meson.build
@@ -17,6 +17,7 @@ tests += {
       't/006_signal_autovacuum.pl',
       't/007_catcache_inval.pl',
       't/008_replslot_single_user.pl',
+      't/009_test_guc_composite.pl',
     ],
   },
 }
diff --git a/src/test/modules/test_misc/t/009_test_guc_composite.pl b/src/test/modules/test_misc/t/009_test_guc_composite.pl
new file mode 100644
index 0000000000..58b1cbc91c
--- /dev/null
+++ b/src/test/modules/test_misc/t/009_test_guc_composite.pl
@@ -0,0 +1,49 @@
+# Copyright (c) 2024-2025, PostgreSQL Global Development Group
+
+# Tests composite GUC parameters
+
+use strict;
+use warnings FATAL => 'all';
+use PostgreSQL::Test::Cluster;
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+my $node = PostgreSQL::Test::Cluster->new('main');
+$node->init;
+$node->start;
+
+# Test ALTER SYSTEM command:
+# ALTER SYSTEM must only write changed parameter in .auto.conf file
+$node->safe_psql(
+    'postgres',
+    "ALTER SYSTEM SET replica->max_delay = 42"
+);
+
+# Check postgresql.auto.conf
+my $auto_conf_path = $node->data_dir . '/postgresql.auto.conf';
+my $expected_line = "replica = {enable_connections: \'false\', max_delay: \'42\', max_slot_size: \'0\'}";
+my $found = 0;
+open(my $fh, '<', $auto_conf_path) or die "Cannot open file: $!";
+while (my $line = <$fh>) {
+    chomp $line;
+    if ($line =~ /^\s*\Q$expected_line\E\s*$/) {
+        $found = 1;
+        last;
+    }
+}
+close($fh);
+
+ok($found, 'Composite parameter setting found in postgresql.auto.conf');
+
+#reload config
+$node->safe_psql('postgres', 'SELECT pg_reload_conf()');
+
+# Check that parameter was applied
+my $current_value = $node->safe_psql(
+    'postgres',
+    "SHOW replica->max_delay"
+);
+
+is($current_value, '42', 'Composite parameter value is correctly set');
+
+done_testing();
diff --git a/src/test/regress/expected/guc_composite.out b/src/test/regress/expected/guc_composite.out
new file mode 100644
index 0000000000..0eafceed60
--- /dev/null
+++ b/src/test/regress/expected/guc_composite.out
@@ -0,0 +1,203 @@
+-- STRUCT
+SHOW replica;
+              replica               
+------------------------------------
+ {                                 +
+         enable_connections: false,+
+         max_delay: 0,             +
+         max_slot_size: 0          +
+ }
+(1 row)
+
+SET replica->max_delay to 42;
+SHOW replica->max_delay;
+ replica 
+---------
+ 42
+(1 row)
+
+SET replica to {enable_connections: true, max_slot_size: 10};
+SHOW replica;
+              replica              
+-----------------------------------
+ {                                +
+         enable_connections: true,+
+         max_delay: 42,           +
+         max_slot_size: 10        +
+ }
+(1 row)
+
+SET replica->invalid_field to 4;
+ERROR:  invalid value for parameter "replica": "{invalid_field: '4'}"
+HINT:  incorrect field name at or near ":"
+-- STATIC ARRAY
+SHOW log_level_names;
+  log_level_names   
+--------------------
+ [                 +
+         'TRACE',  +
+         'LOG',    +
+         'WARNING',+
+         'ERROR',  +
+         'FATAL'   +
+ ]
+(1 row)
+
+SET log_level_names[0] to 'DEBUG';
+SHOW log_level_names[0];
+ log_level_names 
+-----------------
+ 'DEBUG'
+(1 row)
+
+SET log_level_names[10] to 'EXTRA';
+ERROR:  invalid value for parameter "log_level_names": "[10: 'EXTRA']"
+HINT:  there is index which is greater than size of array at or near ":"
+SET log_level_names[-1] to 'EXTRA';
+ERROR:  syntax error at or near "-"
+LINE 1: SET log_level_names[-1] to 'EXTRA';
+                            ^
+-- DYNAMIC ARRAY
+SHOW shared_preload_libraries_list;
+ shared_preload_libraries_list 
+-------------------------------
+ [                            +
+ ]
+(1 row)
+
+SET shared_preload_libraries_list[0] to 'yet_another_ext';
+SHOW shared_preload_libraries_list->data[0];
+ shared_preload_libraries_list 
+-------------------------------
+ 'yet_another_ext'
+(1 row)
+
+SET extended_guc_arrays to true;
+SHOW shared_preload_libraries_list;
+   shared_preload_libraries_list   
+-----------------------------------
+ {                                +
+         size: 1,                 +
+         data: [                  +
+                 'yet_another_ext'+
+         ]                        +
+ }
+(1 row)
+
+SET shared_preload_libraries_list->size to 2;
+SHOW shared_preload_libraries_list;
+   shared_preload_libraries_list    
+------------------------------------
+ {                                 +
+         size: 2,                  +
+         data: [                   +
+                 'yet_another_ext',+
+                 nil               +
+         ]                         +
+ }
+(1 row)
+
+SET shared_preload_libraries_list to {size: 2, data: [3: 'third_ext']};
+ERROR:  invalid value for parameter "shared_preload_libraries_list": "{size: 2, data: [3: 'third_ext']}"
+HINT:  there is index greater than array length.								Change "size" field at or near "'third_ext'"
+SET extended_guc_arrays to false;
+-- CHECK GUC STACK
+SHOW replica;
+              replica              
+-----------------------------------
+ {                                +
+         enable_connections: true,+
+         max_delay: 42,           +
+         max_slot_size: 10        +
+ }
+(1 row)
+
+BEGIN;
+SET replica->max_delay to 6;
+SHOW replica;
+              replica              
+-----------------------------------
+ {                                +
+         enable_connections: true,+
+         max_delay: 6,            +
+         max_slot_size: 10        +
+ }
+(1 row)
+
+COMMIT;
+SHOW replica;
+              replica              
+-----------------------------------
+ {                                +
+         enable_connections: true,+
+         max_delay: 6,            +
+         max_slot_size: 10        +
+ }
+(1 row)
+
+SHOW replica;
+              replica              
+-----------------------------------
+ {                                +
+         enable_connections: true,+
+         max_delay: 6,            +
+         max_slot_size: 10        +
+ }
+(1 row)
+
+BEGIN;
+SET replica->max_delay to 28;
+SHOW replica;
+              replica              
+-----------------------------------
+ {                                +
+         enable_connections: true,+
+         max_delay: 28,           +
+         max_slot_size: 10        +
+ }
+(1 row)
+
+ABORT;
+SHOW replica;
+              replica              
+-----------------------------------
+ {                                +
+         enable_connections: true,+
+         max_delay: 6,            +
+         max_slot_size: 10        +
+ }
+(1 row)
+
+SHOW replica;
+              replica              
+-----------------------------------
+ {                                +
+         enable_connections: true,+
+         max_delay: 6,            +
+         max_slot_size: 10        +
+ }
+(1 row)
+
+BEGIN;
+SET LOCAL replica->max_delay to 28;
+SHOW replica;
+              replica              
+-----------------------------------
+ {                                +
+         enable_connections: true,+
+         max_delay: 28,           +
+         max_slot_size: 10        +
+ }
+(1 row)
+
+COMMIT;
+SHOW replica;
+              replica              
+-----------------------------------
+ {                                +
+         enable_connections: true,+
+         max_delay: 6,            +
+         max_slot_size: 10        +
+ }
+(1 row)
+
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index fbffc67ae6..d6d41bbccc 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -102,7 +102,7 @@ test: publication subscription
 # Another group of parallel tests
 # select_views depends on create_view
 # ----------
-test: select_views portals_p2 foreign_key cluster dependency guc bitmapops combocid tsearch tsdicts foreign_data window xmlmap functional_deps advisory_lock indirect_toast equivclass
+test: select_views portals_p2 foreign_key cluster dependency guc_composite guc bitmapops combocid tsearch tsdicts foreign_data window xmlmap functional_deps advisory_lock indirect_toast equivclass
 
 # ----------
 # Another group of parallel tests (JSON related)
diff --git a/src/test/regress/sql/guc_composite.sql b/src/test/regress/sql/guc_composite.sql
new file mode 100644
index 0000000000..338cc8692c
--- /dev/null
+++ b/src/test/regress/sql/guc_composite.sql
@@ -0,0 +1,55 @@
+-- STRUCT
+SHOW replica;
+
+SET replica->max_delay to 42;
+SHOW replica->max_delay;
+
+SET replica to {enable_connections: true, max_slot_size: 10};
+SHOW replica;
+SET replica->invalid_field to 4;
+
+-- STATIC ARRAY
+SHOW log_level_names;
+SET log_level_names[0] to 'DEBUG';
+SHOW log_level_names[0];
+SET log_level_names[10] to 'EXTRA';
+SET log_level_names[-1] to 'EXTRA';
+
+-- DYNAMIC ARRAY
+
+SHOW shared_preload_libraries_list;
+
+SET shared_preload_libraries_list[0] to 'yet_another_ext';
+SHOW shared_preload_libraries_list->data[0];
+
+SET extended_guc_arrays to true;
+SHOW shared_preload_libraries_list;
+
+SET shared_preload_libraries_list->size to 2;
+SHOW shared_preload_libraries_list;
+
+SET shared_preload_libraries_list to {size: 2, data: [3: 'third_ext']};
+SET extended_guc_arrays to false;
+
+-- CHECK GUC STACK
+
+SHOW replica;
+BEGIN;
+SET replica->max_delay to 6;
+SHOW replica;
+COMMIT;
+SHOW replica;
+
+SHOW replica;
+BEGIN;
+SET replica->max_delay to 28;
+SHOW replica;
+ABORT;
+SHOW replica;
+
+SHOW replica;
+BEGIN;
+SET LOCAL replica->max_delay to 28;
+SHOW replica;
+COMMIT;
+SHOW replica;
-- 
2.48.1

