v6-0001-Supporting-changes-for-pg_get_tablespace_ddl-func.patch
text/x-patch
Filename: v6-0001-Supporting-changes-for-pg_get_tablespace_ddl-func.patch
Type: text/x-patch
Part: 0
From 11831687a0324aa88d13716ec7f051a80a42f8e1 Mon Sep 17 00:00:00 2001
From: Manni Wood <manni.wood@enterprisedb.com>
Date: Thu, 6 Nov 2025 14:03:02 -0600
Subject: [PATCH v6 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/utils/adt/misc.c | 62 ++----------------------
src/backend/utils/adt/ruleutils.c | 79 +++++++++++++++++++++++++++++++
src/include/utils/ruleutils.h | 2 +
3 files changed, 85 insertions(+), 58 deletions(-)
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index fa1cb675027..cb99d7435eb 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_loc_string(tablespaceOid);
- PG_RETURN_TEXT_P(cstring_to_text(targetpath));
+ PG_RETURN_TEXT_P(cstring_to_text(tablespaceLoc));
}
/*
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 556ab057e5a..b15d85c5477 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -18,6 +18,7 @@
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
+#include <sys/stat.h>
#include "access/amapi.h"
#include "access/htup_details.h"
@@ -13743,3 +13744,81 @@ get_range_partbound_string(List *bound_datums)
return buf.data;
}
+
+/*
+ * get_tablespace_loc_string - get location for a tablespace in string. This is
+ * internal version which helps pg_tablespace_location() and others.
+ */
+char *
+get_tablespace_loc_string(Oid tablespaceOid)
+{
+ char sourcepath[MAXPGPATH] = { '\0' };
+ char targetpath[MAXPGPATH] = { '\0' };
+ int rllen;
+ struct stat st;
+ StringInfoData buf;
+
+ initStringInfo(&buf);
+ appendStringInfoString(&buf, "");
+
+ /*
+ * 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)
+ return buf.data;
+
+ /*
+ * 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))
+ {
+ appendStringInfoString(&buf, sourcepath);
+ return buf.data;
+ }
+
+ /*
+ * 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';
+
+ appendStringInfoString(&buf, targetpath);
+
+ return buf.data;
+}
diff --git a/src/include/utils/ruleutils.h b/src/include/utils/ruleutils.h
index 7ba7d887914..6d74485f32a 100644
--- a/src/include/utils/ruleutils.h
+++ b/src/include/utils/ruleutils.h
@@ -54,4 +54,6 @@ extern char *get_range_partbound_string(List *bound_datums);
extern char *pg_get_statisticsobjdef_string(Oid statextid);
+extern char *get_tablespace_loc_string(Oid tablespaceOid);
+
#endif /* RULEUTILS_H */
--
2.51.2