LCOV - differential code coverage report
Current view: top level - src/common - relpath.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 92.2 % 51 47 4 11 36 11
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 4 4 2 2 2
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  * relpath.c
       3                 :  *      Shared frontend/backend code to compute pathnames of relation files
       4                 :  *
       5                 :  * This module also contains some logic associated with fork names.
       6                 :  *
       7                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
       8                 :  * Portions Copyright (c) 1994, Regents of the University of California
       9                 :  *
      10                 :  * IDENTIFICATION
      11                 :  *    src/common/relpath.c
      12                 :  *
      13                 :  *-------------------------------------------------------------------------
      14                 :  */
      15                 : #ifndef FRONTEND
      16                 : #include "postgres.h"
      17                 : #else
      18                 : #include "postgres_fe.h"
      19                 : #endif
      20                 : 
      21                 : #include "catalog/pg_tablespace_d.h"
      22                 : #include "common/relpath.h"
      23                 : #include "storage/backendid.h"
      24                 : 
      25                 : 
      26                 : /*
      27                 :  * Lookup table of fork name by fork number.
      28                 :  *
      29                 :  * If you add a new entry, remember to update the errhint in
      30                 :  * forkname_to_number() below, and update the SGML documentation for
      31                 :  * pg_relation_size().
      32                 :  */
      33                 : const char *const forkNames[] = {
      34                 :     "main",                       /* MAIN_FORKNUM */
      35                 :     "fsm",                        /* FSM_FORKNUM */
      36                 :     "vm",                     /* VISIBILITYMAP_FORKNUM */
      37                 :     "init"                        /* INIT_FORKNUM */
      38                 : };
      39                 : 
      40                 : StaticAssertDecl(lengthof(forkNames) == (MAX_FORKNUM + 1),
      41                 :                  "array length mismatch");
      42                 : 
      43                 : /*
      44                 :  * forkname_to_number - look up fork number by name
      45                 :  *
      46                 :  * In backend, we throw an error for no match; in frontend, we just
      47                 :  * return InvalidForkNumber.
      48                 :  */
      49                 : ForkNumber
      50 CBC        2865 : forkname_to_number(const char *forkName)
      51                 : {
      52                 :     ForkNumber  forkNum;
      53                 : 
      54            2876 :     for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
      55            2875 :         if (strcmp(forkNames[forkNum], forkName) == 0)
      56            2864 :             return forkNum;
      57                 : 
      58                 : #ifndef FRONTEND
      59               1 :     ereport(ERROR,
      60                 :             (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
      61                 :              errmsg("invalid fork name"),
      62                 :              errhint("Valid fork names are \"main\", \"fsm\", "
      63                 :                      "\"vm\", and \"init\".")));
      64                 : #endif
      65                 : 
      66 UBC           0 :     return InvalidForkNumber;
      67                 : }
      68                 : 
      69                 : /*
      70                 :  * forkname_chars
      71                 :  *      We use this to figure out whether a filename could be a relation
      72                 :  *      fork (as opposed to an oddly named stray file that somehow ended
      73                 :  *      up in the database directory).  If the passed string begins with
      74                 :  *      a fork name (other than the main fork name), we return its length,
      75                 :  *      and set *fork (if not NULL) to the fork number.  If not, we return 0.
      76                 :  *
      77                 :  * Note that the present coding assumes that there are no fork names which
      78                 :  * are prefixes of other fork names.
      79                 :  */
      80                 : int
      81 CBC      145789 : forkname_chars(const char *str, ForkNumber *fork)
      82                 : {
      83                 :     ForkNumber  forkNum;
      84                 : 
      85          218618 :     for (forkNum = 1; forkNum <= MAX_FORKNUM; forkNum++)
      86                 :     {
      87          218618 :         int         len = strlen(forkNames[forkNum]);
      88                 : 
      89          218618 :         if (strncmp(forkNames[forkNum], str, len) == 0)
      90                 :         {
      91          145789 :             if (fork)
      92          145767 :                 *fork = forkNum;
      93          145789 :             return len;
      94                 :         }
      95                 :     }
      96 UBC           0 :     if (fork)
      97               0 :         *fork = InvalidForkNumber;
      98               0 :     return 0;
      99                 : }
     100                 : 
     101                 : 
     102                 : /*
     103                 :  * GetDatabasePath - construct path to a database directory
     104                 :  *
     105                 :  * Result is a palloc'd string.
     106                 :  *
     107                 :  * XXX this must agree with GetRelationPath()!
     108                 :  */
     109                 : char *
     110 GNC      213616 : GetDatabasePath(Oid dbOid, Oid spcOid)
     111                 : {
     112          213616 :     if (spcOid == GLOBALTABLESPACE_OID)
     113                 :     {
     114                 :         /* Shared system relations live in {datadir}/global */
     115               2 :         Assert(dbOid == 0);
     116 CBC           2 :         return pstrdup("global");
     117                 :     }
     118 GNC      213614 :     else if (spcOid == DEFAULTTABLESPACE_OID)
     119                 :     {
     120                 :         /* The default tablespace is {datadir}/base */
     121          212252 :         return psprintf("base/%u", dbOid);
     122                 :     }
     123                 :     else
     124                 :     {
     125                 :         /* All other tablespaces are accessed via symlinks */
     126 CBC        1362 :         return psprintf("pg_tblspc/%u/%s/%u",
     127                 :                         spcOid, TABLESPACE_VERSION_DIRECTORY, dbOid);
     128                 :     }
     129                 : }
     130                 : 
     131                 : /*
     132                 :  * GetRelationPath - construct path to a relation's file
     133                 :  *
     134                 :  * Result is a palloc'd string.
     135                 :  *
     136                 :  * Note: ideally, backendId would be declared as type BackendId, but relpath.h
     137                 :  * would have to include a backend-only header to do that; doesn't seem worth
     138                 :  * the trouble considering BackendId is just int anyway.
     139                 :  */
     140                 : char *
     141 GNC     2105549 : GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
     142                 :                 int backendId, ForkNumber forkNumber)
     143                 : {
     144                 :     char       *path;
     145                 : 
     146         2105549 :     if (spcOid == GLOBALTABLESPACE_OID)
     147                 :     {
     148                 :         /* Shared system relations live in {datadir}/global */
     149          121833 :         Assert(dbOid == 0);
     150 CBC      121833 :         Assert(backendId == InvalidBackendId);
     151          121833 :         if (forkNumber != MAIN_FORKNUM)
     152           33076 :             path = psprintf("global/%u_%s",
     153 GNC       33076 :                             relNumber, forkNames[forkNumber]);
     154                 :         else
     155           88757 :             path = psprintf("global/%u", relNumber);
     156                 :     }
     157         1983716 :     else if (spcOid == DEFAULTTABLESPACE_OID)
     158                 :     {
     159                 :         /* The default tablespace is {datadir}/base */
     160 CBC     1978290 :         if (backendId == InvalidBackendId)
     161                 :         {
     162         1951910 :             if (forkNumber != MAIN_FORKNUM)
     163          694255 :                 path = psprintf("base/%u/%u_%s",
     164                 :                                 dbOid, relNumber,
     165          694255 :                                 forkNames[forkNumber]);
     166                 :             else
     167         1257655 :                 path = psprintf("base/%u/%u",
     168                 :                                 dbOid, relNumber);
     169                 :         }
     170                 :         else
     171                 :         {
     172           26380 :             if (forkNumber != MAIN_FORKNUM)
     173           13992 :                 path = psprintf("base/%u/t%d_%u_%s",
     174                 :                                 dbOid, backendId, relNumber,
     175           13992 :                                 forkNames[forkNumber]);
     176                 :             else
     177           12388 :                 path = psprintf("base/%u/t%d_%u",
     178                 :                                 dbOid, backendId, relNumber);
     179                 :         }
     180                 :     }
     181                 :     else
     182                 :     {
     183                 :         /* All other tablespaces are accessed via symlinks */
     184            5426 :         if (backendId == InvalidBackendId)
     185                 :         {
     186            5369 :             if (forkNumber != MAIN_FORKNUM)
     187            2328 :                 path = psprintf("pg_tblspc/%u/%s/%u/%u_%s",
     188                 :                                 spcOid, TABLESPACE_VERSION_DIRECTORY,
     189                 :                                 dbOid, relNumber,
     190            2328 :                                 forkNames[forkNumber]);
     191                 :             else
     192            3041 :                 path = psprintf("pg_tblspc/%u/%s/%u/%u",
     193                 :                                 spcOid, TABLESPACE_VERSION_DIRECTORY,
     194                 :                                 dbOid, relNumber);
     195                 :         }
     196                 :         else
     197                 :         {
     198              57 :             if (forkNumber != MAIN_FORKNUM)
     199              30 :                 path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u_%s",
     200                 :                                 spcOid, TABLESPACE_VERSION_DIRECTORY,
     201                 :                                 dbOid, backendId, relNumber,
     202              30 :                                 forkNames[forkNumber]);
     203                 :             else
     204              27 :                 path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u",
     205                 :                                 spcOid, TABLESPACE_VERSION_DIRECTORY,
     206                 :                                 dbOid, backendId, relNumber);
     207                 :         }
     208                 :     }
     209         2105549 :     return path;
     210                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a