LCOV - code coverage report
Current view: top level - src/backend/catalog - pg_tablespace.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 76.5 % 17 13
Test Date: 2026-03-01 18:15:11 Functions: 100.0 % 1 1
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-2026, 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          156 : 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          156 :     if (tablespaceOid == InvalidOid)
      43            0 :         tablespaceOid = MyDatabaseTableSpace;
      44              : 
      45              :     /*
      46              :      * Return empty string for the cluster's default tablespaces
      47              :      */
      48          156 :     if (tablespaceOid == DEFAULTTABLESPACE_OID ||
      49              :         tablespaceOid == GLOBALTABLESPACE_OID)
      50           99 :         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           57 :     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           57 :     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           57 :     if (!S_ISLNK(st.st_mode))
      71           37 :         return pstrdup(sourcepath);
      72              : 
      73              :     /*
      74              :      * In presence of a link or a junction point, return the path pointed to.
      75              :      */
      76           20 :     rllen = readlink(sourcepath, targetpath, sizeof(targetpath));
      77           20 :     if (rllen < 0)
      78            0 :         ereport(ERROR,
      79              :                 errcode_for_file_access(),
      80              :                 errmsg("could not read symbolic link \"%s\": %m",
      81              :                        sourcepath));
      82           20 :     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           20 :     targetpath[rllen] = '\0';
      88              : 
      89           20 :     return pstrdup(targetpath);
      90              : }
        

Generated by: LCOV version 2.0-1