Rationalize common/relpath.[hc].

Commit a730183926 created rather a mess by
putting dependencies on backend-only include files into include/common.
We really shouldn't do that.  To clean it up:

* Move TABLESPACE_VERSION_DIRECTORY back to its longtime home in
catalog/catalog.h.  We won't consider this symbol part of the FE/BE API.

* Push enum ForkNumber from relfilenode.h into relpath.h.  We'll consider
relpath.h as the source of truth for fork numbers, since relpath.c was
already partially serving that function, and anyway relfilenode.h was
kind of a random place for that enum.

* So, relfilenode.h now includes relpath.h rather than vice-versa.  This
direction of dependency is fine.  (That allows most, but not quite all,
of the existing explicit #includes of relpath.h to go away again.)

* Push forkname_to_number from catalog.c to relpath.c, just to centralize
fork number stuff a bit better.

* Push GetDatabasePath from catalog.c to relpath.c; it was rather odd
that the previous commit didn't keep this together with relpath().

* To avoid needing relfilenode.h in common/, redefine the underlying
function (now called GetRelationPath) as taking separate OID arguments,
and make the APIs using RelFileNode or RelFileNodeBackend into macro
wrappers.  (The macros have a potential multiple-eval risk, but none of
the existing call sites have an issue with that; one of them had such a
risk already anyway.)

* Fix failure to follow the directions when "init" fork type was added;
specifically, the errhint in forkname_to_number wasn't updated, and neither
was the SGML documentation for pg_relation_size().

* Fix tablespace-path-too-long check in CreateTableSpace() to account for
fork-name component of maximum-length pathnames.  This requires putting
FORKNAMECHARS into a header file, but it was rather useless (and
actually unreferenced) where it was.

The last couple of items are potentially back-patchable bug fixes,
if anyone is sufficiently excited about them; but personally I'm not.

Per a gripe from Christoph Berg about how include/common wasn't
self-contained.
This commit is contained in:
Tom Lane 2014-04-30 17:30:50 -04:00
parent 0bff398761
commit 2d00190495
22 changed files with 173 additions and 163 deletions

View File

@ -19,7 +19,6 @@
#include "access/xlogreader.h" #include "access/xlogreader.h"
#include "access/transam.h" #include "access/transam.h"
#include "common/fe_memutils.h" #include "common/fe_memutils.h"
#include "common/relpath.h"
#include "getopt_long.h" #include "getopt_long.h"
#include "rmgrdesc.h" #include "rmgrdesc.h"

View File

@ -16847,7 +16847,7 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
<entry><type>bigint</type></entry> <entry><type>bigint</type></entry>
<entry> <entry>
Disk space used by the specified fork (<literal>'main'</literal>, Disk space used by the specified fork (<literal>'main'</literal>,
<literal>'fsm'</literal> or <literal>'vm'</>) <literal>'fsm'</literal>, <literal>'vm'</>, or <literal>'init'</>)
of the specified table or index of the specified table or index
</entry> </entry>
</row> </row>
@ -16951,14 +16951,16 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
<para> <para>
<function>pg_relation_size</> accepts the OID or name of a table, index or <function>pg_relation_size</> accepts the OID or name of a table, index or
toast table, and returns the on-disk size in bytes. Specifying toast table, and returns the on-disk size in bytes.
<literal>'main'</literal> or leaving out the second argument returns the Specifying <literal>'main'</literal> or leaving out the second argument
size of the main data fork of the relation. Specifying returns the size of the main data fork of the relation.
<literal>'fsm'</literal> returns the size of the Specifying <literal>'fsm'</literal> returns the size of the Free Space
Free Space Map (see <xref linkend="storage-fsm">) associated with the Map (see <xref linkend="storage-fsm">) associated with the relation.
relation. Specifying <literal>'vm'</literal> returns the size of the Specifying <literal>'vm'</literal> returns the size of the Visibility
Visibility Map (see <xref linkend="storage-vm">) associated with the Map (see <xref linkend="storage-vm">) associated with the relation.
relation. Note that this function shows the size of only one fork; Specifying <literal>'init'</literal> returns the size of the
initialization fork, if any, associated with the relation.
Note that this function shows the size of only one fork;
for most purposes it is more convenient to use the higher-level for most purposes it is more convenient to use the higher-level
functions <function>pg_total_relation_size</> or functions <function>pg_total_relation_size</> or
<function>pg_table_size</>. <function>pg_table_size</>.

View File

@ -16,7 +16,6 @@
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/storage_xlog.h" #include "catalog/storage_xlog.h"
#include "common/relpath.h"
void void

View File

@ -16,7 +16,6 @@
#include "access/xact.h" #include "access/xact.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "common/relpath.h"
#include "storage/sinval.h" #include "storage/sinval.h"
#include "utils/timestamp.h" #include "utils/timestamp.h"

View File

@ -17,7 +17,6 @@
#include "access/xlog.h" #include "access/xlog.h"
#include "access/xlog_internal.h" #include "access/xlog_internal.h"
#include "catalog/pg_control.h" #include "catalog/pg_control.h"
#include "common/relpath.h"
#include "utils/guc.h" #include "utils/guc.h"
#include "utils/timestamp.h" #include "utils/timestamp.h"

View File

@ -20,7 +20,6 @@
#include "access/xlog.h" #include "access/xlog.h"
#include "access/xlogutils.h" #include "access/xlogutils.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "common/relpath.h"
#include "storage/smgr.h" #include "storage/smgr.h"
#include "utils/guc.h" #include "utils/guc.h"
#include "utils/hsearch.h" #include "utils/hsearch.h"

View File

@ -37,7 +37,6 @@
#include "catalog/pg_shseclabel.h" #include "catalog/pg_shseclabel.h"
#include "catalog/pg_tablespace.h" #include "catalog/pg_tablespace.h"
#include "catalog/toasting.h" #include "catalog/toasting.h"
#include "common/relpath.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "storage/fd.h" #include "storage/fd.h"
#include "utils/fmgroids.h" #include "utils/fmgroids.h"
@ -45,56 +44,6 @@
#include "utils/tqual.h" #include "utils/tqual.h"
/*
* forkname_to_number - look up fork number by name
*/
ForkNumber
forkname_to_number(char *forkName)
{
ForkNumber forkNum;
for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
if (strcmp(forkNames[forkNum], forkName) == 0)
return forkNum;
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid fork name"),
errhint("Valid fork names are \"main\", \"fsm\", and \"vm\".")));
return InvalidForkNumber; /* keep compiler quiet */
}
/*
* GetDatabasePath - construct path to a database dir
*
* Result is a palloc'd string.
*
* XXX this must agree with relpath()!
*/
char *
GetDatabasePath(Oid dbNode, Oid spcNode)
{
if (spcNode == GLOBALTABLESPACE_OID)
{
/* Shared system relations live in {datadir}/global */
Assert(dbNode == 0);
return pstrdup("global");
}
else if (spcNode == DEFAULTTABLESPACE_OID)
{
/* The default tablespace is {datadir}/base */
return psprintf("base/%u", dbNode);
}
else
{
/* All other tablespaces are accessed via symlinks */
return psprintf("pg_tblspc/%u/%s/%u",
spcNode, TABLESPACE_VERSION_DIRECTORY, dbNode);
}
}
/* /*
* IsSystemRelation * IsSystemRelation
* True iff the relation is either a system catalog or toast table. * True iff the relation is either a system catalog or toast table.

View File

@ -51,7 +51,6 @@
#include "commands/tablespace.h" #include "commands/tablespace.h"
#include "commands/trigger.h" #include "commands/trigger.h"
#include "commands/typecmds.h" #include "commands/typecmds.h"
#include "common/relpath.h"
#include "executor/executor.h" #include "executor/executor.h"
#include "foreign/foreign.h" #include "foreign/foreign.h"
#include "miscadmin.h" #include "miscadmin.h"

View File

@ -68,7 +68,6 @@
#include "commands/tablecmds.h" #include "commands/tablecmds.h"
#include "commands/tablespace.h" #include "commands/tablespace.h"
#include "commands/user.h" #include "commands/user.h"
#include "common/relpath.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "postmaster/bgwriter.h" #include "postmaster/bgwriter.h"
#include "storage/fd.h" #include "storage/fd.h"
@ -278,11 +277,11 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
/* /*
* Check that location isn't too long. Remember that we're going to append * Check that location isn't too long. Remember that we're going to append
* 'PG_XXX/<dboid>/<relid>.<nnn>'. FYI, we never actually reference the * 'PG_XXX/<dboid>/<relid>_<fork>.<nnn>'. FYI, we never actually
* whole path, but mkdir() uses the first two parts. * reference the whole path here, but mkdir() uses the first two parts.
*/ */
if (strlen(location) + 1 + strlen(TABLESPACE_VERSION_DIRECTORY) + 1 + if (strlen(location) + 1 + strlen(TABLESPACE_VERSION_DIRECTORY) + 1 +
OIDCHARS + 1 + OIDCHARS + 1 + OIDCHARS > MAXPGPATH) OIDCHARS + 1 + OIDCHARS + 1 + FORKNAMECHARS + 1 + OIDCHARS > MAXPGPATH)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION), (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("tablespace location \"%s\" is too long", errmsg("tablespace location \"%s\" is too long",

View File

@ -18,8 +18,8 @@
#include <time.h> #include <time.h>
#include "access/xlog_internal.h" /* for pg_start/stop_backup */ #include "access/xlog_internal.h" /* for pg_start/stop_backup */
#include "catalog/catalog.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "common/relpath.h"
#include "lib/stringinfo.h" #include "lib/stringinfo.h"
#include "libpq/libpq.h" #include "libpq/libpq.h"
#include "libpq/pqformat.h" #include "libpq/pqformat.h"

View File

@ -50,28 +50,20 @@
#include <unistd.h> #include <unistd.h>
#include <sys/stat.h> #include <sys/stat.h>
#include "miscadmin.h"
#include "access/rewriteheap.h" #include "access/rewriteheap.h"
#include "access/transam.h" #include "access/transam.h"
#include "access/tuptoaster.h" #include "access/tuptoaster.h"
#include "access/xact.h" #include "access/xact.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "common/relpath.h"
#include "lib/binaryheap.h" #include "lib/binaryheap.h"
#include "miscadmin.h"
#include "replication/logical.h" #include "replication/logical.h"
#include "replication/reorderbuffer.h" #include "replication/reorderbuffer.h"
#include "replication/slot.h" #include "replication/slot.h"
#include "replication/snapbuild.h" /* just for SnapBuildSnapDecRefcount */ #include "replication/snapbuild.h" /* just for SnapBuildSnapDecRefcount */
#include "storage/bufmgr.h" #include "storage/bufmgr.h"
#include "storage/fd.h" #include "storage/fd.h"
#include "storage/sinval.h" #include "storage/sinval.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/combocid.h" #include "utils/combocid.h"
#include "utils/memdebug.h" #include "utils/memdebug.h"
@ -80,6 +72,7 @@
#include "utils/relfilenodemap.h" #include "utils/relfilenodemap.h"
#include "utils/tqual.h" #include "utils/tqual.h"
/* entry for a hash table we use to map from xid to our transaction state */ /* entry for a hash table we use to map from xid to our transaction state */
typedef struct ReorderBufferTXNByIdEnt typedef struct ReorderBufferTXNByIdEnt
{ {

View File

@ -35,7 +35,6 @@
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/storage.h" #include "catalog/storage.h"
#include "common/relpath.h"
#include "executor/instrument.h" #include "executor/instrument.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "pg_trace.h" #include "pg_trace.h"

View File

@ -16,7 +16,6 @@
#include "postgres.h" #include "postgres.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "common/relpath.h"
#include "executor/instrument.h" #include "executor/instrument.h"
#include "storage/buf_internals.h" #include "storage/buf_internals.h"
#include "storage/bufmgr.h" #include "storage/bufmgr.h"

View File

@ -71,7 +71,6 @@
#include "access/xact.h" #include "access/xact.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/pg_tablespace.h" #include "catalog/pg_tablespace.h"
#include "common/relpath.h"
#include "pgstat.h" #include "pgstat.h"
#include "storage/fd.h" #include "storage/fd.h"
#include "storage/ipc.h" #include "storage/ipc.h"

View File

@ -28,7 +28,6 @@
#include "miscadmin.h" #include "miscadmin.h"
#include "access/xlog.h" #include "access/xlog.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "common/relpath.h"
#include "portability/instr_time.h" #include "portability/instr_time.h"
#include "postmaster/bgwriter.h" #include "postmaster/bgwriter.h"
#include "storage/fd.h" #include "storage/fd.h"

View File

@ -21,7 +21,6 @@
#include "catalog/pg_tablespace.h" #include "catalog/pg_tablespace.h"
#include "commands/dbcommands.h" #include "commands/dbcommands.h"
#include "commands/tablespace.h" #include "commands/tablespace.h"
#include "common/relpath.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "storage/fd.h" #include "storage/fd.h"
#include "utils/acl.h" #include "utils/acl.h"

View File

@ -25,7 +25,6 @@
#include "catalog/pg_tablespace.h" #include "catalog/pg_tablespace.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "commands/dbcommands.h" #include "commands/dbcommands.h"
#include "common/relpath.h"
#include "funcapi.h" #include "funcapi.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "parser/keywords.h" #include "parser/keywords.h"

View File

@ -56,7 +56,6 @@
#include "catalog/schemapg.h" #include "catalog/schemapg.h"
#include "catalog/storage.h" #include "catalog/storage.h"
#include "commands/trigger.h" #include "commands/trigger.h"
#include "common/relpath.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "optimizer/clauses.h" #include "optimizer/clauses.h"
#include "optimizer/planmain.h" #include "optimizer/planmain.h"

View File

@ -1,6 +1,8 @@
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* relpath.c * relpath.c
* Shared frontend/backend code to find out pathnames of relation files * Shared frontend/backend code to compute pathnames of relation files
*
* This module also contains some logic associated with fork names.
* *
* Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
@ -16,18 +18,18 @@
#include "postgres_fe.h" #include "postgres_fe.h"
#endif #endif
#include "catalog/catalog.h"
#include "catalog/pg_tablespace.h" #include "catalog/pg_tablespace.h"
#include "common/relpath.h" #include "common/relpath.h"
#include "storage/backendid.h" #include "storage/backendid.h"
#define FORKNAMECHARS 4 /* max chars for a fork name */
/* /*
* Lookup table of fork name by fork number. * Lookup table of fork name by fork number.
* *
* If you add a new entry, remember to update the errhint below, and the * If you add a new entry, remember to update the errhint in
* documentation for pg_relation_size(). Also keep FORKNAMECHARS above * forkname_to_number() below, and update the SGML documentation for
* up-to-date. * pg_relation_size().
*/ */
const char *const forkNames[] = { const char *const forkNames[] = {
"main", /* MAIN_FORKNUM */ "main", /* MAIN_FORKNUM */
@ -36,6 +38,32 @@ const char *const forkNames[] = {
"init" /* INIT_FORKNUM */ "init" /* INIT_FORKNUM */
}; };
/*
* forkname_to_number - look up fork number by name
*
* In backend, we throw an error for no match; in frontend, we just
* return InvalidForkNumber.
*/
ForkNumber
forkname_to_number(const char *forkName)
{
ForkNumber forkNum;
for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
if (strcmp(forkNames[forkNum], forkName) == 0)
return forkNum;
#ifndef FRONTEND
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("invalid fork name"),
errhint("Valid fork names are \"main\", \"fsm\", "
"\"vm\", and \"init\".")));
#endif
return InvalidForkNumber;
}
/* /*
* forkname_chars * forkname_chars
* We use this to figure out whether a filename could be a relation * We use this to figure out whether a filename could be a relation
@ -63,80 +91,117 @@ forkname_chars(const char *str, ForkNumber *fork)
return len; return len;
} }
} }
if (fork)
*fork = InvalidForkNumber;
return 0; return 0;
} }
/* /*
* relpathbackend - construct path to a relation's file * GetDatabasePath - construct path to a database directory
* *
* Result is a palloc'd string. * Result is a palloc'd string.
*
* XXX this must agree with GetRelationPath()!
*/ */
char * char *
relpathbackend(RelFileNode rnode, BackendId backend, ForkNumber forknum) GetDatabasePath(Oid dbNode, Oid spcNode)
{
if (spcNode == GLOBALTABLESPACE_OID)
{
/* Shared system relations live in {datadir}/global */
Assert(dbNode == 0);
return pstrdup("global");
}
else if (spcNode == DEFAULTTABLESPACE_OID)
{
/* The default tablespace is {datadir}/base */
return psprintf("base/%u", dbNode);
}
else
{
/* All other tablespaces are accessed via symlinks */
return psprintf("pg_tblspc/%u/%s/%u",
spcNode, TABLESPACE_VERSION_DIRECTORY, dbNode);
}
}
/*
* GetRelationPath - construct path to a relation's file
*
* Result is a palloc'd string.
*
* Note: ideally, backendId would be declared as type BackendId, but relpath.h
* would have to include a backend-only header to do that; doesn't seem worth
* the trouble considering BackendId is just int anyway.
*/
char *
GetRelationPath(Oid dbNode, Oid spcNode, Oid relNode,
int backendId, ForkNumber forkNumber)
{ {
char *path; char *path;
if (rnode.spcNode == GLOBALTABLESPACE_OID) if (spcNode == GLOBALTABLESPACE_OID)
{ {
/* Shared system relations live in {datadir}/global */ /* Shared system relations live in {datadir}/global */
Assert(rnode.dbNode == 0); Assert(dbNode == 0);
Assert(backend == InvalidBackendId); Assert(backendId == InvalidBackendId);
if (forknum != MAIN_FORKNUM) if (forkNumber != MAIN_FORKNUM)
path = psprintf("global/%u_%s", path = psprintf("global/%u_%s",
rnode.relNode, forkNames[forknum]); relNode, forkNames[forkNumber]);
else else
path = psprintf("global/%u", rnode.relNode); path = psprintf("global/%u", relNode);
} }
else if (rnode.spcNode == DEFAULTTABLESPACE_OID) else if (spcNode == DEFAULTTABLESPACE_OID)
{ {
/* The default tablespace is {datadir}/base */ /* The default tablespace is {datadir}/base */
if (backend == InvalidBackendId) if (backendId == InvalidBackendId)
{ {
if (forknum != MAIN_FORKNUM) if (forkNumber != MAIN_FORKNUM)
path = psprintf("base/%u/%u_%s", path = psprintf("base/%u/%u_%s",
rnode.dbNode, rnode.relNode, dbNode, relNode,
forkNames[forknum]); forkNames[forkNumber]);
else else
path = psprintf("base/%u/%u", path = psprintf("base/%u/%u",
rnode.dbNode, rnode.relNode); dbNode, relNode);
} }
else else
{ {
if (forknum != MAIN_FORKNUM) if (forkNumber != MAIN_FORKNUM)
path = psprintf("base/%u/t%d_%u_%s", path = psprintf("base/%u/t%d_%u_%s",
rnode.dbNode, backend, rnode.relNode, dbNode, backendId, relNode,
forkNames[forknum]); forkNames[forkNumber]);
else else
path = psprintf("base/%u/t%d_%u", path = psprintf("base/%u/t%d_%u",
rnode.dbNode, backend, rnode.relNode); dbNode, backendId, relNode);
} }
} }
else else
{ {
/* All other tablespaces are accessed via symlinks */ /* All other tablespaces are accessed via symlinks */
if (backend == InvalidBackendId) if (backendId == InvalidBackendId)
{ {
if (forknum != MAIN_FORKNUM) if (forkNumber != MAIN_FORKNUM)
path = psprintf("pg_tblspc/%u/%s/%u/%u_%s", path = psprintf("pg_tblspc/%u/%s/%u/%u_%s",
rnode.spcNode, TABLESPACE_VERSION_DIRECTORY, spcNode, TABLESPACE_VERSION_DIRECTORY,
rnode.dbNode, rnode.relNode, dbNode, relNode,
forkNames[forknum]); forkNames[forkNumber]);
else else
path = psprintf("pg_tblspc/%u/%s/%u/%u", path = psprintf("pg_tblspc/%u/%s/%u/%u",
rnode.spcNode, TABLESPACE_VERSION_DIRECTORY, spcNode, TABLESPACE_VERSION_DIRECTORY,
rnode.dbNode, rnode.relNode); dbNode, relNode);
} }
else else
{ {
if (forknum != MAIN_FORKNUM) if (forkNumber != MAIN_FORKNUM)
path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u_%s", path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u_%s",
rnode.spcNode, TABLESPACE_VERSION_DIRECTORY, spcNode, TABLESPACE_VERSION_DIRECTORY,
rnode.dbNode, backend, rnode.relNode, dbNode, backendId, relNode,
forkNames[forknum]); forkNames[forkNumber]);
else else
path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u", path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u",
rnode.spcNode, TABLESPACE_VERSION_DIRECTORY, spcNode, TABLESPACE_VERSION_DIRECTORY,
rnode.dbNode, backend, rnode.relNode); dbNode, backendId, relNode);
} }
} }
return path; return path;

View File

@ -14,13 +14,17 @@
#ifndef CATALOG_H #ifndef CATALOG_H
#define CATALOG_H #define CATALOG_H
/*
* 'pgrminclude ignore' needed here because CppAsString2() does not throw
* an error if the symbol is not defined.
*/
#include "catalog/catversion.h" /* pgrminclude ignore */
#include "catalog/pg_class.h" #include "catalog/pg_class.h"
#include "storage/relfilenode.h"
#include "utils/relcache.h" #include "utils/relcache.h"
extern ForkNumber forkname_to_number(char *forkName); #define OIDCHARS 10 /* max chars printed by %u */
#define TABLESPACE_VERSION_DIRECTORY "PG_" PG_MAJORVERSION "_" \
extern char *GetDatabasePath(Oid dbNode, Oid spcNode); CppAsString2(CATALOG_VERSION_NO)
extern bool IsSystemRelation(Relation relation); extern bool IsSystemRelation(Relation relation);

View File

@ -1,7 +1,7 @@
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* *
* relpath.h * relpath.h
* Declarations for relpath() and friends * Declarations for GetRelationPath() and friends
* *
* Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
@ -14,29 +14,61 @@
#define RELPATH_H #define RELPATH_H
/* /*
* 'pgrminclude ignore' needed here because CppAsString2() does not throw * Stuff for fork names.
* an error if the symbol is not defined. *
* 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.
*/ */
#include "catalog/catversion.h" /* pgrminclude ignore */ typedef enum ForkNumber
#include "storage/relfilenode.h" {
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 OIDCHARS 10 /* max chars printed by %u */ #define MAX_FORKNUM INIT_FORKNUM
#define TABLESPACE_VERSION_DIRECTORY "PG_" PG_MAJORVERSION "_" \
CppAsString2(CATALOG_VERSION_NO) #define FORKNAMECHARS 4 /* max chars for a fork name */
extern const char *const forkNames[]; extern const char *const forkNames[];
extern ForkNumber forkname_to_number(const char *forkName);
extern int forkname_chars(const char *str, ForkNumber *fork); extern int forkname_chars(const char *str, ForkNumber *fork);
extern char *relpathbackend(RelFileNode rnode, BackendId backend,
ForkNumber forknum);
/* First argument is a RelFileNodeBackend */ /*
#define relpath(rnode, forknum) \ * Stuff for computing filesystem pathnames for relations.
relpathbackend((rnode).node, (rnode).backend, (forknum)) */
extern char *GetDatabasePath(Oid dbNode, Oid spcNode);
extern char *GetRelationPath(Oid dbNode, Oid spcNode, Oid relNode,
int backendId, ForkNumber forkNumber);
/*
* Wrapper macros for GetRelationPath. Beware of multiple
* evaluation of the RelFileNode or RelFileNodeBackend argument!
*/
/* First argument is a RelFileNode */
#define relpathbackend(rnode, backend, forknum) \
GetRelationPath((rnode).dbNode, (rnode).spcNode, (rnode).relNode, \
backend, forknum)
/* First argument is a RelFileNode */ /* First argument is a RelFileNode */
#define relpathperm(rnode, forknum) \ #define relpathperm(rnode, forknum) \
relpathbackend((rnode), InvalidBackendId, (forknum)) relpathbackend(rnode, InvalidBackendId, forknum)
/* First argument is a RelFileNodeBackend */
#define relpath(rnode, forknum) \
relpathbackend((rnode).node, (rnode).backend, forknum)
#endif /* RELPATH_H */ #endif /* RELPATH_H */

View File

@ -14,30 +14,9 @@
#ifndef RELFILENODE_H #ifndef RELFILENODE_H
#define RELFILENODE_H #define RELFILENODE_H
#include "common/relpath.h"
#include "storage/backendid.h" #include "storage/backendid.h"
/*
* 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 below and update the
* forkNames array in src/common/relpath.c
*/
} ForkNumber;
#define MAX_FORKNUM INIT_FORKNUM
/* /*
* RelFileNode must provide all that we need to know to physically access * RelFileNode must provide all that we need to know to physically access
* a relation, with the exception of the backend ID, which can be provided * a relation, with the exception of the backend ID, which can be provided