mirror of https://github.com/postgres/postgres
This enables non-backend code, such as pg_xlogdump, to use it easily. The previous location, in src/backend/catalog/catalog.c, made that essentially impossible because that file depends on many backend-only facilities; so this needs to live separately.pull/3/head
parent
6e3fd96463
commit
a730183926
@ -0,0 +1,162 @@ |
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* relpath.c |
||||||
|
* Shared frontend/backend code to find out pathnames of relation files |
||||||
|
* |
||||||
|
* Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group |
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California |
||||||
|
* |
||||||
|
* IDENTIFICATION |
||||||
|
* src/common/relpath.c |
||||||
|
* |
||||||
|
*------------------------------------------------------------------------- |
||||||
|
*/ |
||||||
|
#ifndef FRONTEND |
||||||
|
#include "postgres.h" |
||||||
|
#else |
||||||
|
#include "postgres_fe.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
#include "catalog/pg_tablespace.h" |
||||||
|
#include "common/relpath.h" |
||||||
|
#include "storage/backendid.h" |
||||||
|
|
||||||
|
#define FORKNAMECHARS 4 /* max chars for a fork name */ |
||||||
|
|
||||||
|
/*
|
||||||
|
* Lookup table of fork name by fork number. |
||||||
|
* |
||||||
|
* If you add a new entry, remember to update the errhint below, and the |
||||||
|
* documentation for pg_relation_size(). Also keep FORKNAMECHARS above |
||||||
|
* up-to-date. |
||||||
|
*/ |
||||||
|
const char *forkNames[] = { |
||||||
|
"main", /* MAIN_FORKNUM */ |
||||||
|
"fsm", /* FSM_FORKNUM */ |
||||||
|
"vm", /* VISIBILITYMAP_FORKNUM */ |
||||||
|
"init" /* INIT_FORKNUM */ |
||||||
|
}; |
||||||
|
|
||||||
|
/*
|
||||||
|
* forkname_chars |
||||||
|
* We use this to figure out whether a filename could be a relation |
||||||
|
* fork (as opposed to an oddly named stray file that somehow ended |
||||||
|
* up in the database directory). If the passed string begins with |
||||||
|
* a fork name (other than the main fork name), we return its length, |
||||||
|
* and set *fork (if not NULL) to the fork number. If not, we return 0. |
||||||
|
* |
||||||
|
* Note that the present coding assumes that there are no fork names which |
||||||
|
* are prefixes of other fork names. |
||||||
|
*/ |
||||||
|
int |
||||||
|
forkname_chars(const char *str, ForkNumber *fork) |
||||||
|
{ |
||||||
|
ForkNumber forkNum; |
||||||
|
|
||||||
|
for (forkNum = 1; forkNum <= MAX_FORKNUM; forkNum++) |
||||||
|
{ |
||||||
|
int len = strlen(forkNames[forkNum]); |
||||||
|
|
||||||
|
if (strncmp(forkNames[forkNum], str, len) == 0) |
||||||
|
{ |
||||||
|
if (fork) |
||||||
|
*fork = forkNum; |
||||||
|
return len; |
||||||
|
} |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* relpathbackend - construct path to a relation's file |
||||||
|
* |
||||||
|
* Result is a palloc'd string. |
||||||
|
*/ |
||||||
|
char * |
||||||
|
relpathbackend(RelFileNode rnode, BackendId backend, ForkNumber forknum) |
||||||
|
{ |
||||||
|
int pathlen; |
||||||
|
char *path; |
||||||
|
|
||||||
|
if (rnode.spcNode == GLOBALTABLESPACE_OID) |
||||||
|
{ |
||||||
|
/* Shared system relations live in {datadir}/global */ |
||||||
|
Assert(rnode.dbNode == 0); |
||||||
|
Assert(backend == InvalidBackendId); |
||||||
|
pathlen = 7 + OIDCHARS + 1 + FORKNAMECHARS + 1; |
||||||
|
path = (char *) palloc(pathlen); |
||||||
|
if (forknum != MAIN_FORKNUM) |
||||||
|
snprintf(path, pathlen, "global/%u_%s", |
||||||
|
rnode.relNode, forkNames[forknum]); |
||||||
|
else |
||||||
|
snprintf(path, pathlen, "global/%u", rnode.relNode); |
||||||
|
} |
||||||
|
else if (rnode.spcNode == DEFAULTTABLESPACE_OID) |
||||||
|
{ |
||||||
|
/* The default tablespace is {datadir}/base */ |
||||||
|
if (backend == InvalidBackendId) |
||||||
|
{ |
||||||
|
pathlen = 5 + OIDCHARS + 1 + OIDCHARS + 1 + FORKNAMECHARS + 1; |
||||||
|
path = (char *) palloc(pathlen); |
||||||
|
if (forknum != MAIN_FORKNUM) |
||||||
|
snprintf(path, pathlen, "base/%u/%u_%s", |
||||||
|
rnode.dbNode, rnode.relNode, |
||||||
|
forkNames[forknum]); |
||||||
|
else |
||||||
|
snprintf(path, pathlen, "base/%u/%u", |
||||||
|
rnode.dbNode, rnode.relNode); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
/* OIDCHARS will suffice for an integer, too */ |
||||||
|
pathlen = 5 + OIDCHARS + 2 + OIDCHARS + 1 + OIDCHARS + 1 |
||||||
|
+ FORKNAMECHARS + 1; |
||||||
|
path = (char *) palloc(pathlen); |
||||||
|
if (forknum != MAIN_FORKNUM) |
||||||
|
snprintf(path, pathlen, "base/%u/t%d_%u_%s", |
||||||
|
rnode.dbNode, backend, rnode.relNode, |
||||||
|
forkNames[forknum]); |
||||||
|
else |
||||||
|
snprintf(path, pathlen, "base/%u/t%d_%u", |
||||||
|
rnode.dbNode, backend, rnode.relNode); |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
/* All other tablespaces are accessed via symlinks */ |
||||||
|
if (backend == InvalidBackendId) |
||||||
|
{ |
||||||
|
pathlen = 9 + 1 + OIDCHARS + 1 |
||||||
|
+ strlen(TABLESPACE_VERSION_DIRECTORY) + 1 + OIDCHARS + 1 |
||||||
|
+ OIDCHARS + 1 + FORKNAMECHARS + 1; |
||||||
|
path = (char *) palloc(pathlen); |
||||||
|
if (forknum != MAIN_FORKNUM) |
||||||
|
snprintf(path, pathlen, "pg_tblspc/%u/%s/%u/%u_%s", |
||||||
|
rnode.spcNode, TABLESPACE_VERSION_DIRECTORY, |
||||||
|
rnode.dbNode, rnode.relNode, |
||||||
|
forkNames[forknum]); |
||||||
|
else |
||||||
|
snprintf(path, pathlen, "pg_tblspc/%u/%s/%u/%u", |
||||||
|
rnode.spcNode, TABLESPACE_VERSION_DIRECTORY, |
||||||
|
rnode.dbNode, rnode.relNode); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
/* OIDCHARS will suffice for an integer, too */ |
||||||
|
pathlen = 9 + 1 + OIDCHARS + 1 |
||||||
|
+ strlen(TABLESPACE_VERSION_DIRECTORY) + 1 + OIDCHARS + 2 |
||||||
|
+ OIDCHARS + 1 + OIDCHARS + 1 + FORKNAMECHARS + 1; |
||||||
|
path = (char *) palloc(pathlen); |
||||||
|
if (forknum != MAIN_FORKNUM) |
||||||
|
snprintf(path, pathlen, "pg_tblspc/%u/%s/%u/t%d_%u_%s", |
||||||
|
rnode.spcNode, TABLESPACE_VERSION_DIRECTORY, |
||||||
|
rnode.dbNode, backend, rnode.relNode, |
||||||
|
forkNames[forknum]); |
||||||
|
else |
||||||
|
snprintf(path, pathlen, "pg_tblspc/%u/%s/%u/t%d_%u", |
||||||
|
rnode.spcNode, TABLESPACE_VERSION_DIRECTORY, |
||||||
|
rnode.dbNode, backend, rnode.relNode); |
||||||
|
} |
||||||
|
} |
||||||
|
return path; |
||||||
|
} |
||||||
|
|
@ -0,0 +1,41 @@ |
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* |
||||||
|
* relpath.h |
||||||
|
* Declarations for relpath() and friends |
||||||
|
* |
||||||
|
* Portions Copyright (c) 1996-2013, 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 |
||||||
|
|
||||||
|
/*
|
||||||
|
* 'pgrminclude ignore' needed here because CppAsString2() does not throw |
||||||
|
* an error if the symbol is not defined. |
||||||
|
*/ |
||||||
|
#include "catalog/catversion.h" /* pgrminclude ignore */ |
||||||
|
#include "storage/relfilenode.h" |
||||||
|
|
||||||
|
|
||||||
|
#define OIDCHARS 10 /* max chars printed by %u */ |
||||||
|
#define TABLESPACE_VERSION_DIRECTORY "PG_" PG_MAJORVERSION "_" \ |
||||||
|
CppAsString2(CATALOG_VERSION_NO) |
||||||
|
|
||||||
|
extern const char *forkNames[]; |
||||||
|
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) \ |
||||||
|
relpathbackend((rnode).node, (rnode).backend, (forknum)) |
||||||
|
|
||||||
|
/* First argument is a RelFileNode */ |
||||||
|
#define relpathperm(rnode, forknum) \ |
||||||
|
relpathbackend((rnode), InvalidBackendId, (forknum)) |
||||||
|
|
||||||
|
#endif /* RELPATH_H */ |
Loading…
Reference in new issue