aboutsummaryrefslogtreecommitdiff
path: root/src/include/common/relpath.h
blob: 6f2fce216f8c578572ee94bd97ac5857e7a2c74e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*-------------------------------------------------------------------------
 *
 * relpath.h
 *		Declarations for GetRelationPath() and friends
 *
 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/common/relpath.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef RELPATH_H
#define RELPATH_H

/*
 *	Required here; note that CppAsString2() does not throw an error if the
 *	symbol is not defined.
 */
#include "catalog/catversion.h"

/*
 * RelFileNumber data type identifies the specific relation file name.
 */
typedef Oid RelFileNumber;
#define InvalidRelFileNumber		((RelFileNumber) InvalidOid)
#define RelFileNumberIsValid(relnumber) \
				((bool) ((relnumber) != InvalidRelFileNumber))

/*
 * Name of major-version-specific tablespace subdirectories
 */
#define TABLESPACE_VERSION_DIRECTORY	"PG_" PG_MAJORVERSION "_" \
									CppAsString2(CATALOG_VERSION_NO)

/*
 * Tablespace path (relative to installation's $PGDATA).
 *
 * These values should not be changed as many tools rely on it.
 */
#define PG_TBLSPC_DIR "pg_tblspc"
#define PG_TBLSPC_DIR_SLASH "pg_tblspc/"	/* required for strings
											 * comparisons */

/* Characters to allow for an OID in a relation path */
#define OIDCHARS		10		/* max chars printed by %u */

/*
 * Stuff for fork names.
 *
 * The physical storage of a relation consists of one or more forks.
 * The main fork is always created, but in addition to that there can be
 * additional forks for storing various metadata. ForkNumber is used when
 * we need to refer to a specific fork in a relation.
 */
typedef enum ForkNumber
{
	InvalidForkNumber = -1,
	MAIN_FORKNUM = 0,
	FSM_FORKNUM,
	VISIBILITYMAP_FORKNUM,
	INIT_FORKNUM,

	/*
	 * NOTE: if you add a new fork, change MAX_FORKNUM and possibly
	 * FORKNAMECHARS below, and update the forkNames array in
	 * src/common/relpath.c
	 */
} ForkNumber;

#define MAX_FORKNUM		INIT_FORKNUM

#define FORKNAMECHARS	4		/* max chars for a fork name */

extern PGDLLIMPORT const char *const forkNames[];

extern ForkNumber forkname_to_number(const char *forkName);
extern int	forkname_chars(const char *str, ForkNumber *fork);


/*
 * Unfortunately, there's no easy way to derive PROCNUMBER_CHARS from
 * MAX_BACKENDS. MAX_BACKENDS is 2^18-1. Crosschecked in test_relpath().
 */
#define PROCNUMBER_CHARS	6

/*
 * The longest possible relation path lengths is from the following format:
 * sprintf(rp.path, "%s/%u/%s/%u/t%d_%u",
 *         PG_TBLSPC_DIR, spcOid,
 *         TABLESPACE_VERSION_DIRECTORY,
 *         dbOid, procNumber, relNumber);
 *
 * Note this does *not* include the trailing null-byte, to make it easier to
 * combine it with other lengths.
 */
#define REL_PATH_STR_MAXLEN \
	( \
		sizeof(PG_TBLSPC_DIR) - 1 \
		+ sizeof((char)'/') \
		+ OIDCHARS /* spcOid */ \
		+ sizeof((char)'/') \
		+ sizeof(TABLESPACE_VERSION_DIRECTORY) - 1 \
		+ sizeof((char)'/') \
		+ OIDCHARS /* dbOid */ \
		+ sizeof((char)'/') \
		+ sizeof((char)'t') /* temporary table indicator */ \
		+ PROCNUMBER_CHARS /* procNumber */ \
		+ sizeof((char)'_') \
		+ OIDCHARS /* relNumber */ \
		+ sizeof((char)'_') \
		+ FORKNAMECHARS /* forkNames[forkNumber] */ \
	)

/*
 * String of the exact length required to represent a relation path. We return
 * this struct, instead of char[REL_PATH_STR_MAXLEN + 1], as the pointer would
 * decay to a plain char * too easily, possibly preventing the compiler from
 * detecting invalid references to the on-stack return value of
 * GetRelationPath().
 */
typedef struct RelPathStr
{
	char		str[REL_PATH_STR_MAXLEN + 1];
} RelPathStr;


/*
 * Stuff for computing filesystem pathnames for relations.
 */
extern char *GetDatabasePath(Oid dbOid, Oid spcOid);

extern RelPathStr GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber,
								  int procNumber, ForkNumber forkNumber);

/*
 * Wrapper macros for GetRelationPath.  Beware of multiple
 * evaluation of the RelFileLocator or RelFileLocatorBackend argument!
 */

/* First argument is a RelFileLocator */
#define relpathbackend(rlocator, backend, forknum) \
	GetRelationPath((rlocator).dbOid, (rlocator).spcOid, (rlocator).relNumber, \
					backend, forknum)

/* First argument is a RelFileLocator */
#define relpathperm(rlocator, forknum) \
	relpathbackend(rlocator, INVALID_PROC_NUMBER, forknum)

/* First argument is a RelFileLocatorBackend */
#define relpath(rlocator, forknum) \
	relpathbackend((rlocator).locator, (rlocator).backend, forknum)

#endif							/* RELPATH_H */