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)
signature.asc
Description: PGP signature