aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/pageinspect/brinfuncs.c2
-rw-r--r--contrib/pageinspect/btreefuncs.c2
-rw-r--r--contrib/pageinspect/fsmfuncs.c2
-rw-r--r--contrib/pageinspect/ginfuncs.c22
-rw-r--r--contrib/pageinspect/hashfuncs.c18
-rw-r--r--contrib/pageinspect/heapfuncs.c2
-rw-r--r--contrib/pageinspect/pageinspect.h21
-rw-r--r--contrib/pageinspect/rawpage.c38
8 files changed, 73 insertions, 34 deletions
diff --git a/contrib/pageinspect/brinfuncs.c b/contrib/pageinspect/brinfuncs.c
index 7b877e3d0ca..2c7963ec19b 100644
--- a/contrib/pageinspect/brinfuncs.c
+++ b/contrib/pageinspect/brinfuncs.c
@@ -9,6 +9,8 @@
*/
#include "postgres.h"
+#include "pageinspect.h"
+
#include "access/htup_details.h"
#include "access/brin.h"
#include "access/brin_internal.h"
diff --git a/contrib/pageinspect/btreefuncs.c b/contrib/pageinspect/btreefuncs.c
index 3f09d5f0a45..d50ec3a68d9 100644
--- a/contrib/pageinspect/btreefuncs.c
+++ b/contrib/pageinspect/btreefuncs.c
@@ -27,6 +27,8 @@
#include "postgres.h"
+#include "pageinspect.h"
+
#include "access/nbtree.h"
#include "catalog/namespace.h"
#include "catalog/pg_am.h"
diff --git a/contrib/pageinspect/fsmfuncs.c b/contrib/pageinspect/fsmfuncs.c
index 654164616be..615dab8b13b 100644
--- a/contrib/pageinspect/fsmfuncs.c
+++ b/contrib/pageinspect/fsmfuncs.c
@@ -19,6 +19,8 @@
#include "postgres.h"
+#include "pageinspect.h"
+
#include "funcapi.h"
#include "lib/stringinfo.h"
#include "miscadmin.h"
diff --git a/contrib/pageinspect/ginfuncs.c b/contrib/pageinspect/ginfuncs.c
index cea77d301ed..993fc2d9ae1 100644
--- a/contrib/pageinspect/ginfuncs.c
+++ b/contrib/pageinspect/ginfuncs.c
@@ -9,6 +9,8 @@
*/
#include "postgres.h"
+#include "pageinspect.h"
+
#include "access/gin.h"
#include "access/gin_private.h"
#include "access/htup_details.h"
@@ -29,26 +31,6 @@ PG_FUNCTION_INFO_V1(gin_page_opaque_info);
PG_FUNCTION_INFO_V1(gin_leafpage_items);
-static Page
-get_page_from_raw(bytea *raw_page)
-{
- int raw_page_size;
- Page page;
-
- raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
- if (raw_page_size < BLCKSZ)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("input page too small (%d bytes)", raw_page_size)));
-
- /* make a copy so that the page is properly aligned for struct access */
- page = palloc(raw_page_size);
- memcpy(page, VARDATA(raw_page), raw_page_size);
-
- return page;
-}
-
-
Datum
gin_metapage_info(PG_FUNCTION_ARGS)
{
diff --git a/contrib/pageinspect/hashfuncs.c b/contrib/pageinspect/hashfuncs.c
index 83b469864a9..49cb12e5189 100644
--- a/contrib/pageinspect/hashfuncs.c
+++ b/contrib/pageinspect/hashfuncs.c
@@ -10,6 +10,8 @@
#include "postgres.h"
+#include "pageinspect.h"
+
#include "access/hash.h"
#include "access/htup_details.h"
#include "catalog/pg_type.h"
@@ -48,27 +50,15 @@ typedef struct HashPageStat
/*
* Verify that the given bytea contains a HASH page, or die in the attempt.
- * A pointer to the page is returned.
+ * A pointer to a palloc'd, properly aligned copy of the page is returned.
*/
static Page
verify_hash_page(bytea *raw_page, int flags)
{
- Page page;
- int raw_page_size;
+ Page page = get_page_from_raw(raw_page);
int pagetype;
HashPageOpaque pageopaque;
- raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
-
- if (raw_page_size != BLCKSZ)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("invalid page size"),
- errdetail("Expected size %d, got %d",
- BLCKSZ, raw_page_size)));
-
- page = VARDATA(raw_page);
-
if (PageIsNew(page))
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
diff --git a/contrib/pageinspect/heapfuncs.c b/contrib/pageinspect/heapfuncs.c
index 748b1db0930..1448effb503 100644
--- a/contrib/pageinspect/heapfuncs.c
+++ b/contrib/pageinspect/heapfuncs.c
@@ -25,6 +25,8 @@
#include "postgres.h"
+#include "pageinspect.h"
+
#include "access/htup_details.h"
#include "funcapi.h"
#include "catalog/pg_type.h"
diff --git a/contrib/pageinspect/pageinspect.h b/contrib/pageinspect/pageinspect.h
new file mode 100644
index 00000000000..55ca68fab36
--- /dev/null
+++ b/contrib/pageinspect/pageinspect.h
@@ -0,0 +1,21 @@
+/*-------------------------------------------------------------------------
+ *
+ * pageinspect.h
+ * Common functions for pageinspect.
+ *
+ * Copyright (c) 2017, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * contrib/pageinspect/pageinspect.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef _PAGEINSPECT_H_
+#define _PAGEINSPECT_H_
+
+#include "storage/bufpage.h"
+
+/* in rawpage.c */
+extern Page get_page_from_raw(bytea *raw_page);
+
+#endif /* _PAGEINSPECT_H_ */
diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c
index a2ac078d404..102f360c6f7 100644
--- a/contrib/pageinspect/rawpage.c
+++ b/contrib/pageinspect/rawpage.c
@@ -15,6 +15,8 @@
#include "postgres.h"
+#include "pageinspect.h"
+
#include "access/htup_details.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
@@ -158,6 +160,42 @@ get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno)
return raw_page;
}
+
+/*
+ * get_page_from_raw
+ *
+ * Get a palloc'd, maxalign'ed page image from the result of get_raw_page()
+ *
+ * On machines with MAXALIGN = 8, the payload of a bytea is not maxaligned,
+ * since it will start 4 bytes into a palloc'd value. On alignment-picky
+ * machines, this will cause failures in accesses to 8-byte-wide values
+ * within the page. We don't need to worry if accessing only 4-byte or
+ * smaller fields, but when examining a struct that contains 8-byte fields,
+ * use this function for safety.
+ */
+Page
+get_page_from_raw(bytea *raw_page)
+{
+ Page page;
+ int raw_page_size;
+
+ raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
+
+ if (raw_page_size != BLCKSZ)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid page size"),
+ errdetail("Expected %d bytes, got %d.",
+ BLCKSZ, raw_page_size)));
+
+ page = palloc(raw_page_size);
+
+ memcpy(page, VARDATA(raw_page), raw_page_size);
+
+ return page;
+}
+
+
/*
* page_header
*