From d70aa4c127fbcecb11e61393c17735a1e3473f86 Mon Sep 17 00:00:00 2001
From: Mahendra Singh Thalor <mahi6run@gmail.com>
Date: Mon, 10 Mar 2025 13:55:15 +0530
Subject: [PATCH] enlarge on_exit_nicely_list array whenever no slot left

Earlier we were using fixed size array with the size of MAX_ON_EXIT_NICELY=20
but for pg_restore, we need more slots as we will restore multiple database
by single dump file of pg_dumpall.
Instead of fixed size array, now we will allocate memory dynamically and
if there is no slot, then we will double the previous size.
---
 src/bin/pg_dump/pg_backup_utils.c | 42 +++++++++++++++++++++++++++----
 src/tools/pgindent/typedefs.list  |  1 +
 2 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/src/bin/pg_dump/pg_backup_utils.c b/src/bin/pg_dump/pg_backup_utils.c
index 79aec5f5158..cecec14982d 100644
--- a/src/bin/pg_dump/pg_backup_utils.c
+++ b/src/bin/pg_dump/pg_backup_utils.c
@@ -23,13 +23,16 @@ const char *progname = NULL;
 
 #define MAX_ON_EXIT_NICELY				20
 
-static struct
+typedef struct on_exit_nicely_item
 {
 	on_exit_nicely_callback function;
 	void	   *arg;
-}			on_exit_nicely_list[MAX_ON_EXIT_NICELY];
+} on_exit_nicely_item;
 
-static int	on_exit_nicely_index;
+static on_exit_nicely_item *on_exit_nicely_list = NULL;
+static int on_exit_nicely_index;
+static int max_on_exit_nicely_list;
+static void EnlargeExitNicelyArray(void);
 
 /*
  * Parse a --section=foo command line argument.
@@ -59,13 +62,42 @@ set_dump_section(const char *arg, int *dumpSections)
 	}
 }
 
+/*
+ * EnlargeExitNicelyArray
+ *
+ * Enlarges the array size, if required.  If first time, we allocate the memory
+ * using malloc.
+ */
+static void
+EnlargeExitNicelyArray(void)
+{
+	/* If array has space for 1 entry, then return from here. */
+	if (on_exit_nicely_index < max_on_exit_nicely_list)
+		return;
+
+	/* Double the capacity of the array. */
+	max_on_exit_nicely_list = (max_on_exit_nicely_list > 0) ? max_on_exit_nicely_list * 2 : MAX_ON_EXIT_NICELY;
+
+	/* If array is pointing to NULL, then allocate memory for fixed size. */
+	if (!on_exit_nicely_list)
+		on_exit_nicely_list = (on_exit_nicely_item *) pg_malloc0(max_on_exit_nicely_list * sizeof(on_exit_nicely_item));
+	else
+	{
+		/*
+		 * As array already have some memory so instead of alloc, using
+		 * repalloc so that all old data of array will be copied into new
+		 * allocated memory.
+		 */
+		on_exit_nicely_list = (on_exit_nicely_item *) pg_realloc(on_exit_nicely_list,
+				max_on_exit_nicely_list * sizeof(on_exit_nicely_item));
+	}
+}
 
 /* Register a callback to be run when exit_nicely is invoked. */
 void
 on_exit_nicely(on_exit_nicely_callback function, void *arg)
 {
-	if (on_exit_nicely_index >= MAX_ON_EXIT_NICELY)
-		pg_fatal("out of on_exit_nicely slots");
+	EnlargeExitNicelyArray();
 	on_exit_nicely_list[on_exit_nicely_index].function = function;
 	on_exit_nicely_list[on_exit_nicely_index].arg = arg;
 	on_exit_nicely_index++;
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 9840060997f..da458d1cb6a 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -3724,6 +3724,7 @@ oidKEY
 oidvector
 on_dsm_detach_callback
 on_exit_nicely_callback
+on_exit_nicely_item
 openssl_tls_init_hook_typ
 ossl_EVP_cipher_func
 other
-- 
2.39.3

