]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Split out innards of pg_tablespace_location()
authorÁlvaro Herrera <alvherre@kurilemu.de>
Wed, 12 Nov 2025 15:39:55 +0000 (16:39 +0100)
committerÁlvaro Herrera <alvherre@kurilemu.de>
Wed, 12 Nov 2025 15:39:55 +0000 (16:39 +0100)
This creates a src/backend/catalog/pg_tablespace.c supporting file
containing a new function get_tablespace_location(), which lets the code
underlying pg_tablespace_location() be reused for other purposes.

Author: Manni Wood <manni.wood@enterprisedb.com>
Author: Nishant Sharma <nishant.sharma@enterprisedb.com>
Reviewed-by: Vaibhav Dalvi <vaibhav.dalvi@enterprisedb.com>
Reviewed-by: Ian Lawrence Barwick <barwick@gmail.com>
Reviewed-by: Jim Jones <jim.jones@uni-muenster.de>
Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>
Discussion: https://postgr.es/m/CAKWEB6rmnmGKUA87Zmq-s=b3Scsnj02C0kObQjnbL2ajfPWGEw@mail.gmail.com

src/backend/catalog/Makefile
src/backend/catalog/meson.build
src/backend/catalog/pg_tablespace.c [new file with mode: 0644]
src/backend/utils/adt/misc.c
src/include/catalog/pg_tablespace.h

index c090094ed08d567e2184bb999fec9221d5c3663b..8e40e1b8189f8f27d724df622b18b8b544aadd54 100644 (file)
@@ -44,6 +44,7 @@ OBJS = \
        pg_range.o \
        pg_shdepend.o \
        pg_subscription.o \
+       pg_tablespace.o \
        pg_type.o \
        storage.o \
        toasting.o
index 1958ea9238a76e544bf6fdeabdaf6b5039a55769..58674ffeee642a4f1030350ed65197368f231b45 100644 (file)
@@ -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 (file)
index 0000000..6aca24c
--- /dev/null
@@ -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);
+}
index fa1cb67502735b25e3248ae28e5e71554d3aa159..a365c432d34f7687edde3da5afd688af5df2259e 100644 (file)
@@ -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));
 }
 
 /*
index 5293488c63091e7ea2b59fff1e34c0c7b0a7fd77..7816d779d8cce67a1f27d0ae0167c4381777ee65 100644 (file)
@@ -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 */