Just a heads up: I intend to push this shortly, and after it has seen some BF activity, pg_xlogdump as well.
-- Álvaro Herrera http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
*** a/src/backend/Makefile --- b/src/backend/Makefile *************** *** 35,44 **** LOCALOBJS += utils/probes.o endif endif ! OBJS = $(SUBDIROBJS) $(LOCALOBJS) $(top_builddir)/src/port/libpgport_srv.a ! # We put libpgport into OBJS, so remove it from LIBS; also add libldap ! LIBS := $(filter-out -lpgport, $(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)) --- 35,46 ---- endif endif ! OBJS = $(SUBDIROBJS) $(LOCALOBJS) $(top_builddir)/src/port/libpgport_srv.a \ ! $(top_builddir)/src/common/libpgcommon_srv.a ! # 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)) *** a/src/backend/access/rmgrdesc/smgrdesc.c --- b/src/backend/access/rmgrdesc/smgrdesc.c *************** *** 16,21 **** --- 16,22 ---- #include "catalog/catalog.h" #include "catalog/storage_xlog.h" + #include "common/relpath.h" void *** a/src/backend/access/rmgrdesc/xactdesc.c --- b/src/backend/access/rmgrdesc/xactdesc.c *************** *** 16,21 **** --- 16,22 ---- #include "access/xact.h" #include "catalog/catalog.h" + #include "common/relpath.h" #include "storage/sinval.h" #include "utils/timestamp.h" *** a/src/backend/access/transam/xlogutils.c --- b/src/backend/access/transam/xlogutils.c *************** *** 20,25 **** --- 20,26 ---- #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" *** a/src/backend/catalog/catalog.c --- b/src/backend/catalog/catalog.c *************** *** 37,42 **** --- 37,43 ---- #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,64 **** #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 --- 45,50 ---- *************** *** 80,209 **** forkname_to_number(char *forkName) } /* - * 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 * * Result is a palloc'd string. --- 66,71 ---- *** a/src/backend/commands/tablespace.c --- b/src/backend/commands/tablespace.c *************** *** 64,69 **** --- 64,70 ---- #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" *** a/src/backend/storage/buffer/bufmgr.c --- b/src/backend/storage/buffer/bufmgr.c *************** *** 34,39 **** --- 34,40 ---- #include <unistd.h> #include "catalog/catalog.h" + #include "common/relpath.h" #include "executor/instrument.h" #include "miscadmin.h" #include "pg_trace.h" *** a/src/backend/storage/buffer/localbuf.c --- b/src/backend/storage/buffer/localbuf.c *************** *** 16,21 **** --- 16,22 ---- #include "postgres.h" #include "catalog/catalog.h" + #include "common/relpath.h" #include "executor/instrument.h" #include "storage/buf_internals.h" #include "storage/bufmgr.h" *** a/src/backend/storage/file/fd.c --- b/src/backend/storage/file/fd.c *************** *** 71,76 **** --- 71,77 ---- #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" *** a/src/backend/storage/file/reinit.c --- b/src/backend/storage/file/reinit.c *************** *** 17,22 **** --- 17,23 ---- #include <unistd.h> #include "catalog/catalog.h" + #include "common/relpath.h" #include "storage/copydir.h" #include "storage/fd.h" #include "storage/reinit.h" *** a/src/backend/storage/smgr/md.c --- b/src/backend/storage/smgr/md.c *************** *** 21,26 **** --- 21,27 ---- #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" *** a/src/backend/utils/adt/dbsize.c --- b/src/backend/utils/adt/dbsize.c *************** *** 21,26 **** --- 21,27 ---- #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" *** a/src/backend/utils/adt/misc.c --- b/src/backend/utils/adt/misc.c *************** *** 24,29 **** --- 24,30 ---- #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" *** a/src/backend/utils/cache/relcache.c --- b/src/backend/utils/cache/relcache.c *************** *** 56,61 **** --- 56,62 ---- #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" *** a/src/common/Makefile --- b/src/common/Makefile *************** *** 23,35 **** include $(top_builddir)/src/Makefile.global override CPPFLAGS := -DFRONTEND $(CPPFLAGS) LIBS += $(PTHREAD_LIBS) ! OBJS_COMMON = OBJS_FRONTEND = $(OBJS_COMMON) fe_memutils.o OBJS_SRV = $(OBJS_COMMON:%.o=%_srv.o) ! all: libpgcommon.a # libpgcommon is needed by some contrib install: all installdirs --- 23,35 ---- override CPPFLAGS := -DFRONTEND $(CPPFLAGS) LIBS += $(PTHREAD_LIBS) ! OBJS_COMMON = relpath.o OBJS_FRONTEND = $(OBJS_COMMON) fe_memutils.o OBJS_SRV = $(OBJS_COMMON:%.o=%_srv.o) ! all: libpgcommon.a libpgcommon_srv.a # libpgcommon is needed by some contrib install: all installdirs *************** *** 60,64 **** libpgcommon_srv.a: $(OBJS_SRV) --- 60,71 ---- %_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) *** /dev/null --- b/src/common/relpath.c *************** *** 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; + } + *** a/src/include/catalog/catalog.h --- b/src/include/catalog/catalog.h *************** *** 14,47 **** #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); --- 14,27 ---- *** /dev/null --- b/src/include/common/relpath.h *************** *** 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 */ *** a/src/tools/msvc/Mkvcbuild.pm --- b/src/tools/msvc/Mkvcbuild.pm *************** *** 69,78 **** 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 @pgcommonbkndfiles = qw(); $libpgport = $solution->AddProject('libpgport', 'lib', 'misc'); $libpgport->AddDefine('FRONTEND'); --- 69,81 ---- sprompt.c tar.c thread.c getopt.c getopt_long.c dirent.c rint.c win32env.c win32error.c win32setlocale.c); ! our @pgcommonallfiles = qw( ! relpath.c); ! our @pgcommonfrontendfiles = (@pgcommonallfiles, ! qw(fe_memutils.c)); ! ! our @pgcommonbkndfiles = @pgcommonallfiles; $libpgport = $solution->AddProject('libpgport', 'lib', 'misc'); $libpgport->AddDefine('FRONTEND'); *************** *** 80,86 **** sub mkvcbuild $libpgcommon = $solution->AddProject('libpgcommon', 'lib', 'misc'); $libpgcommon->AddDefine('FRONTEND'); ! $libpgcommon->AddFiles('src\common', @pgcommonfiles); $postgres = $solution->AddProject('postgres', 'exe', '', 'src\backend'); $postgres->AddIncludeDir('src\backend'); --- 83,89 ---- $libpgcommon = $solution->AddProject('libpgcommon', 'lib', 'misc'); $libpgcommon->AddDefine('FRONTEND'); ! $libpgcommon->AddFiles('src\common', @pgcommonfrontendfiles); $postgres = $solution->AddProject('postgres', 'exe', '', 'src\backend'); $postgres->AddIncludeDir('src\backend');
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers