From e4ff58468a812bbeba377b957956ea18a9e100d4 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 16 May 2022 09:58:13 +0200 Subject: [PATCH] Convert macros to static inline functions (bufpage.h) rawpage.c needs some adjustments because it was previously playing loose with the Page vs. PageHeader types, which is no longer possible with the functions instead of macros. --- contrib/pageinspect/rawpage.c | 24 ++++--- src/include/storage/bufpage.h | 125 ++++++++++++++++++++-------------- 2 files changed, 86 insertions(+), 63 deletions(-) diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c index 730a46b1d8..90942be71e 100644 --- a/contrib/pageinspect/rawpage.c +++ b/contrib/pageinspect/rawpage.c @@ -254,7 +254,8 @@ page_header(PG_FUNCTION_ARGS) Datum values[9]; bool nulls[9]; - PageHeader page; + Page page; + PageHeader pageheader; XLogRecPtr lsn; if (!superuser()) @@ -262,7 +263,8 @@ page_header(PG_FUNCTION_ARGS) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to use raw page functions"))); - page = (PageHeader) get_page_from_raw(raw_page); + page = get_page_from_raw(raw_page); + pageheader = (PageHeader) page; /* Build a tuple descriptor for our result type */ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) @@ -282,8 +284,8 @@ page_header(PG_FUNCTION_ARGS) } else values[0] = LSNGetDatum(lsn); - values[1] = UInt16GetDatum(page->pd_checksum); - values[2] = UInt16GetDatum(page->pd_flags); + values[1] = UInt16GetDatum(pageheader->pd_checksum); + values[2] = UInt16GetDatum(pageheader->pd_flags); /* pageinspect >= 1.10 uses int4 instead of int2 for those fields */ switch (TupleDescAttr(tupdesc, 3)->atttypid) @@ -292,18 +294,18 @@ page_header(PG_FUNCTION_ARGS) Assert(TupleDescAttr(tupdesc, 4)->atttypid == INT2OID && TupleDescAttr(tupdesc, 5)->atttypid == INT2OID && TupleDescAttr(tupdesc, 6)->atttypid == INT2OID); - values[3] = UInt16GetDatum(page->pd_lower); - values[4] = UInt16GetDatum(page->pd_upper); - values[5] = UInt16GetDatum(page->pd_special); + values[3] = UInt16GetDatum(pageheader->pd_lower); + values[4] = UInt16GetDatum(pageheader->pd_upper); + values[5] = UInt16GetDatum(pageheader->pd_special); values[6] = UInt16GetDatum(PageGetPageSize(page)); break; case INT4OID: Assert(TupleDescAttr(tupdesc, 4)->atttypid == INT4OID && TupleDescAttr(tupdesc, 5)->atttypid == INT4OID && TupleDescAttr(tupdesc, 6)->atttypid == INT4OID); - values[3] = Int32GetDatum(page->pd_lower); - values[4] = Int32GetDatum(page->pd_upper); - values[5] = Int32GetDatum(page->pd_special); + values[3] = Int32GetDatum(pageheader->pd_lower); + values[4] = Int32GetDatum(pageheader->pd_upper); + values[5] = Int32GetDatum(pageheader->pd_special); values[6] = Int32GetDatum(PageGetPageSize(page)); break; default: @@ -312,7 +314,7 @@ page_header(PG_FUNCTION_ARGS) } values[7] = UInt16GetDatum(PageGetPageLayoutVersion(page)); - values[8] = TransactionIdGetDatum(page->pd_prune_xid); + values[8] = TransactionIdGetDatum(pageheader->pd_prune_xid); /* Build and return the tuple. */ diff --git a/src/include/storage/bufpage.h b/src/include/storage/bufpage.h index e9f253f2c8..6d5d6b2b0d 100644 --- a/src/include/storage/bufpage.h +++ b/src/include/storage/bufpage.h @@ -14,6 +14,7 @@ #ifndef BUFPAGE_H #define BUFPAGE_H +#include "access/transam.h" #include "access/xlogdefs.h" #include "storage/block.h" #include "storage/item.h" @@ -97,8 +98,12 @@ typedef struct uint32 xrecoff; /* low bits */ } PageXLogRecPtr; -#define PageXLogRecPtrGet(val) \ - ((uint64) (val).xlogid << 32 | (val).xrecoff) + +static inline XLogRecPtr +PageXLogRecPtrGet(PageXLogRecPtr val) +{ + return (uint64) val.xlogid << 32 | val.xrecoff; +} #define PageXLogRecPtrSet(ptr, lsn) \ ((ptr).xlogid = (uint32) ((lsn) >> 32), (ptr).xrecoff = (uint32) (lsn)) @@ -200,7 +205,7 @@ typedef PageHeaderData *PageHeader; #define PG_DATA_CHECKSUM_VERSION 1 /* ---------------------------------------------------------------- - * page support macros + * page support macros and functions * ---------------------------------------------------------------- */ @@ -247,7 +252,7 @@ typedef PageHeaderData *PageHeader; ((char *) (page) + MAXALIGN(SizeOfPageHeaderData)) /* ---------------- - * macros to access page size info + * macros and functions to access page size info * ---------------- */ @@ -265,15 +270,21 @@ typedef PageHeaderData *PageHeader; * BufferGetPageSize, which can be called on an unformatted page). * however, it can be called on a page that is not stored in a buffer. */ -#define PageGetPageSize(page) \ - ((Size) (((PageHeader) (page))->pd_pagesize_version & (uint16) 0xFF00)) +static inline Size +PageGetPageSize(Page page) +{ + return (Size) (((PageHeader) page)->pd_pagesize_version & (uint16) 0xFF00); +} /* * PageGetPageLayoutVersion * Returns the page layout version of a page. */ -#define PageGetPageLayoutVersion(page) \ - (((PageHeader) (page))->pd_pagesize_version & 0x00FF) +static inline uint8 +PageGetPageLayoutVersion(Page page) +{ + return (((PageHeader) page)->pd_pagesize_version & 0x00FF); +} /* * PageSetPageSizeAndVersion @@ -282,52 +293,52 @@ typedef PageHeaderData *PageHeader; * We could support setting these two values separately, but there's * no real need for it at the moment. */ -#define PageSetPageSizeAndVersion(page, size, version) \ -( \ - AssertMacro(((size) & 0xFF00) == (size)), \ - AssertMacro(((version) & 0x00FF) == (version)), \ - ((PageHeader) (page))->pd_pagesize_version = (size) | (version) \ -) +static inline void +PageSetPageSizeAndVersion(Page page, Size size, uint8 version) +{ + Assert((size & 0xFF00) == size); + Assert((version & 0x00FF) == version); + + ((PageHeader) page)->pd_pagesize_version = size | version; +} /* ---------------- - * page special data macros + * page special data macros and functions * ---------------- */ /* * PageGetSpecialSize * Returns size of special space on a page. */ -#define PageGetSpecialSize(page) \ - ((uint16) (PageGetPageSize(page) - ((PageHeader)(page))->pd_special)) +static inline uint16 +PageGetSpecialSize(Page page) +{ + return ((uint16) (PageGetPageSize(page) - ((PageHeader) page)->pd_special)); +} /* * Using assertions, validate that the page special pointer is OK. * * This is intended to catch use of the pointer before page initialization. - * It is implemented as a function due to the limitations of the MSVC - * compiler, which choked on doing all these tests within another macro. We - * return true so that AssertMacro() can be used while still getting the - * specifics from the macro failure within this function. */ -static inline bool +static inline void PageValidateSpecialPointer(Page page) { Assert(PageIsValid(page)); Assert(((PageHeader) (page))->pd_special <= BLCKSZ); Assert(((PageHeader) (page))->pd_special >= SizeOfPageHeaderData); - - return true; } /* * PageGetSpecialPointer * Returns pointer to special space on a page. */ -#define PageGetSpecialPointer(page) \ -( \ - AssertMacro(PageValidateSpecialPointer(page)), \ - (char *) ((char *) (page) + ((PageHeader) (page))->pd_special) \ -) +static inline char * +PageGetSpecialPointer(Page page) +{ + PageValidateSpecialPointer(page); + return (char *) page + ((PageHeader) page)->pd_special; +} /* * PageGetItem @@ -337,12 +348,14 @@ PageValidateSpecialPointer(Page page) * This does not change the status of any of the resources passed. * The semantics may change in the future. */ -#define PageGetItem(page, itemId) \ -( \ - AssertMacro(PageIsValid(page)), \ - AssertMacro(ItemIdHasStorage(itemId)), \ - (Item)(((char *)(page)) + ItemIdGetOffset(itemId)) \ -) +static inline Item +PageGetItem(Page page, ItemId itemId) +{ + Assert(PageIsValid(page)); + Assert(ItemIdHasStorage(itemId)); + + return (Item) (((char *) page) + ItemIdGetOffset(itemId)); +} /* * PageGetMaxOffsetNumber @@ -351,17 +364,19 @@ PageValidateSpecialPointer(Page page) * of items on the page. * * NOTE: if the page is not initialized (pd_lower == 0), we must - * return zero to ensure sane behavior. Accept double evaluation - * of the argument so that we can ensure this. + * return zero to ensure sane behavior. */ -#define PageGetMaxOffsetNumber(page) \ - (((PageHeader) (page))->pd_lower <= SizeOfPageHeaderData ? 0 : \ - ((((PageHeader) (page))->pd_lower - SizeOfPageHeaderData) \ - / sizeof(ItemIdData))) +static inline OffsetNumber +PageGetMaxOffsetNumber(Page page) +{ + if (((PageHeader) page)->pd_lower <= SizeOfPageHeaderData) + return 0; + else + return ((((PageHeader) page)->pd_lower - SizeOfPageHeaderData) / sizeof(ItemIdData)); +} /* - * Additional macros for access to page headers. (Beware multiple evaluation - * of the arguments!) + * Additional macros and functions for access to page headers. */ #define PageGetLSN(page) \ PageXLogRecPtrGet(((PageHeader) (page))->pd_lsn) @@ -389,15 +404,21 @@ PageValidateSpecialPointer(Page page) #define PageClearAllVisible(page) \ (((PageHeader) (page))->pd_flags &= ~PD_ALL_VISIBLE) -#define PageSetPrunable(page, xid) \ -do { \ - Assert(TransactionIdIsNormal(xid)); \ - if (!TransactionIdIsValid(((PageHeader) (page))->pd_prune_xid) || \ - TransactionIdPrecedes(xid, ((PageHeader) (page))->pd_prune_xid)) \ - ((PageHeader) (page))->pd_prune_xid = (xid); \ -} while (0) -#define PageClearPrunable(page) \ - (((PageHeader) (page))->pd_prune_xid = InvalidTransactionId) +static inline void +PageSetPrunable(Page page, TransactionId xid) +{ + Assert(TransactionIdIsNormal(xid)); + + if (!TransactionIdIsValid(((PageHeader) page)->pd_prune_xid) || + TransactionIdPrecedes(xid, ((PageHeader) page)->pd_prune_xid)) + ((PageHeader) page)->pd_prune_xid = xid; +} + +static inline void +PageClearPrunable(Page page) +{ + ((PageHeader) page)->pd_prune_xid = InvalidTransactionId; +} /* ---------------------------------------------------------------- -- 2.35.1