aboutsummaryrefslogtreecommitdiff
path: root/src/common/relpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/relpath.c')
-rw-r--r--src/common/relpath.c137
1 files changed, 101 insertions, 36 deletions
diff --git a/src/common/relpath.c b/src/common/relpath.c
index fbb5de6922b..fc8b2732eaa 100644
--- a/src/common/relpath.c
+++ b/src/common/relpath.c
@@ -1,6 +1,8 @@
/*-------------------------------------------------------------------------
* 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) 1994, Regents of the University of California
@@ -16,18 +18,18 @@
#include "postgres_fe.h"
#endif
+#include "catalog/catalog.h"
#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.
+ * If you add a new entry, remember to update the errhint in
+ * forkname_to_number() below, and update the SGML documentation for
+ * pg_relation_size().
*/
const char *const forkNames[] = {
"main", /* MAIN_FORKNUM */
@@ -37,6 +39,32 @@ const char *const forkNames[] = {
};
/*
+ * 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
* 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
@@ -63,80 +91,117 @@ forkname_chars(const char *str, ForkNumber *fork)
return len;
}
}
+ if (fork)
+ *fork = InvalidForkNumber;
return 0;
}
+
+/*
+ * GetDatabasePath - construct path to a database directory
+ *
+ * Result is a palloc'd string.
+ *
+ * XXX this must agree with GetRelationPath()!
+ */
+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);
+ }
+}
+
/*
- * relpathbackend - construct path to a relation's file
+ * 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 *
-relpathbackend(RelFileNode rnode, BackendId backend, ForkNumber forknum)
+GetRelationPath(Oid dbNode, Oid spcNode, Oid relNode,
+ int backendId, ForkNumber forkNumber)
{
char *path;
- if (rnode.spcNode == GLOBALTABLESPACE_OID)
+ if (spcNode == GLOBALTABLESPACE_OID)
{
/* Shared system relations live in {datadir}/global */
- Assert(rnode.dbNode == 0);
- Assert(backend == InvalidBackendId);
- if (forknum != MAIN_FORKNUM)
+ Assert(dbNode == 0);
+ Assert(backendId == InvalidBackendId);
+ if (forkNumber != MAIN_FORKNUM)
path = psprintf("global/%u_%s",
- rnode.relNode, forkNames[forknum]);
+ relNode, forkNames[forkNumber]);
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 */
- if (backend == InvalidBackendId)
+ if (backendId == InvalidBackendId)
{
- if (forknum != MAIN_FORKNUM)
+ if (forkNumber != MAIN_FORKNUM)
path = psprintf("base/%u/%u_%s",
- rnode.dbNode, rnode.relNode,
- forkNames[forknum]);
+ dbNode, relNode,
+ forkNames[forkNumber]);
else
path = psprintf("base/%u/%u",
- rnode.dbNode, rnode.relNode);
+ dbNode, relNode);
}
else
{
- if (forknum != MAIN_FORKNUM)
+ if (forkNumber != MAIN_FORKNUM)
path = psprintf("base/%u/t%d_%u_%s",
- rnode.dbNode, backend, rnode.relNode,
- forkNames[forknum]);
+ dbNode, backendId, relNode,
+ forkNames[forkNumber]);
else
path = psprintf("base/%u/t%d_%u",
- rnode.dbNode, backend, rnode.relNode);
+ dbNode, backendId, relNode);
}
}
else
{
/* 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",
- rnode.spcNode, TABLESPACE_VERSION_DIRECTORY,
- rnode.dbNode, rnode.relNode,
- forkNames[forknum]);
+ spcNode, TABLESPACE_VERSION_DIRECTORY,
+ dbNode, relNode,
+ forkNames[forkNumber]);
else
path = psprintf("pg_tblspc/%u/%s/%u/%u",
- rnode.spcNode, TABLESPACE_VERSION_DIRECTORY,
- rnode.dbNode, rnode.relNode);
+ spcNode, TABLESPACE_VERSION_DIRECTORY,
+ dbNode, relNode);
}
else
{
- if (forknum != MAIN_FORKNUM)
+ if (forkNumber != MAIN_FORKNUM)
path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u_%s",
- rnode.spcNode, TABLESPACE_VERSION_DIRECTORY,
- rnode.dbNode, backend, rnode.relNode,
- forkNames[forknum]);
+ spcNode, TABLESPACE_VERSION_DIRECTORY,
+ dbNode, backendId, relNode,
+ forkNames[forkNumber]);
else
path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u",
- rnode.spcNode, TABLESPACE_VERSION_DIRECTORY,
- rnode.dbNode, backend, rnode.relNode);
+ spcNode, TABLESPACE_VERSION_DIRECTORY,
+ dbNode, backendId, relNode);
}
}
return path;