YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/postgres/src/common/relpath.c
Line
Count
Source (jump to first uncovered line)
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-2018, 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
/*
41
 * forkname_to_number - look up fork number by name
42
 *
43
 * In backend, we throw an error for no match; in frontend, we just
44
 * return InvalidForkNumber.
45
 */
46
ForkNumber
47
forkname_to_number(const char *forkName)
48
20
{
49
20
  ForkNumber  forkNum;
50
51
20
  for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
52
20
    if (strcmp(forkNames[forkNum], forkName) == 0)
53
20
      return forkNum;
54
55
20
#ifndef FRONTEND
56
0
  ereport(ERROR,
57
0
      (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
58
0
       errmsg("invalid fork name"),
59
0
       errhint("Valid fork names are \"main\", \"fsm\", "
60
0
           "\"vm\", and \"init\".")));
61
0
#endif
62
63
0
  return InvalidForkNumber;
64
0
}
65
66
/*
67
 * forkname_chars
68
 *    We use this to figure out whether a filename could be a relation
69
 *    fork (as opposed to an oddly named stray file that somehow ended
70
 *    up in the database directory).  If the passed string begins with
71
 *    a fork name (other than the main fork name), we return its length,
72
 *    and set *fork (if not NULL) to the fork number.  If not, we return 0.
73
 *
74
 * Note that the present coding assumes that there are no fork names which
75
 * are prefixes of other fork names.
76
 */
77
int
78
forkname_chars(const char *str, ForkNumber *fork)
79
0
{
80
0
  ForkNumber  forkNum;
81
82
0
  for (forkNum = 1; forkNum <= MAX_FORKNUM; forkNum++)
83
0
  {
84
0
    int     len = strlen(forkNames[forkNum]);
85
86
0
    if (strncmp(forkNames[forkNum], str, len) == 0)
87
0
    {
88
0
      if (fork)
89
0
        *fork = forkNum;
90
0
      return len;
91
0
    }
92
0
  }
93
0
  if (fork)
94
0
    *fork = InvalidForkNumber;
95
0
  return 0;
96
0
}
97
98
99
/*
100
 * GetDatabasePath - construct path to a database directory
101
 *
102
 * Result is a palloc'd string.
103
 *
104
 * XXX this must agree with GetRelationPath()!
105
 */
106
char *
107
GetDatabasePath(Oid dbNode, Oid spcNode)
108
1.02k
{
109
1.02k
  if (spcNode == GLOBALTABLESPACE_OID)
110
0
  {
111
    /* Shared system relations live in {datadir}/global */
112
0
    Assert(dbNode == 0);
113
0
    return pstrdup("global");
114
1.02k
  }
115
1.02k
  else if (spcNode == DEFAULTTABLESPACE_OID)
116
1.02k
  {
117
    /* The default tablespace is {datadir}/base */
118
1.02k
    return psprintf("base/%u", dbNode);
119
1.02k
  }
120
0
  else
121
0
  {
122
    /* All other tablespaces are accessed via symlinks */
123
0
    return psprintf("pg_tblspc/%u/%s/%u",
124
0
            spcNode, TABLESPACE_VERSION_DIRECTORY, dbNode);
125
0
  }
126
1.02k
}
127
128
/*
129
 * GetRelationPath - construct path to a relation's file
130
 *
131
 * Result is a palloc'd string.
132
 *
133
 * Note: ideally, backendId would be declared as type BackendId, but relpath.h
134
 * would have to include a backend-only header to do that; doesn't seem worth
135
 * the trouble considering BackendId is just int anyway.
136
 */
137
char *
138
GetRelationPath(Oid dbNode, Oid spcNode, Oid relNode,
139
        int backendId, ForkNumber forkNumber)
140
4.02k
{
141
4.02k
  char     *path;
142
143
4.02k
  if (spcNode == GLOBALTABLESPACE_OID)
144
8
  {
145
    /* Shared system relations live in {datadir}/global */
146
8
    Assert(dbNode == 0);
147
8
    Assert(backendId == InvalidBackendId);
148
8
    if (forkNumber != MAIN_FORKNUM)
149
8
      path = psprintf("global/%u_%s",
150
8
              relNode, forkNames[forkNumber]);
151
0
    else
152
0
      path = psprintf("global/%u", relNode);
153
8
  }
154
4.02k
  else if (spcNode == DEFAULTTABLESPACE_OID)
155
4.02k
  {
156
    /* The default tablespace is {datadir}/base */
157
4.02k
    if (backendId == InvalidBackendId)
158
3.22k
    {
159
3.22k
      if (forkNumber != MAIN_FORKNUM)
160
846
        path = psprintf("base/%u/%u_%s",
161
846
                dbNode, relNode,
162
846
                forkNames[forkNumber]);
163
2.37k
      else
164
2.37k
        path = psprintf("base/%u/%u",
165
2.37k
                dbNode, relNode);
166
3.22k
    }
167
796
    else
168
796
    {
169
796
      if (forkNumber != MAIN_FORKNUM)
170
491
        path = psprintf("base/%u/t%d_%u_%s",
171
491
                dbNode, backendId, relNode,
172
491
                forkNames[forkNumber]);
173
305
      else
174
305
        path = psprintf("base/%u/t%d_%u",
175
305
                dbNode, backendId, relNode);
176
796
    }
177
4.02k
  }
178
0
  else
179
0
  {
180
    /* All other tablespaces are accessed via symlinks */
181
0
    if (backendId == InvalidBackendId)
182
0
    {
183
0
      if (forkNumber != MAIN_FORKNUM)
184
0
        path = psprintf("pg_tblspc/%u/%s/%u/%u_%s",
185
0
                spcNode, TABLESPACE_VERSION_DIRECTORY,
186
0
                dbNode, relNode,
187
0
                forkNames[forkNumber]);
188
0
      else
189
0
        path = psprintf("pg_tblspc/%u/%s/%u/%u",
190
0
                spcNode, TABLESPACE_VERSION_DIRECTORY,
191
0
                dbNode, relNode);
192
0
    }
193
0
    else
194
0
    {
195
0
      if (forkNumber != MAIN_FORKNUM)
196
0
        path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u_%s",
197
0
                spcNode, TABLESPACE_VERSION_DIRECTORY,
198
0
                dbNode, backendId, relNode,
199
0
                forkNames[forkNumber]);
200
0
      else
201
0
        path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u",
202
0
                spcNode, TABLESPACE_VERSION_DIRECTORY,
203
0
                dbNode, backendId, relNode);
204
0
    }
205
0
  }
206
4.02k
  return path;
207
4.02k
}