#include "catalog/pg_shseclabel.h"
#include "catalog/pg_tablespace.h"
#include "catalog/toasting.h"
+#include "common/relpath.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/fmgroids.h"
#include "utils/tqual.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_to_number - look up fork number by name
return InvalidForkNumber; /* keep compiler quiet */
}
-/*
- * 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;
-}
-
/*
* GetDatabasePath - construct path to a database dir
*