Make metapage stuff compile.
authorRobert Haas <rhaas@postgresql.org>
Tue, 29 May 2012 15:34:58 +0000 (11:34 -0400)
committerRobert Haas <rhaas@postgresql.org>
Thu, 14 Jun 2012 14:31:33 +0000 (10:31 -0400)
src/backend/access/common/Makefile
src/backend/access/common/metapage.c [new file with mode: 0644]
src/include/access/metapage.h [new file with mode: 0644]
src/include/storage/bufpage.h

index 1fa6de0823a5e8cf3d71052499452f53a1821d2d..b09d2f89d6866969a515d5285ceeae023b73aeca 100644 (file)
@@ -12,7 +12,7 @@ subdir = src/backend/access/common
 top_builddir = ../../../..
 include $(top_builddir)/src/Makefile.global
 
-OBJS = heaptuple.o indextuple.o printtup.o reloptions.o scankey.o \
+OBJS = heaptuple.o indextuple.o metapage.o printtup.o reloptions.o scankey.o \
        tupconvert.o tupdesc.o
 
 include $(top_srcdir)/src/backend/common.mk
diff --git a/src/backend/access/common/metapage.c b/src/backend/access/common/metapage.c
new file mode 100644 (file)
index 0000000..43cb089
--- /dev/null
@@ -0,0 +1,53 @@
+/*-------------------------------------------------------------------------
+ *
+ * metapage.c
+ *       Generic relation metapage support.
+ *
+ * Prior to PostgreSQL 9.3, some relation types (heap, gist) had no
+ * metapage at all, while others (btree, gin, hash, spgist) had only an
+ * access-method specific metapage.  Beginning in PostgreSQL 9.3, all
+ * relations have a metapage.  We reserve the first 512 bytes of each
+ * metablock for the page header and generic metadata that applies to all
+ * relation types; the remainder of the page may be used by each individual
+ * access method for its own purposes.
+ *
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *       src/backend/access/common/heaptuple.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include <time.h>
+
+#include "access/metapage.h"
+#include "storage/buf.h"
+
+/*
+ * Initialize a relation metapage.
+ */
+void
+MetapageInit(Relation relation, Page page)
+{
+       RelationMetaPage        meta;
+
+       PageSetRelationMetapage(page);
+
+       meta = BlindGetRelationMeta(page);
+       meta->rmp_magic = METAPAGE_MAGIC;
+       meta->rmp_version = METAPAGE_VERSION;
+       meta->rmp_dboid = relation->rd_node.dbNode;
+       meta->rmp_tsoid = relation->rd_node.spcNode;
+       meta->rmp_reloid = RelationGetRelid(relation);
+       meta->rmp_relfilenode = relation->rd_node.relNode;
+       meta->rmp_creation_time = (pg_time_t) time(NULL);
+       meta->rmp_rewrite_time = meta->rmp_creation_time;
+       meta->rmp_flags = 0;
+       meta->rmp_minlayout = PG_PAGE_LAYOUT_VERSION;
+       meta->rmp_maxlayout = PG_PAGE_LAYOUT_VERSION;
+}
diff --git a/src/include/access/metapage.h b/src/include/access/metapage.h
new file mode 100644 (file)
index 0000000..721abe2
--- /dev/null
@@ -0,0 +1,76 @@
+/*-------------------------------------------------------------------------
+ *
+ * metapage.h
+ *       Generic relation metapage support.
+ *
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/access/metapage.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef METAPAGE_H
+#define METAPAGE_H
+
+#include "pgtime.h"
+#include "storage/bufpage.h"
+#include "utils/rel.h"
+
+#define METAPAGE_MAGIC                         0x518f912a
+#define METAPAGE_VERSION                       1
+
+/*
+ * Metadata that is common to all relation types.  This information is stored
+ * at the beginning of each page, following the page-header, at the address
+ * returned by PageGetContents().
+ */
+typedef struct RelationMetaPageData
+{
+       uint32          rmp_magic;                      /* should contain METAPAGE_MAGIC */
+       uint32          rmp_version;            /* should contain METAPAGE_VERSION */
+       Oid                             rmp_dboid;                      /* database OID */
+       Oid                             rmp_tsoid;                      /* tablespace OID */
+       Oid                             rmp_reloid;                     /* relation OID */
+       Oid                             rmp_relfilenode;        /* relation relfilenode */
+       pg_time_t               rmp_creation_time;      /* time created, or 0 if unknown */
+       pg_time_t               rmp_rewrite_time;       /* last rewrite, or 0 if unknown */
+       uint32                  rmp_flags;                      /* relation-level flag bits */
+       uint16                  rmp_minlayout;          /* oldest page layout version in rel */
+       uint16                  rmp_maxlayout;          /* newest page layout version in rel */
+} RelationMetaPageData;
+
+typedef RelationMetaPageData *RelationMetaPage;
+
+/*
+ * Metadata that is specific to a particular access method is stored later
+ * in the page, following the common metadata.  In order to allow for future
+ * expansion of the common metadata, we start the access-method specific
+ * metadata 512 bytes from the beginning of the page.  That way, future
+ * versions of RelationMetaPageData can be larger without affecting the
+ * placement of data on the page.
+ *
+ * Prior to the introduction of metapages for all relations, access methods
+ * that had metapages stored their private metadata at the offset where
+ * common metadata is now stored.  Code that needs to read both old and new
+ * metapages can use GetAccessMethodMeta() to locate their data at whichever
+ * address it's stored, while code that knows it is looking at a new-format
+ * metapage can use BlindGetAccessMethodMeta() for efficiency.
+ */
+#define BlindGetRelationMeta(page) \
+       ((RelationMetaPage) PageGetContents((page)))
+#define ACCESS_METHOD_META_OFFSET 512
+#define BlindGetAccessMethodMeta(page) \
+       (((char *) (page)) + ACCESS_METHOD_META_OFFSET)
+#define GetRelationMeta(page) \
+       (PageIsRelationMetapage((page)) ? BlindGetRelationMeta((page)) : NULL)
+#define GetAccessMethodMeta(page)) \
+       (PageIsRelationMetapage((page)) ? BlindGetAccessMethodMeta((page)) \
+               : PageGetContents((page)))
+
+/*
+ * Function prototypes.
+ */
+extern void MetapageInit(Relation relation, Page page);
+
+#endif   /* METAPAGE_H */
index 1ab64e021d5e762e0a25eac892560726d692f638..3dac505822c51ac7e1f7665a54afe62ac12f7571 100644 (file)
@@ -154,8 +154,9 @@ typedef PageHeaderData *PageHeader;
                                                                                 * tuple? */
 #define PD_ALL_VISIBLE         0x0004          /* all tuples on page are visible to
                                                                                 * everyone */
+#define PD_RELATION_METAPAGE 0x0008            /* page is a relation metapage */
 
-#define PD_VALID_FLAG_BITS     0x0007          /* OR of all valid pd_flags bits */
+#define PD_VALID_FLAG_BITS     0x000F          /* OR of all valid pd_flags bits */
 
 /*
  * Page layout version number 0 is for pre-7.3 Postgres releases.
@@ -345,6 +346,11 @@ typedef PageHeaderData *PageHeader;
 #define PageClearAllVisible(page) \
        (((PageHeader) (page))->pd_flags &= ~PD_ALL_VISIBLE)
 
+#define PageIsRelationMetapage(page) \
+       (((PageHeader) (page))->pd_flags & PD_RELATION_METAPAGE)
+#define PageSetRelationMetapage(page) \
+       (((PageHeader) (page))->pd_flags |= PD_RELATION_METAPAGE)
+
 #define PageIsPrunable(page, oldestxmin) \
 ( \
        AssertMacro(TransactionIdIsNormal(oldestxmin)), \