LCOV - code coverage report
Current view: top level - src/backend/catalog - pg_tablespace.c (source / functions) Hit Total Coverage
Test: PostgreSQL 19devel Lines: 13 17 76.5 %
Date: 2025-11-20 17:18:17 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * pg_tablespace.c
       4             :  *    routines to support manipulation of the pg_tablespace relation
       5             :  *
       6             :  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/backend/catalog/pg_tablespace.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : #include "postgres.h"
      16             : 
      17             : #include <unistd.h>
      18             : #include <sys/stat.h>
      19             : 
      20             : #include "catalog/pg_tablespace.h"
      21             : #include "commands/tablespace.h"
      22             : #include "miscadmin.h"
      23             : 
      24             : 
      25             : /*
      26             :  * get_tablespace_location
      27             :  *      Get a tablespace's location as a C-string, by its OID
      28             :  */
      29             : char *
      30         264 : get_tablespace_location(Oid tablespaceOid)
      31             : {
      32             :     char        sourcepath[MAXPGPATH];
      33             :     char        targetpath[MAXPGPATH];
      34             :     int         rllen;
      35             :     struct stat st;
      36             : 
      37             :     /*
      38             :      * It's useful to apply this to pg_class.reltablespace, wherein zero means
      39             :      * "the database's default tablespace".  So, rather than throwing an error
      40             :      * for zero, we choose to assume that's what is meant.
      41             :      */
      42         264 :     if (tablespaceOid == InvalidOid)
      43           0 :         tablespaceOid = MyDatabaseTableSpace;
      44             : 
      45             :     /*
      46             :      * Return empty string for the cluster's default tablespaces
      47             :      */
      48         264 :     if (tablespaceOid == DEFAULTTABLESPACE_OID ||
      49             :         tablespaceOid == GLOBALTABLESPACE_OID)
      50         186 :         return pstrdup("");
      51             : 
      52             :     /*
      53             :      * Find the location of the tablespace by reading the symbolic link that
      54             :      * is in pg_tblspc/<oid>.
      55             :      */
      56          78 :     snprintf(sourcepath, sizeof(sourcepath), "%s/%u", PG_TBLSPC_DIR, tablespaceOid);
      57             : 
      58             :     /*
      59             :      * Before reading the link, check if the source path is a link or a
      60             :      * junction point.  Note that a directory is possible for a tablespace
      61             :      * created with allow_in_place_tablespaces enabled.  If a directory is
      62             :      * found, a relative path to the data directory is returned.
      63             :      */
      64          78 :     if (lstat(sourcepath, &st) < 0)
      65           0 :         ereport(ERROR,
      66             :                 errcode_for_file_access(),
      67             :                 errmsg("could not stat file \"%s\": %m",
      68             :                        sourcepath));
      69             : 
      70          78 :     if (!S_ISLNK(st.st_mode))
      71          74 :         return pstrdup(sourcepath);
      72             : 
      73             :     /*
      74             :      * In presence of a link or a junction point, return the path pointed to.
      75             :      */
      76           4 :     rllen = readlink(sourcepath, targetpath, sizeof(targetpath));
      77           4 :     if (rllen < 0)
      78           0 :         ereport(ERROR,
      79             :                 errcode_for_file_access(),
      80             :                 errmsg("could not read symbolic link \"%s\": %m",
      81             :                        sourcepath));
      82           4 :     if (rllen >= sizeof(targetpath))
      83           0 :         ereport(ERROR,
      84             :                 errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
      85             :                 errmsg("symbolic link \"%s\" target is too long",
      86             :                        sourcepath));
      87           4 :     targetpath[rllen] = '\0';
      88             : 
      89           4 :     return pstrdup(targetpath);
      90             : }

Generated by: LCOV version 1.16