From: Alvaro Herrera Date: Fri, 22 Feb 2013 01:46:17 +0000 (-0300) Subject: Move relpath() to libpgcommon X-Git-Tag: REL9_3_BETA1~321 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a73018392636ce832b09b5c31f6ad1f18a4643ea;p=postgresql Move relpath() to libpgcommon 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. --- diff --git a/src/backend/Makefile b/src/backend/Makefile index 323b417ed7..318cdbcf76 100644 --- a/src/backend/Makefile +++ b/src/backend/Makefile @@ -35,10 +35,12 @@ LOCALOBJS += utils/probes.o endif endif -OBJS = $(SUBDIROBJS) $(LOCALOBJS) $(top_builddir)/src/port/libpgport_srv.a +OBJS = $(SUBDIROBJS) $(LOCALOBJS) $(top_builddir)/src/port/libpgport_srv.a \ + $(top_builddir)/src/common/libpgcommon_srv.a -# We put libpgport into OBJS, so remove it from LIBS; also add libldap -LIBS := $(filter-out -lpgport, $(LIBS)) $(LDAP_LIBS_BE) +# We put libpgport and libpgcommon into OBJS, so remove it from LIBS; also add +# libldap +LIBS := $(filter-out -lpgport -lpgcommon, $(LIBS)) $(LDAP_LIBS_BE) # The backend doesn't need everything that's in LIBS, however LIBS := $(filter-out -lz -lreadline -ledit -ltermcap -lncurses -lcurses, $(LIBS)) diff --git a/src/backend/access/rmgrdesc/smgrdesc.c b/src/backend/access/rmgrdesc/smgrdesc.c index bcabf8993a..176d8142a6 100644 --- a/src/backend/access/rmgrdesc/smgrdesc.c +++ b/src/backend/access/rmgrdesc/smgrdesc.c @@ -16,6 +16,7 @@ #include "catalog/catalog.h" #include "catalog/storage_xlog.h" +#include "common/relpath.h" void diff --git a/src/backend/access/rmgrdesc/xactdesc.c b/src/backend/access/rmgrdesc/xactdesc.c index 247127999e..11c6912753 100644 --- a/src/backend/access/rmgrdesc/xactdesc.c +++ b/src/backend/access/rmgrdesc/xactdesc.c @@ -16,6 +16,7 @@ #include "access/xact.h" #include "catalog/catalog.h" +#include "common/relpath.h" #include "storage/sinval.h" #include "utils/timestamp.h" diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c index f9a6e628b7..5429d5ed5e 100644 --- a/src/backend/access/transam/xlogutils.c +++ b/src/backend/access/transam/xlogutils.c @@ -20,6 +20,7 @@ #include "access/xlog.h" #include "access/xlogutils.h" #include "catalog/catalog.h" +#include "common/relpath.h" #include "storage/smgr.h" #include "utils/guc.h" #include "utils/hsearch.h" diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c index 968648627c..967182b541 100644 --- a/src/backend/catalog/catalog.c +++ b/src/backend/catalog/catalog.c @@ -37,6 +37,7 @@ #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" @@ -44,21 +45,6 @@ #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 @@ -79,130 +65,6 @@ forkname_to_number(char *forkName) 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 * diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 9bba75be1a..7cad0cc969 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -64,6 +64,7 @@ #include "commands/comment.h" #include "commands/seclabel.h" #include "commands/tablespace.h" +#include "common/relpath.h" #include "miscadmin.h" #include "postmaster/bgwriter.h" #include "storage/fd.h" diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 405ff61130..ea7d469f2f 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -34,6 +34,7 @@ #include #include "catalog/catalog.h" +#include "common/relpath.h" #include "executor/instrument.h" #include "miscadmin.h" #include "pg_trace.h" diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c index df15789e6a..30dc8098ed 100644 --- a/src/backend/storage/buffer/localbuf.c +++ b/src/backend/storage/buffer/localbuf.c @@ -16,6 +16,7 @@ #include "postgres.h" #include "catalog/catalog.h" +#include "common/relpath.h" #include "executor/instrument.h" #include "storage/buf_internals.h" #include "storage/bufmgr.h" diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index ff7e221cde..ba1b84eade 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -71,6 +71,7 @@ #include "access/xact.h" #include "catalog/catalog.h" #include "catalog/pg_tablespace.h" +#include "common/relpath.h" #include "pgstat.h" #include "storage/fd.h" #include "storage/ipc.h" diff --git a/src/backend/storage/file/reinit.c b/src/backend/storage/file/reinit.c index 2623be8aef..d62d5848a7 100644 --- a/src/backend/storage/file/reinit.c +++ b/src/backend/storage/file/reinit.c @@ -17,6 +17,7 @@ #include #include "catalog/catalog.h" +#include "common/relpath.h" #include "storage/copydir.h" #include "storage/fd.h" #include "storage/reinit.h" diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index 20eb36a85f..7d567ae110 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -21,6 +21,7 @@ #include "miscadmin.h" #include "access/xlog.h" #include "catalog/catalog.h" +#include "common/relpath.h" #include "portability/instr_time.h" #include "postmaster/bgwriter.h" #include "storage/fd.h" diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c index 89ad3868ba..11b004072f 100644 --- a/src/backend/utils/adt/dbsize.c +++ b/src/backend/utils/adt/dbsize.c @@ -21,6 +21,7 @@ #include "catalog/pg_tablespace.h" #include "commands/dbcommands.h" #include "commands/tablespace.h" +#include "common/relpath.h" #include "miscadmin.h" #include "storage/fd.h" #include "utils/acl.h" diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index a36d065abf..4e38d7c06c 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -24,6 +24,7 @@ #include "catalog/pg_tablespace.h" #include "catalog/pg_type.h" #include "commands/dbcommands.h" +#include "common/relpath.h" #include "funcapi.h" #include "miscadmin.h" #include "parser/keywords.h" diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index b9c03c3115..e85c7a9872 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -56,6 +56,7 @@ #include "catalog/schemapg.h" #include "catalog/storage.h" #include "commands/trigger.h" +#include "common/relpath.h" #include "miscadmin.h" #include "optimizer/clauses.h" #include "optimizer/planmain.h" diff --git a/src/common/Makefile b/src/common/Makefile index 55d7b5b935..cd97980ce6 100644 --- a/src/common/Makefile +++ b/src/common/Makefile @@ -23,13 +23,13 @@ include $(top_builddir)/src/Makefile.global override CPPFLAGS := -DFRONTEND $(CPPFLAGS) LIBS += $(PTHREAD_LIBS) -OBJS_COMMON = +OBJS_COMMON = relpath.o OBJS_FRONTEND = $(OBJS_COMMON) fe_memutils.o OBJS_SRV = $(OBJS_COMMON:%.o=%_srv.o) -all: libpgcommon.a +all: libpgcommon.a libpgcommon_srv.a # libpgcommon is needed by some contrib install: all installdirs @@ -60,5 +60,12 @@ libpgcommon_srv.a: $(OBJS_SRV) %_srv.o: %.c %.o $(CC) $(CFLAGS) $(subst -DFRONTEND,, $(CPPFLAGS)) -c $< -o $@ +$(OBJS_SRV): | submake-errcodes + +.PHONY: submake-errcodes + +submake-errcodes: + $(MAKE) -C ../backend submake-errcodes + clean distclean maintainer-clean: rm -f libpgcommon.a libpgcommon_srv.a $(OBJS_FRONTEND) $(OBJS_SRV) diff --git a/src/common/relpath.c b/src/common/relpath.c new file mode 100644 index 0000000000..18fe4d1fe3 --- /dev/null +++ b/src/common/relpath.c @@ -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; +} + diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index 5d506fe78b..44b6f38743 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -14,34 +14,14 @@ #ifndef 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 "storage/relfilenode.h" #include "utils/relcache.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 ForkNumber forkname_to_number(char *forkName); -extern int forkname_chars(const char *str, ForkNumber *); -extern char *relpathbackend(RelFileNode rnode, BackendId backend, - ForkNumber forknum); extern char *GetDatabasePath(Oid dbNode, Oid spcNode); -/* 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)) extern bool IsSystemRelation(Relation relation); extern bool IsToastRelation(Relation relation); diff --git a/src/include/common/relpath.h b/src/include/common/relpath.h new file mode 100644 index 0000000000..5b28bd0361 --- /dev/null +++ b/src/include/common/relpath.h @@ -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 */ diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm index ad797ffa6c..9bca46fa94 100644 --- a/src/tools/msvc/Mkvcbuild.pm +++ b/src/tools/msvc/Mkvcbuild.pm @@ -69,10 +69,13 @@ sub mkvcbuild sprompt.c tar.c thread.c getopt.c getopt_long.c dirent.c rint.c win32env.c win32error.c win32setlocale.c); - our @pgcommonfiles = qw( - fe_memutils.c); + our @pgcommonallfiles = qw( + relpath.c); - our @pgcommonbkndfiles = qw(); + our @pgcommonfrontendfiles = (@pgcommonallfiles, + qw(fe_memutils.c)); + + our @pgcommonbkndfiles = @pgcommonallfiles; $libpgport = $solution->AddProject('libpgport', 'lib', 'misc'); $libpgport->AddDefine('FRONTEND'); @@ -80,7 +83,7 @@ sub mkvcbuild $libpgcommon = $solution->AddProject('libpgcommon', 'lib', 'misc'); $libpgcommon->AddDefine('FRONTEND'); - $libpgcommon->AddFiles('src\common', @pgcommonfiles); + $libpgcommon->AddFiles('src\common', @pgcommonfrontendfiles); $postgres = $solution->AddProject('postgres', 'exe', '', 'src\backend'); $postgres->AddIncludeDir('src\backend');