v11-0001-Supporting-changes-for-pg_get_tablespace_ddl-fun.patch

text/x-patch

Filename: v11-0001-Supporting-changes-for-pg_get_tablespace_ddl-fun.patch
Type: text/x-patch
Part: 1
Message: Re: [PATCH] Add pg_get_tablespace_ddl() function to reconstruct CREATE TABLESPACE statement
From 40ee6ffe76b987c52a2affda41ba73f6217c0355 Mon Sep 17 00:00:00 2001
From: Nishant Sharma <nishant.sharma@enterprisedb.com>
Date: Wed, 12 Nov 2025 14:24:49 +0530
Subject: [PATCH v11 1/2] Supporting changes for pg_get_tablespace_ddl function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Moving core logic of pg_tablespace_location() to new generic function
get_tablespace_loc_string()

Authors: Manni Wood <manni.wood@enterprisedb.com> and Nishant Sharma
<nishant.sharma@enterprisedb.com>
Reviewers: Vaibhav Dalvi, Ian Barwick, Jim Jones, Álvaro Herrera
Discussion:
https://www.postgresql.org/message-id/flat/CAKWEB6rmnmGKUA87Zmq-s=b3Scsnj02C0kObQjnbL2ajfPWGEw@mail.gmail.com
---
 src/backend/catalog/Makefile        |  1 +
 src/backend/catalog/meson.build     |  1 +
 src/backend/catalog/pg_tablespace.c | 90 +++++++++++++++++++++++++++++
 src/backend/utils/adt/misc.c        | 62 ++------------------
 src/include/catalog/pg_tablespace.h |  2 +
 5 files changed, 98 insertions(+), 58 deletions(-)
 create mode 100644 src/backend/catalog/pg_tablespace.c

diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile
index c090094ed08..8e40e1b8189 100644
--- a/src/backend/catalog/Makefile
+++ b/src/backend/catalog/Makefile
@@ -44,6 +44,7 @@ OBJS = \
 	pg_range.o \
 	pg_shdepend.o \
 	pg_subscription.o \
+	pg_tablespace.o \
 	pg_type.o \
 	storage.o \
 	toasting.o
diff --git a/src/backend/catalog/meson.build b/src/backend/catalog/meson.build
index 1958ea9238a..58674ffeee6 100644
--- a/src/backend/catalog/meson.build
+++ b/src/backend/catalog/meson.build
@@ -31,6 +31,7 @@ backend_sources += files(
   'pg_range.c',
   'pg_shdepend.c',
   'pg_subscription.c',
+  'pg_tablespace.c',
   'pg_type.c',
   'storage.c',
   'toasting.c',
diff --git a/src/backend/catalog/pg_tablespace.c b/src/backend/catalog/pg_tablespace.c
new file mode 100644
index 00000000000..c205b883502
--- /dev/null
+++ b/src/backend/catalog/pg_tablespace.c
@@ -0,0 +1,90 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_tablespace.c
+ *	  routines to support tablespaces
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *	  src/backend/catalog/pg_tablespace.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include "catalog/pg_tablespace.h"
+#include "commands/tablespace.h"
+#include "miscadmin.h"
+
+
+/*
+ * get_tablespace_location
+ *		Get a tablespace's location as a C-string, by its OID
+ */
+char *
+get_tablespace_location(Oid tablespaceOid)
+{
+	char		sourcepath[MAXPGPATH];
+	char		targetpath[MAXPGPATH];
+	int			rllen;
+	struct stat st;
+
+	/*
+	 * It's useful to apply this to pg_class.reltablespace, wherein zero means
+	 * "the database's default tablespace".  So, rather than throwing an error
+	 * for zero, we choose to assume that's what is meant.
+	 */
+	if (tablespaceOid == InvalidOid)
+		tablespaceOid = MyDatabaseTableSpace;
+
+	/*
+	 * Return empty string for the cluster's default tablespaces
+	 */
+	if (tablespaceOid == DEFAULTTABLESPACE_OID ||
+		tablespaceOid == GLOBALTABLESPACE_OID)
+		return pstrdup("");
+
+	/*
+	 * Find the location of the tablespace by reading the symbolic link that
+	 * is in pg_tblspc/<oid>.
+	 */
+	snprintf(sourcepath, sizeof(sourcepath), "%s/%u", PG_TBLSPC_DIR, tablespaceOid);
+
+	/*
+	 * Before reading the link, check if the source path is a link or a
+	 * junction point.  Note that a directory is possible for a tablespace
+	 * created with allow_in_place_tablespaces enabled.  If a directory is
+	 * found, a relative path to the data directory is returned.
+	 */
+	if (lstat(sourcepath, &st) < 0)
+		ereport(ERROR,
+				errcode_for_file_access(),
+				errmsg("could not stat file \"%s\": %m",
+					   sourcepath));
+
+	if (!S_ISLNK(st.st_mode))
+		return pstrdup(sourcepath);
+
+	/*
+	 * In presence of a link or a junction point, return the path pointed to.
+	 */
+	rllen = readlink(sourcepath, targetpath, sizeof(targetpath));
+	if (rllen < 0)
+		ereport(ERROR,
+				errcode_for_file_access(),
+				errmsg("could not read symbolic link \"%s\": %m",
+					   sourcepath));
+	if (rllen >= sizeof(targetpath))
+		ereport(ERROR,
+				errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+				errmsg("symbolic link \"%s\" target is too long",
+					   sourcepath));
+	targetpath[rllen] = '\0';
+
+	return pstrdup(targetpath);
+}
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index fa1cb675027..a365c432d34 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -315,66 +315,12 @@ Datum
 pg_tablespace_location(PG_FUNCTION_ARGS)
 {
 	Oid			tablespaceOid = PG_GETARG_OID(0);
-	char		sourcepath[MAXPGPATH];
-	char		targetpath[MAXPGPATH];
-	int			rllen;
-	struct stat st;
+	char	   *tablespaceLoc;
 
-	/*
-	 * It's useful to apply this function to pg_class.reltablespace, wherein
-	 * zero means "the database's default tablespace".  So, rather than
-	 * throwing an error for zero, we choose to assume that's what is meant.
-	 */
-	if (tablespaceOid == InvalidOid)
-		tablespaceOid = MyDatabaseTableSpace;
-
-	/*
-	 * Return empty string for the cluster's default tablespaces
-	 */
-	if (tablespaceOid == DEFAULTTABLESPACE_OID ||
-		tablespaceOid == GLOBALTABLESPACE_OID)
-		PG_RETURN_TEXT_P(cstring_to_text(""));
-
-	/*
-	 * Find the location of the tablespace by reading the symbolic link that
-	 * is in pg_tblspc/<oid>.
-	 */
-	snprintf(sourcepath, sizeof(sourcepath), "%s/%u", PG_TBLSPC_DIR, tablespaceOid);
-
-	/*
-	 * Before reading the link, check if the source path is a link or a
-	 * junction point.  Note that a directory is possible for a tablespace
-	 * created with allow_in_place_tablespaces enabled.  If a directory is
-	 * found, a relative path to the data directory is returned.
-	 */
-	if (lstat(sourcepath, &st) < 0)
-	{
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not stat file \"%s\": %m",
-						sourcepath)));
-	}
-
-	if (!S_ISLNK(st.st_mode))
-		PG_RETURN_TEXT_P(cstring_to_text(sourcepath));
-
-	/*
-	 * In presence of a link or a junction point, return the path pointing to.
-	 */
-	rllen = readlink(sourcepath, targetpath, sizeof(targetpath));
-	if (rllen < 0)
-		ereport(ERROR,
-				(errcode_for_file_access(),
-				 errmsg("could not read symbolic link \"%s\": %m",
-						sourcepath)));
-	if (rllen >= sizeof(targetpath))
-		ereport(ERROR,
-				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
-				 errmsg("symbolic link \"%s\" target is too long",
-						sourcepath)));
-	targetpath[rllen] = '\0';
+	/* Get LOCATION string from its OID */
+	tablespaceLoc = get_tablespace_location(tablespaceOid);
 
-	PG_RETURN_TEXT_P(cstring_to_text(targetpath));
+	PG_RETURN_TEXT_P(cstring_to_text(tablespaceLoc));
 }
 
 /*
diff --git a/src/include/catalog/pg_tablespace.h b/src/include/catalog/pg_tablespace.h
index 5293488c630..7816d779d8c 100644
--- a/src/include/catalog/pg_tablespace.h
+++ b/src/include/catalog/pg_tablespace.h
@@ -54,4 +54,6 @@ DECLARE_UNIQUE_INDEX(pg_tablespace_spcname_index, 2698, TablespaceNameIndexId, p
 
 MAKE_SYSCACHE(TABLESPACEOID, pg_tablespace_oid_index, 4);
 
+extern char *get_tablespace_location(Oid tablespaceOid);
+
 #endif							/* PG_TABLESPACE_H */
-- 
2.47.3