From 9f163f7172ffecfcfe6c46013b82aa410e98c020 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 3 Nov 2026 15:39:36 +0100 Subject: [PATCH 04/10] Fix -Wcast-qual warning in XLogInsertRecord() XLogInsertRecord() obtained the record header by casting the data pointer of the first entry of the XLogRecData chain: XLogRecord *rechdr = (XLogRecord *) rdata->data; This casts away the const qualifier on XLogRecData.data. And XLogInsertRecord() really does write through that pointer. To fix, don't derive the header pointer from the chain but instead pass the record header to XLogInsertRecord() as a separate argument that is not const. --- src/backend/access/transam/xlog.c | 13 ++++++++----- src/backend/access/transam/xloginsert.c | 3 ++- src/include/access/xlog.h | 4 +++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 8636ad9ab2c..d20c91dcde2 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -824,9 +824,11 @@ static XLogRecPtr XLogChecksums(uint32 new_type); * current subtransaction. See XLogRecordAssemble(). * * The first XLogRecData in the chain must be for the record header, and its - * data must be MAXALIGNed. XLogInsertRecord fills in the xl_prev and - * xl_crc fields in the header, the rest of the header must already be filled - * by the caller. + * data must be MAXALIGNed. 'rechdr' must point to that same record header; + * it is passed separately because the data pointers in the chain are const. + * XLogInsertRecord fills in the xl_prev and xl_crc fields in the header + * through 'rechdr', the rest of the header must already be filled by the + * caller. * * Returns XLOG pointer to end of record (beginning of next record). * This can be used as LSN for data pages affected by the logged action. @@ -835,7 +837,8 @@ static XLogRecPtr XLogChecksums(uint32 new_type); * WAL rule "write the log before the data".) */ XLogRecPtr -XLogInsertRecord(XLogRecData *rdata, +XLogInsertRecord(XLogRecord *rechdr, + XLogRecData *rdata, XLogRecPtr fpw_lsn, uint8 flags, int num_fpi, @@ -845,7 +848,6 @@ XLogInsertRecord(XLogRecData *rdata, XLogCtlInsert *Insert = &XLogCtl->Insert; pg_crc32c rdata_crc; bool inserted; - XLogRecord *rechdr = (XLogRecord *) rdata->data; uint8 info = rechdr->xl_info & ~XLR_INFO_MASK; WalInsertClass class = WALINSERT_NORMAL; XLogRecPtr StartPos; @@ -863,6 +865,7 @@ XLogInsertRecord(XLogRecData *rdata, } /* we assume that all of the record header is in the first chunk */ + Assert(rdata->data == rechdr); Assert(rdata->len >= SizeOfXLogRecord); /* cross-check on whether we should be here or not */ diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c index 341deb7b80d..3e5aca79cdf 100644 --- a/src/backend/access/transam/xloginsert.c +++ b/src/backend/access/transam/xloginsert.c @@ -534,7 +534,8 @@ XLogInsert(RmgrId rmid, uint8 info) &fpw_lsn, &num_fpi, &fpi_bytes, &topxid_included); - EndPos = XLogInsertRecord(rdt, fpw_lsn, curinsert_flags, num_fpi, + EndPos = XLogInsertRecord((XLogRecord *) hdr_scratch, rdt, fpw_lsn, + curinsert_flags, num_fpi, fpi_bytes, topxid_included); } while (!XLogRecPtrIsValid(EndPos)); diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 2bf5714b51e..966b41a7d89 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -220,10 +220,12 @@ typedef enum WALAvailability WALAVAIL_REMOVED, /* WAL segment has been removed */ } WALAvailability; +struct XLogRecord; struct XLogRecData; struct XLogReaderState; -extern XLogRecPtr XLogInsertRecord(struct XLogRecData *rdata, +extern XLogRecPtr XLogInsertRecord(struct XLogRecord *rechdr, + struct XLogRecData *rdata, XLogRecPtr fpw_lsn, uint8 flags, int num_fpi, -- 2.56.0