summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/Makefile1
-rw-r--r--src/backend/catalog/meson.build1
-rw-r--r--src/backend/catalog/pg_tablespace.c90
-rw-r--r--src/backend/utils/adt/misc.c62
-rw-r--r--src/include/catalog/pg_tablespace.h2
5 files changed, 98 insertions, 58 deletions
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..6aca24c231e
--- /dev/null
+++ b/src/backend/catalog/pg_tablespace.c
@@ -0,0 +1,90 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_tablespace.c
+ * routines to support manipulation of the pg_tablespace relation
+ *
+ * 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 */