vacuumlazy.c: Tweak local variable name.
[pgsql.git] / src / common / relpath.c
blob87de5f6c9608b1a3cd559e8c91c09956a4287072
1 /*-------------------------------------------------------------------------
2 * relpath.c
3 * Shared frontend/backend code to compute pathnames of relation files
5 * This module also contains some logic associated with fork names.
7 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
10 * IDENTIFICATION
11 * src/common/relpath.c
13 *-------------------------------------------------------------------------
15 #ifndef FRONTEND
16 #include "postgres.h"
17 #else
18 #include "postgres_fe.h"
19 #endif
21 #include "catalog/pg_tablespace_d.h"
22 #include "common/relpath.h"
23 #include "storage/backendid.h"
27 * Lookup table of fork name by fork number.
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().
33 const char *const forkNames[] = {
34 "main", /* MAIN_FORKNUM */
35 "fsm", /* FSM_FORKNUM */
36 "vm", /* VISIBILITYMAP_FORKNUM */
37 "init" /* INIT_FORKNUM */
40 StaticAssertDecl(lengthof(forkNames) == (MAX_FORKNUM + 1),
41 "array length mismatch");
44 * forkname_to_number - look up fork number by name
46 * In backend, we throw an error for no match; in frontend, we just
47 * return InvalidForkNumber.
49 ForkNumber
50 forkname_to_number(const char *forkName)
52 ForkNumber forkNum;
54 for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
55 if (strcmp(forkNames[forkNum], forkName) == 0)
56 return forkNum;
58 #ifndef FRONTEND
59 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
66 return InvalidForkNumber;
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.
77 * Note that the present coding assumes that there are no fork names which
78 * are prefixes of other fork names.
80 int
81 forkname_chars(const char *str, ForkNumber *fork)
83 ForkNumber forkNum;
85 for (forkNum = 1; forkNum <= MAX_FORKNUM; forkNum++)
87 int len = strlen(forkNames[forkNum]);
89 if (strncmp(forkNames[forkNum], str, len) == 0)
91 if (fork)
92 *fork = forkNum;
93 return len;
96 if (fork)
97 *fork = InvalidForkNumber;
98 return 0;
103 * GetDatabasePath - construct path to a database directory
105 * Result is a palloc'd string.
107 * XXX this must agree with GetRelationPath()!
109 char *
110 GetDatabasePath(Oid dbOid, Oid spcOid)
112 if (spcOid == GLOBALTABLESPACE_OID)
114 /* Shared system relations live in {datadir}/global */
115 Assert(dbOid == 0);
116 return pstrdup("global");
118 else if (spcOid == DEFAULTTABLESPACE_OID)
120 /* The default tablespace is {datadir}/base */
121 return psprintf("base/%u", dbOid);
123 else
125 /* All other tablespaces are accessed via symlinks */
126 return psprintf("pg_tblspc/%u/%s/%u",
127 spcOid, TABLESPACE_VERSION_DIRECTORY, dbOid);
132 * GetRelationPath - construct path to a relation's file
134 * Result is a palloc'd string.
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.
140 char *
141 GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
142 int backendId, ForkNumber forkNumber)
144 char *path;
146 if (spcOid == GLOBALTABLESPACE_OID)
148 /* Shared system relations live in {datadir}/global */
149 Assert(dbOid == 0);
150 Assert(backendId == InvalidBackendId);
151 if (forkNumber != MAIN_FORKNUM)
152 path = psprintf("global/%u_%s",
153 relNumber, forkNames[forkNumber]);
154 else
155 path = psprintf("global/%u", relNumber);
157 else if (spcOid == DEFAULTTABLESPACE_OID)
159 /* The default tablespace is {datadir}/base */
160 if (backendId == InvalidBackendId)
162 if (forkNumber != MAIN_FORKNUM)
163 path = psprintf("base/%u/%u_%s",
164 dbOid, relNumber,
165 forkNames[forkNumber]);
166 else
167 path = psprintf("base/%u/%u",
168 dbOid, relNumber);
170 else
172 if (forkNumber != MAIN_FORKNUM)
173 path = psprintf("base/%u/t%d_%u_%s",
174 dbOid, backendId, relNumber,
175 forkNames[forkNumber]);
176 else
177 path = psprintf("base/%u/t%d_%u",
178 dbOid, backendId, relNumber);
181 else
183 /* All other tablespaces are accessed via symlinks */
184 if (backendId == InvalidBackendId)
186 if (forkNumber != MAIN_FORKNUM)
187 path = psprintf("pg_tblspc/%u/%s/%u/%u_%s",
188 spcOid, TABLESPACE_VERSION_DIRECTORY,
189 dbOid, relNumber,
190 forkNames[forkNumber]);
191 else
192 path = psprintf("pg_tblspc/%u/%s/%u/%u",
193 spcOid, TABLESPACE_VERSION_DIRECTORY,
194 dbOid, relNumber);
196 else
198 if (forkNumber != MAIN_FORKNUM)
199 path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u_%s",
200 spcOid, TABLESPACE_VERSION_DIRECTORY,
201 dbOid, backendId, relNumber,
202 forkNames[forkNumber]);
203 else
204 path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u",
205 spcOid, TABLESPACE_VERSION_DIRECTORY,
206 dbOid, backendId, relNumber);
209 return path;