On Thu, Mar 31, 2022 at 12:09:35PM +0200, Matthias van de Meent wrote:
> PageInit MAXALIGNs the size of the special area that it receives as an
> argument; so any changes to the page header that would misalign the
> value would be AM-specific; in which case it is quite unlikely that
> this is the right accessor for your page's special area.

Right.  I'd still be tempted to keep that per-AM rather than making
the checks deeper with one extra macro layer in the page header or
with a different macro that would depend on the opaque type, though.
Like in the attached, for example.
--
Michael
diff --git a/src/include/access/ginblock.h b/src/include/access/ginblock.h
index 9347f464f3..050fff80dc 100644
--- a/src/include/access/ginblock.h
+++ b/src/include/access/ginblock.h
@@ -108,7 +108,11 @@ typedef struct GinMetaPageData
 /*
  * Macros for accessing a GIN index page's opaque data
  */
-#define GinPageGetOpaque(page) ( (GinPageOpaque) PageGetSpecialPointer(page) )
+#define GinPageGetOpaque(page) \
+( \
+	AssertMacro(PageGetSpecialSize(page) == MAXALIGN(sizeof(GinPageOpaqueData))), \
+	(GinPageOpaque) PageGetSpecialPointer(page) \
+)
 
 #define GinPageIsLeaf(page)    ( (GinPageGetOpaque(page)->flags & GIN_LEAF) != 0 )
 #define GinPageSetLeaf(page)   ( GinPageGetOpaque(page)->flags |= GIN_LEAF )
diff --git a/src/include/access/gist.h b/src/include/access/gist.h
index a3337627b8..a10caf8ae9 100644
--- a/src/include/access/gist.h
+++ b/src/include/access/gist.h
@@ -164,7 +164,11 @@ typedef struct GISTENTRY
 	bool		leafkey;
 } GISTENTRY;
 
-#define GistPageGetOpaque(page) ( (GISTPageOpaque) PageGetSpecialPointer(page) )
+#define GistPageGetOpaque(page) \
+( \
+	AssertMacro(PageGetSpecialSize(page) == MAXALIGN(sizeof(GISTPageOpaqueData))), \
+	(GISTPageOpaque) PageGetSpecialPointer(page) \
+)
 
 #define GistPageIsLeaf(page)	( GistPageGetOpaque(page)->flags & F_LEAF)
 #define GIST_LEAF(entry) (GistPageIsLeaf((entry)->page))
diff --git a/src/include/access/hash.h b/src/include/access/hash.h
index da372841c4..b442ddc4c8 100644
--- a/src/include/access/hash.h
+++ b/src/include/access/hash.h
@@ -85,7 +85,11 @@ typedef struct HashPageOpaqueData
 
 typedef HashPageOpaqueData *HashPageOpaque;
 
-#define HashPageGetOpaque(page) ((HashPageOpaque) PageGetSpecialPointer(page))
+#define HashPageGetOpaque(page) \
+( \
+	AssertMacro(PageGetSpecialSize(page) == MAXALIGN(sizeof(HashPageOpaqueData))), \
+	(HashPageOpaque) PageGetSpecialPointer(page) \
+)
 
 #define H_NEEDS_SPLIT_CLEANUP(opaque)	(((opaque)->hasho_flag & LH_BUCKET_NEEDS_SPLIT_CLEANUP) != 0)
 #define H_BUCKET_BEING_SPLIT(opaque)	(((opaque)->hasho_flag & LH_BUCKET_BEING_SPLIT) != 0)
diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h
index 93f8267b48..e11839857d 100644
--- a/src/include/access/nbtree.h
+++ b/src/include/access/nbtree.h
@@ -70,7 +70,11 @@ typedef struct BTPageOpaqueData
 
 typedef BTPageOpaqueData *BTPageOpaque;
 
-#define BTPageGetOpaque(page) ((BTPageOpaque) PageGetSpecialPointer(page))
+#define BTPageGetOpaque(page) \
+( \
+	AssertMacro(PageGetSpecialSize(page) == MAXALIGN(sizeof(BTPageOpaqueData))), \
+	(BTPageOpaque) PageGetSpecialPointer(page) \
+)
 
 /* Bits defined in btpo_flags */
 #define BTP_LEAF		(1 << 0)	/* leaf page, i.e. not internal page */
diff --git a/src/include/access/spgist_private.h b/src/include/access/spgist_private.h
index eb56b1c6b8..d61433b5af 100644
--- a/src/include/access/spgist_private.h
+++ b/src/include/access/spgist_private.h
@@ -75,7 +75,12 @@ typedef SpGistPageOpaqueData *SpGistPageOpaque;
 #define SPGIST_LEAF			(1<<2)
 #define SPGIST_NULLS		(1<<3)
 
-#define SpGistPageGetOpaque(page) ((SpGistPageOpaque) PageGetSpecialPointer(page))
+#define SpGistPageGetOpaque(page) \
+( \
+	AssertMacro(PageGetSpecialSize(page) == MAXALIGN(sizeof(SpGistPageOpaqueData))), \
+	(SpGistPageOpaque) PageGetSpecialPointer(page) \
+)
+
 #define SpGistPageIsMeta(page) (SpGistPageGetOpaque(page)->flags & SPGIST_META)
 #define SpGistPageIsDeleted(page) (SpGistPageGetOpaque(page)->flags & SPGIST_DELETED)
 #define SpGistPageIsLeaf(page) (SpGistPageGetOpaque(page)->flags & SPGIST_LEAF)

Attachment: signature.asc
Description: PGP signature

Reply via email to