From 6816577a786cd9be257f6600e3cde2d86f5adb46 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sun, 13 Jul 2008 21:50:04 +0000
Subject: [PATCH] Change the PageGetContents() macro to guarantee its result is
 maxalign'd, thereby forestalling any problems with alignment of the data
 structure placed there.  Since SizeOfPageHeaderData is maxalign'd anyway in
 8.3 and HEAD, this does not actually change anything right now, but it is
 foreseeable that the header size will change again someday.  I had to fix a
 couple of places that were assuming that the content offset is just
 SizeOfPageHeaderData rather than MAXALIGN(SizeOfPageHeaderData).  Per
 discussion of Zdenek's page-macros patch.

---
 src/backend/storage/page/bufpage.c | 11 ++++-------
 src/include/access/gin.h           | 20 +++++++++++---------
 src/include/storage/bufpage.h      |  8 ++++++--
 3 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/src/backend/storage/page/bufpage.c b/src/backend/storage/page/bufpage.c
index c4af3b193fc..abfc569399e 100644
--- a/src/backend/storage/page/bufpage.c
+++ b/src/backend/storage/page/bufpage.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/storage/page/bufpage.c,v 1.79 2008/05/13 15:44:08 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/storage/page/bufpage.c,v 1.80 2008/07/13 21:50:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -260,7 +260,6 @@ Page
 PageGetTempPage(Page page, Size specialSize)
 {
 	Size		pageSize;
-	Size		size;
 	Page		temp;
 	PageHeader	thdr;
 
@@ -271,15 +270,13 @@ PageGetTempPage(Page page, Size specialSize)
 	/* copy old page in */
 	memcpy(temp, page, pageSize);
 
-	/* clear out the middle */
-	size = pageSize - SizeOfPageHeaderData;
-	size -= MAXALIGN(specialSize);
-	MemSet(PageGetContents(thdr), 0, size);
-
 	/* set high, low water marks */
 	thdr->pd_lower = SizeOfPageHeaderData;
 	thdr->pd_upper = pageSize - MAXALIGN(specialSize);
 
+	/* clear out the middle */
+	MemSet((char *) temp + thdr->pd_lower, 0, thdr->pd_upper - thdr->pd_lower);
+
 	return temp;
 }
 
diff --git a/src/include/access/gin.h b/src/include/access/gin.h
index f6a786d3db0..de29cff86ba 100644
--- a/src/include/access/gin.h
+++ b/src/include/access/gin.h
@@ -4,7 +4,7 @@
  *
  *	Copyright (c) 2006-2008, PostgreSQL Global Development Group
  *
- *	$PostgreSQL: pgsql/src/include/access/gin.h,v 1.23 2008/07/11 21:06:29 tgl Exp $
+ *	$PostgreSQL: pgsql/src/include/access/gin.h,v 1.24 2008/07/13 21:50:04 tgl Exp $
  *--------------------------------------------------------------------------
  */
 
@@ -121,17 +121,19 @@ typedef struct
 /*
  * Data (posting tree) pages
  */
+#define GinDataPageGetRightBound(page)	((ItemPointer) PageGetContents(page))
 #define GinDataPageGetData(page)	\
-	(PageGetContents(page)+MAXALIGN(sizeof(ItemPointerData)))
-#define GinDataPageGetRightBound(page)	((ItemPointer)PageGetContents(page))
-#define GinSizeOfItem(page) ( (GinPageIsLeaf(page)) ? sizeof(ItemPointerData) : sizeof(PostingItem) )
-#define GinDataPageGetItem(page,i) ( GinDataPageGetData(page) + ((i)-1) * GinSizeOfItem(page) )
+	(PageGetContents(page) + MAXALIGN(sizeof(ItemPointerData)))
+#define GinSizeOfItem(page)	\
+	(GinPageIsLeaf(page) ? sizeof(ItemPointerData) : sizeof(PostingItem))
+#define GinDataPageGetItem(page,i)	\
+	(GinDataPageGetData(page) + ((i)-1) * GinSizeOfItem(page))
 
 #define GinDataPageGetFreeSpace(page)	\
-	( BLCKSZ - SizeOfPageHeaderData - MAXALIGN(sizeof(GinPageOpaqueData)) - \
-		GinPageGetOpaque(page)->maxoff * GinSizeOfItem(page) - \
-		MAXALIGN(sizeof(ItemPointerData)))
-
+	(BLCKSZ - MAXALIGN(SizeOfPageHeaderData) \
+	 - MAXALIGN(sizeof(ItemPointerData)) \
+	 - GinPageGetOpaque(page)->maxoff * GinSizeOfItem(page) \
+	 - MAXALIGN(sizeof(GinPageOpaqueData)))
 
 
 #define GIN_UNLOCK	BUFFER_LOCK_UNLOCK
diff --git a/src/include/storage/bufpage.h b/src/include/storage/bufpage.h
index a52fb62a9fb..9a09121a697 100644
--- a/src/include/storage/bufpage.h
+++ b/src/include/storage/bufpage.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/storage/bufpage.h,v 1.81 2008/06/08 22:00:48 alvherre Exp $
+ * $PostgreSQL: pgsql/src/include/storage/bufpage.h,v 1.82 2008/07/13 21:50:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -206,9 +206,13 @@ typedef PageHeaderData *PageHeader;
 /*
  * PageGetContents
  *		To be used in case the page does not contain item pointers.
+ *
+ * Note: prior to 8.3 this was not guaranteed to yield a MAXALIGN'd result.
+ * Now it is.  Beware of old code that might think the offset to the contents
+ * is just SizeOfPageHeaderData rather than MAXALIGN(SizeOfPageHeaderData).
  */
 #define PageGetContents(page) \
-	((char *) (&((PageHeader) (page))->pd_linp[0]))
+	((char *) (page) + MAXALIGN(SizeOfPageHeaderData))
 
 /* ----------------
  *		macros to access page size info
-- 
GitLab