From b300dfe9f8525b28d3ff0fe397315b3c6a0de379 Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Date: Wed, 29 Oct 2025 10:34:03 +0000
Subject: [PATCH v5 1/4] Introduce XLogRecPtrIsValid() and replace
 XLogRecPtrIsInvalid() calls

XLogRecPtrIsInvalid() is inconsistent with the affirmative form of other
*IsValid() macros and leads to awkward double negative.

This commit introduces XLogRecPtrIsValid() and replace all the
XLogRecPtrIsInvalid() calls.

It also adds a comment mentioning that new code should use XLogRecPtrIsValid()
instead of XLogRecPtrIsInvalid() and that XLogRecPtrIsInvalid() could be
deprecated in the future.
---
 contrib/pg_walinspect/pg_walinspect.c         |  4 +--
 src/backend/access/gist/gist.c                |  4 +--
 src/backend/access/gist/gistget.c             |  4 +--
 src/backend/access/gist/gistutil.c            |  2 +-
 src/backend/access/heap/visibilitymap.c       |  4 +--
 src/backend/access/transam/clog.c             |  5 ++--
 src/backend/access/transam/slru.c             |  2 +-
 src/backend/access/transam/timeline.c         |  4 +--
 src/backend/access/transam/twophase.c         |  4 +--
 src/backend/access/transam/xlog.c             | 30 +++++++++----------
 src/backend/access/transam/xlogbackup.c       |  4 +--
 src/backend/access/transam/xlogreader.c       |  6 ++--
 src/backend/access/transam/xlogrecovery.c     | 12 ++++----
 src/backend/access/transam/xlogwait.c         |  2 +-
 src/backend/backup/backup_manifest.c          |  4 +--
 src/backend/backup/basebackup_incremental.c   |  2 +-
 src/backend/backup/walsummary.c               |  8 ++---
 src/backend/commands/subscriptioncmds.c       |  6 ++--
 src/backend/postmaster/walsummarizer.c        | 18 +++++------
 .../replication/logical/applyparallelworker.c |  4 +--
 src/backend/replication/logical/launcher.c    |  4 +--
 src/backend/replication/logical/logical.c     |  2 +-
 .../replication/logical/logicalfuncs.c        |  2 +-
 src/backend/replication/logical/slotsync.c    |  6 ++--
 src/backend/replication/logical/worker.c      | 16 +++++-----
 src/backend/replication/slot.c                | 10 +++----
 src/backend/replication/slotfuncs.c           | 16 +++++-----
 src/backend/replication/syncrep.c             | 10 +++----
 src/backend/replication/walreceiver.c         |  8 ++---
 src/backend/replication/walsender.c           | 22 +++++++-------
 src/backend/storage/buffer/bufmgr.c           |  2 +-
 src/bin/pg_basebackup/pg_receivewal.c         |  2 +-
 src/bin/pg_basebackup/pg_recvlogical.c        |  2 +-
 src/bin/pg_rewind/pg_rewind.c                 |  4 +--
 src/bin/pg_waldump/pg_waldump.c               | 10 +++----
 src/include/access/xlogdefs.h                 | 10 ++++++-
 36 files changed, 132 insertions(+), 123 deletions(-)
   4.2% src/backend/access/gist/
  27.6% src/backend/access/transam/
   6.4% src/backend/backup/
   7.5% src/backend/postmaster/
  13.8% src/backend/replication/logical/
  25.9% src/backend/replication/
   4.0% src/backend/
   3.7% src/bin/pg_waldump/
   5.2% src/

diff --git a/contrib/pg_walinspect/pg_walinspect.c b/contrib/pg_walinspect/pg_walinspect.c
index 501cea8fc1a..3c5e4a856a7 100644
--- a/contrib/pg_walinspect/pg_walinspect.c
+++ b/contrib/pg_walinspect/pg_walinspect.c
@@ -83,7 +83,7 @@ GetCurrentLSN(void)
 	else
 		curr_lsn = GetXLogReplayRecPtr(NULL);
 
-	Assert(!XLogRecPtrIsInvalid(curr_lsn));
+	Assert(XLogRecPtrIsValid(curr_lsn));
 
 	return curr_lsn;
 }
@@ -127,7 +127,7 @@ InitXLogReaderState(XLogRecPtr lsn)
 	/* first find a valid recptr to start from */
 	first_valid_record = XLogFindNextRecord(xlogreader, lsn);
 
-	if (XLogRecPtrIsInvalid(first_valid_record))
+	if (!XLogRecPtrIsValid(first_valid_record))
 		ereport(ERROR,
 				errmsg("could not find a valid record after %X/%08X",
 					   LSN_FORMAT_ARGS(lsn)));
diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c
index 5213cd71e97..3fb1a1285c5 100644
--- a/src/backend/access/gist/gist.c
+++ b/src/backend/access/gist/gist.c
@@ -682,7 +682,7 @@ gistdoinsert(Relation r, IndexTuple itup, Size freespace,
 			state.stack = stack = stack->parent;
 		}
 
-		if (XLogRecPtrIsInvalid(stack->lsn))
+		if (!XLogRecPtrIsValid(stack->lsn))
 			stack->buffer = ReadBuffer(state.r, stack->blkno);
 
 		/*
@@ -698,7 +698,7 @@ gistdoinsert(Relation r, IndexTuple itup, Size freespace,
 		stack->page = BufferGetPage(stack->buffer);
 		stack->lsn = xlocked ?
 			PageGetLSN(stack->page) : BufferGetLSNAtomic(stack->buffer);
-		Assert(!RelationNeedsWAL(state.r) || !XLogRecPtrIsInvalid(stack->lsn));
+		Assert(!RelationNeedsWAL(state.r) || XLogRecPtrIsValid(stack->lsn));
 
 		/*
 		 * If this page was split but the downlink was never inserted to the
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index 387d9972345..9ba45acfff3 100644
--- a/src/backend/access/gist/gistget.c
+++ b/src/backend/access/gist/gistget.c
@@ -46,7 +46,7 @@ gistkillitems(IndexScanDesc scan)
 	bool		killedsomething = false;
 
 	Assert(so->curBlkno != InvalidBlockNumber);
-	Assert(!XLogRecPtrIsInvalid(so->curPageLSN));
+	Assert(XLogRecPtrIsValid(so->curPageLSN));
 	Assert(so->killedItems != NULL);
 
 	buffer = ReadBuffer(scan->indexRelation, so->curBlkno);
@@ -353,7 +353,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem,
 	 * parentlsn < nsn), or if the system crashed after a page split but
 	 * before the downlink was inserted into the parent.
 	 */
-	if (!XLogRecPtrIsInvalid(pageItem->data.parentlsn) &&
+	if (XLogRecPtrIsValid(pageItem->data.parentlsn) &&
 		(GistFollowRight(page) ||
 		 pageItem->data.parentlsn < GistPageGetNSN(page)) &&
 		opaque->rightlink != InvalidBlockNumber /* sanity check */ )
diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c
index 98b79608341..75272827837 100644
--- a/src/backend/access/gist/gistutil.c
+++ b/src/backend/access/gist/gistutil.c
@@ -1040,7 +1040,7 @@ gistGetFakeLSN(Relation rel)
 		Assert(!RelationNeedsWAL(rel));
 
 		/* No need for an actual record if we already have a distinct LSN */
-		if (!XLogRecPtrIsInvalid(lastlsn) && lastlsn == currlsn)
+		if (XLogRecPtrIsValid(lastlsn) && lastlsn == currlsn)
 			currlsn = gistXLogAssignLSN();
 
 		lastlsn = currlsn;
diff --git a/src/backend/access/heap/visibilitymap.c b/src/backend/access/heap/visibilitymap.c
index 2f5e61e2392..d14588e92ae 100644
--- a/src/backend/access/heap/visibilitymap.c
+++ b/src/backend/access/heap/visibilitymap.c
@@ -260,7 +260,7 @@ visibilitymap_set(Relation rel, BlockNumber heapBlk, Buffer heapBuf,
 		 flags, RelationGetRelationName(rel), heapBlk);
 #endif
 
-	Assert(InRecovery || XLogRecPtrIsInvalid(recptr));
+	Assert(InRecovery || !XLogRecPtrIsValid(recptr));
 	Assert(InRecovery || PageIsAllVisible(BufferGetPage(heapBuf)));
 	Assert((flags & VISIBILITYMAP_VALID_BITS) == flags);
 
@@ -292,7 +292,7 @@ visibilitymap_set(Relation rel, BlockNumber heapBlk, Buffer heapBuf,
 
 		if (RelationNeedsWAL(rel))
 		{
-			if (XLogRecPtrIsInvalid(recptr))
+			if (!XLogRecPtrIsValid(recptr))
 			{
 				Assert(!InRecovery);
 				recptr = log_heap_visible(rel, heapBuf, vmBuf, cutoff_xid, flags);
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index e80fbe109cf..ea43b432daf 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -381,7 +381,8 @@ TransactionIdSetPageStatusInternal(TransactionId xid, int nsubxids,
 	 * write-busy, since we don't care if the update reaches disk sooner than
 	 * we think.
 	 */
-	slotno = SimpleLruReadPage(XactCtl, pageno, XLogRecPtrIsInvalid(lsn), xid);
+	slotno = SimpleLruReadPage(XactCtl, pageno, !XLogRecPtrIsValid(lsn),
+							   xid);
 
 	/*
 	 * Set the main transaction id, if any.
@@ -705,7 +706,7 @@ TransactionIdSetStatusBit(TransactionId xid, XidStatus status, XLogRecPtr lsn, i
 	 * recovery. After recovery completes the next clog change will set the
 	 * LSN correctly.
 	 */
-	if (!XLogRecPtrIsInvalid(lsn))
+	if (XLogRecPtrIsValid(lsn))
 	{
 		int			lsnindex = GetLSNIndex(slotno, xid);
 
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index 5d3fcd62c94..77676d6d035 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -937,7 +937,7 @@ SlruPhysicalWritePage(SlruCtl ctl, int64 pageno, int slotno, SlruWriteAll fdata)
 				max_lsn = this_lsn;
 		}
 
-		if (!XLogRecPtrIsInvalid(max_lsn))
+		if (XLogRecPtrIsValid(max_lsn))
 		{
 			/*
 			 * As noted above, elog(ERROR) is not acceptable here, so if
diff --git a/src/backend/access/transam/timeline.c b/src/backend/access/transam/timeline.c
index 186eb91f609..ec3e323ec0c 100644
--- a/src/backend/access/transam/timeline.c
+++ b/src/backend/access/transam/timeline.c
@@ -549,8 +549,8 @@ tliOfPointInHistory(XLogRecPtr ptr, List *history)
 	{
 		TimeLineHistoryEntry *tle = (TimeLineHistoryEntry *) lfirst(cell);
 
-		if ((XLogRecPtrIsInvalid(tle->begin) || tle->begin <= ptr) &&
-			(XLogRecPtrIsInvalid(tle->end) || ptr < tle->end))
+		if ((!XLogRecPtrIsValid(tle->begin) || tle->begin <= ptr) &&
+			(!XLogRecPtrIsValid(tle->end) || ptr < tle->end))
 		{
 			/* found it */
 			return tle->tli;
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index 33369fbe23a..8a92b292e56 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -2547,7 +2547,7 @@ PrepareRedoAdd(FullTransactionId fxid, char *buf,
 	 * the record is added to TwoPhaseState and it should have no
 	 * corresponding file in pg_twophase.
 	 */
-	if (!XLogRecPtrIsInvalid(start_lsn))
+	if (XLogRecPtrIsValid(start_lsn))
 	{
 		char		path[MAXPGPATH];
 
@@ -2587,7 +2587,7 @@ PrepareRedoAdd(FullTransactionId fxid, char *buf,
 	gxact->owner = hdr->owner;
 	gxact->locking_backend = INVALID_PROC_NUMBER;
 	gxact->valid = false;
-	gxact->ondisk = XLogRecPtrIsInvalid(start_lsn);
+	gxact->ondisk = !XLogRecPtrIsValid(start_lsn);
 	gxact->inredo = true;		/* yes, added in redo */
 	strcpy(gxact->gid, gid);
 
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 7c959051e11..0564482cda8 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -1762,7 +1762,7 @@ WALReadFromBuffers(char *dstbuf, XLogRecPtr startptr, Size count,
 	if (RecoveryInProgress() || tli != GetWALInsertionTimeLine())
 		return 0;
 
-	Assert(!XLogRecPtrIsInvalid(startptr));
+	Assert(XLogRecPtrIsValid(startptr));
 
 	/*
 	 * Caller should ensure that the requested data has been inserted into WAL
@@ -2717,7 +2717,7 @@ UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
 	 * available is replayed in this case.  This also saves from extra locks
 	 * taken on the control file from the startup process.
 	 */
-	if (XLogRecPtrIsInvalid(LocalMinRecoveryPoint) && InRecovery)
+	if (!XLogRecPtrIsValid(LocalMinRecoveryPoint) && InRecovery)
 	{
 		updateMinRecoveryPoint = false;
 		return;
@@ -2729,7 +2729,7 @@ UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
 	LocalMinRecoveryPoint = ControlFile->minRecoveryPoint;
 	LocalMinRecoveryPointTLI = ControlFile->minRecoveryPointTLI;
 
-	if (XLogRecPtrIsInvalid(LocalMinRecoveryPoint))
+	if (!XLogRecPtrIsValid(LocalMinRecoveryPoint))
 		updateMinRecoveryPoint = false;
 	else if (force || LocalMinRecoveryPoint < lsn)
 	{
@@ -3149,7 +3149,7 @@ XLogNeedsFlush(XLogRecPtr record)
 		 * which cannot update its local copy of minRecoveryPoint as long as
 		 * it has not replayed all WAL available when doing crash recovery.
 		 */
-		if (XLogRecPtrIsInvalid(LocalMinRecoveryPoint) && InRecovery)
+		if (!XLogRecPtrIsValid(LocalMinRecoveryPoint) && InRecovery)
 		{
 			updateMinRecoveryPoint = false;
 			return false;
@@ -3170,7 +3170,7 @@ XLogNeedsFlush(XLogRecPtr record)
 		 * process doing crash recovery, which should not update the control
 		 * file value if crash recovery is still running.
 		 */
-		if (XLogRecPtrIsInvalid(LocalMinRecoveryPoint))
+		if (!XLogRecPtrIsValid(LocalMinRecoveryPoint))
 			updateMinRecoveryPoint = false;
 
 		/* check again */
@@ -5935,7 +5935,7 @@ StartupXLOG(void)
 	 */
 	if (InRecovery &&
 		(EndOfLog < LocalMinRecoveryPoint ||
-		 !XLogRecPtrIsInvalid(ControlFile->backupStartPoint)))
+		 XLogRecPtrIsValid(ControlFile->backupStartPoint)))
 	{
 		/*
 		 * Ran off end of WAL before reaching end-of-backup WAL record, or
@@ -5945,7 +5945,7 @@ StartupXLOG(void)
 		 */
 		if (ArchiveRecoveryRequested || ControlFile->backupEndRequired)
 		{
-			if (!XLogRecPtrIsInvalid(ControlFile->backupStartPoint) || ControlFile->backupEndRequired)
+			if (XLogRecPtrIsValid(ControlFile->backupStartPoint) || ControlFile->backupEndRequired)
 				ereport(FATAL,
 						(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
 						 errmsg("WAL ends before end of online backup"),
@@ -6047,7 +6047,7 @@ StartupXLOG(void)
 	 * (It's critical to first write an OVERWRITE_CONTRECORD message, which
 	 * we'll do as soon as we're open for writing new WAL.)
 	 */
-	if (!XLogRecPtrIsInvalid(missingContrecPtr))
+	if (XLogRecPtrIsValid(missingContrecPtr))
 	{
 		/*
 		 * We should only have a missingContrecPtr if we're not switching to a
@@ -6057,7 +6057,7 @@ StartupXLOG(void)
 		 * disregard.
 		 */
 		Assert(newTLI == endOfRecoveryInfo->lastRecTLI);
-		Assert(!XLogRecPtrIsInvalid(abortedRecPtr));
+		Assert(XLogRecPtrIsValid(abortedRecPtr));
 		EndOfLog = missingContrecPtr;
 	}
 
@@ -6161,9 +6161,9 @@ StartupXLOG(void)
 	LocalSetXLogInsertAllowed();
 
 	/* If necessary, write overwrite-contrecord before doing anything else */
-	if (!XLogRecPtrIsInvalid(abortedRecPtr))
+	if (XLogRecPtrIsValid(abortedRecPtr))
 	{
-		Assert(!XLogRecPtrIsInvalid(missingContrecPtr));
+		Assert(XLogRecPtrIsValid(missingContrecPtr));
 		CreateOverwriteContrecordRecord(abortedRecPtr, missingContrecPtr, newTLI);
 	}
 
@@ -7693,7 +7693,7 @@ CreateRestartPoint(int flags)
 	 * restartpoint. It's assumed that flushing the buffers will do that as a
 	 * side-effect.
 	 */
-	if (XLogRecPtrIsInvalid(lastCheckPointRecPtr) ||
+	if (!XLogRecPtrIsValid(lastCheckPointRecPtr) ||
 		lastCheckPoint.redo <= ControlFile->checkPointCopy.redo)
 	{
 		ereport(DEBUG2,
@@ -7936,7 +7936,7 @@ GetWALAvailability(XLogRecPtr targetLSN)
 	/*
 	 * slot does not reserve WAL. Either deactivated, or has never been active
 	 */
-	if (XLogRecPtrIsInvalid(targetLSN))
+	if (!XLogRecPtrIsValid(targetLSN))
 		return WALAVAIL_INVALID_LSN;
 
 	/*
@@ -8352,8 +8352,8 @@ xlog_redo(XLogReaderState *record)
 		 * never arrive.
 		 */
 		if (ArchiveRecoveryRequested &&
-			!XLogRecPtrIsInvalid(ControlFile->backupStartPoint) &&
-			XLogRecPtrIsInvalid(ControlFile->backupEndPoint))
+			XLogRecPtrIsValid(ControlFile->backupStartPoint) &&
+			!XLogRecPtrIsValid(ControlFile->backupEndPoint))
 			ereport(PANIC,
 					(errmsg("online backup was canceled, recovery cannot continue")));
 
diff --git a/src/backend/access/transam/xlogbackup.c b/src/backend/access/transam/xlogbackup.c
index 8a8a2a7b326..7e48aa43901 100644
--- a/src/backend/access/transam/xlogbackup.c
+++ b/src/backend/access/transam/xlogbackup.c
@@ -79,8 +79,8 @@ build_backup_content(BackupState *state, bool ishistoryfile)
 	}
 
 	/* either both istartpoint and istarttli should be set, or neither */
-	Assert(XLogRecPtrIsInvalid(state->istartpoint) == (state->istarttli == 0));
-	if (!XLogRecPtrIsInvalid(state->istartpoint))
+	Assert(!XLogRecPtrIsValid(state->istartpoint) == (state->istarttli == 0));
+	if (XLogRecPtrIsValid(state->istartpoint))
 	{
 		appendStringInfo(&result, "INCREMENTAL FROM LSN: %X/%08X\n",
 						 LSN_FORMAT_ARGS(state->istartpoint));
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index dcc8d4f9c1b..aad16127e60 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -231,7 +231,7 @@ WALOpenSegmentInit(WALOpenSegment *seg, WALSegmentContext *segcxt,
 void
 XLogBeginRead(XLogReaderState *state, XLogRecPtr RecPtr)
 {
-	Assert(!XLogRecPtrIsInvalid(RecPtr));
+	Assert(XLogRecPtrIsValid(RecPtr));
 
 	ResetDecoder(state);
 
@@ -343,7 +343,7 @@ XLogNextRecord(XLogReaderState *state, char **errormsg)
 		 * XLogBeginRead() or XLogNextRecord(), and is the location of the
 		 * error.
 		 */
-		Assert(!XLogRecPtrIsInvalid(state->EndRecPtr));
+		Assert(XLogRecPtrIsValid(state->EndRecPtr));
 
 		return NULL;
 	}
@@ -1398,7 +1398,7 @@ XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr)
 	XLogPageHeader header;
 	char	   *errormsg;
 
-	Assert(!XLogRecPtrIsInvalid(RecPtr));
+	Assert(XLogRecPtrIsValid(RecPtr));
 
 	/* Make sure ReadPageInternal() can't return XLREAD_WOULDBLOCK. */
 	state->nonblocking = false;
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index 550de6e4a59..bb7b79613c2 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -773,7 +773,7 @@ InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr,
 		 * emit a log message when we continue initializing from a base
 		 * backup.
 		 */
-		if (!XLogRecPtrIsInvalid(ControlFile->backupStartPoint))
+		if (XLogRecPtrIsValid(ControlFile->backupStartPoint))
 			ereport(LOG,
 					errmsg("restarting backup recovery with redo LSN %X/%08X",
 						   LSN_FORMAT_ARGS(ControlFile->backupStartPoint)));
@@ -868,7 +868,7 @@ InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr,
 	 * The min recovery point should be part of the requested timeline's
 	 * history, too.
 	 */
-	if (!XLogRecPtrIsInvalid(ControlFile->minRecoveryPoint) &&
+	if (XLogRecPtrIsValid(ControlFile->minRecoveryPoint) &&
 		tliOfPointInHistory(ControlFile->minRecoveryPoint - 1, expectedTLEs) !=
 		ControlFile->minRecoveryPointTLI)
 		ereport(FATAL,
@@ -2204,7 +2204,7 @@ CheckRecoveryConsistency(void)
 	 * During crash recovery, we don't reach a consistent state until we've
 	 * replayed all the WAL.
 	 */
-	if (XLogRecPtrIsInvalid(minRecoveryPoint))
+	if (!XLogRecPtrIsValid(minRecoveryPoint))
 		return;
 
 	Assert(InArchiveRecovery);
@@ -2219,7 +2219,7 @@ CheckRecoveryConsistency(void)
 	/*
 	 * Have we reached the point where our base backup was completed?
 	 */
-	if (!XLogRecPtrIsInvalid(backupEndPoint) &&
+	if (XLogRecPtrIsValid(backupEndPoint) &&
 		backupEndPoint <= lastReplayedEndRecPtr)
 	{
 		XLogRecPtr	saveBackupStartPoint = backupStartPoint;
@@ -2425,7 +2425,7 @@ checkTimeLineSwitch(XLogRecPtr lsn, TimeLineID newTLI, TimeLineID prevTLI,
 	 * branched before the timeline the min recovery point is on, and you
 	 * attempt to do PITR to the new timeline.
 	 */
-	if (!XLogRecPtrIsInvalid(minRecoveryPoint) &&
+	if (XLogRecPtrIsValid(minRecoveryPoint) &&
 		lsn < minRecoveryPoint &&
 		newTLI > minRecoveryPointTLI)
 		ereport(PANIC,
@@ -3190,7 +3190,7 @@ ReadRecord(XLogPrefetcher *xlogprefetcher, int emode,
 			 * overwrite contrecord in the wrong place, breaking everything.
 			 */
 			if (!ArchiveRecoveryRequested &&
-				!XLogRecPtrIsInvalid(xlogreader->abortedRecPtr))
+				XLogRecPtrIsValid(xlogreader->abortedRecPtr))
 			{
 				abortedRecPtr = xlogreader->abortedRecPtr;
 				missingContrecPtr = xlogreader->missingContrecPtr;
diff --git a/src/backend/access/transam/xlogwait.c b/src/backend/access/transam/xlogwait.c
index e04567cfd67..6b4c1623e57 100644
--- a/src/backend/access/transam/xlogwait.c
+++ b/src/backend/access/transam/xlogwait.c
@@ -230,7 +230,7 @@ wakeupWaiters(WaitLSNType lsnType, XLogRecPtr currentLSN)
 			/* Get procInfo using appropriate heap node */
 			procInfo = pairingheap_container(WaitLSNProcInfo, heapNode[i], node);
 
-			if (!XLogRecPtrIsInvalid(currentLSN) && procInfo->waitLSN > currentLSN)
+			if (XLogRecPtrIsValid(currentLSN) && procInfo->waitLSN > currentLSN)
 				break;
 
 			Assert(numWakeUpProcs < WAKEUP_PROC_STATIC_ARRAY_SIZE);
diff --git a/src/backend/backup/backup_manifest.c b/src/backend/backup/backup_manifest.c
index d05252f383c..dd76c9b0b63 100644
--- a/src/backend/backup/backup_manifest.c
+++ b/src/backend/backup/backup_manifest.c
@@ -242,7 +242,7 @@ AddWALInfoToBackupManifest(backup_manifest_info *manifest, XLogRecPtr startptr,
 		 * entry->end is InvalidXLogRecPtr, it means that the timeline has not
 		 * yet ended.)
 		 */
-		if (!XLogRecPtrIsInvalid(entry->end) && entry->end < startptr)
+		if (XLogRecPtrIsValid(entry->end) && entry->end < startptr)
 			continue;
 
 		/*
@@ -274,7 +274,7 @@ AddWALInfoToBackupManifest(backup_manifest_info *manifest, XLogRecPtr startptr,
 			 * better have arrived at the expected starting TLI. If not,
 			 * something's gone horribly wrong.
 			 */
-			if (XLogRecPtrIsInvalid(entry->begin))
+			if (!XLogRecPtrIsValid(entry->begin))
 				ereport(ERROR,
 						errmsg("expected start timeline %u but found timeline %u",
 							   starttli, entry->tli));
diff --git a/src/backend/backup/basebackup_incremental.c b/src/backend/backup/basebackup_incremental.c
index a0d48ff0fef..852ab577045 100644
--- a/src/backend/backup/basebackup_incremental.c
+++ b/src/backend/backup/basebackup_incremental.c
@@ -519,7 +519,7 @@ PrepareForIncrementalBackup(IncrementalBackupInfo *ib,
 		if (!WalSummariesAreComplete(tli_wslist, tli_start_lsn, tli_end_lsn,
 									 &tli_missing_lsn))
 		{
-			if (XLogRecPtrIsInvalid(tli_missing_lsn))
+			if (!XLogRecPtrIsValid(tli_missing_lsn))
 				ereport(ERROR,
 						(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
 						 errmsg("WAL summaries are required on timeline %u from %X/%08X to %X/%08X, but no summaries for that timeline and LSN range exist",
diff --git a/src/backend/backup/walsummary.c b/src/backend/backup/walsummary.c
index c7a2c65cc6a..2689eae3328 100644
--- a/src/backend/backup/walsummary.c
+++ b/src/backend/backup/walsummary.c
@@ -67,9 +67,9 @@ GetWalSummaries(TimeLineID tli, XLogRecPtr start_lsn, XLogRecPtr end_lsn)
 		/* Skip if it doesn't match the filter criteria. */
 		if (tli != 0 && tli != file_tli)
 			continue;
-		if (!XLogRecPtrIsInvalid(start_lsn) && start_lsn >= file_end_lsn)
+		if (XLogRecPtrIsValid(start_lsn) && start_lsn >= file_end_lsn)
 			continue;
-		if (!XLogRecPtrIsInvalid(end_lsn) && end_lsn <= file_start_lsn)
+		if (XLogRecPtrIsValid(end_lsn) && end_lsn <= file_start_lsn)
 			continue;
 
 		/* Add it to the list. */
@@ -111,9 +111,9 @@ FilterWalSummaries(List *wslist, TimeLineID tli,
 		/* Skip if it doesn't match the filter criteria. */
 		if (tli != 0 && tli != ws->tli)
 			continue;
-		if (!XLogRecPtrIsInvalid(start_lsn) && start_lsn > ws->end_lsn)
+		if (XLogRecPtrIsValid(start_lsn) && start_lsn > ws->end_lsn)
 			continue;
-		if (!XLogRecPtrIsInvalid(end_lsn) && end_lsn < ws->start_lsn)
+		if (XLogRecPtrIsValid(end_lsn) && end_lsn < ws->start_lsn)
 			continue;
 
 		/* Add it to the result list. */
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index 3d29818badd..2b0c0ca8d05 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -393,7 +393,7 @@ parse_subscription_options(ParseState *pstate, List *stmt_options,
 				lsn = DatumGetLSN(DirectFunctionCall1(pg_lsn_in,
 													  CStringGetDatum(lsn_str)));
 
-				if (XLogRecPtrIsInvalid(lsn))
+				if (!XLogRecPtrIsValid(lsn))
 					ereport(ERROR,
 							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 							 errmsg("invalid WAL location (LSN): %s", lsn_str)));
@@ -1895,7 +1895,7 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt,
 				 * If the user sets subskiplsn, we do a sanity check to make
 				 * sure that the specified LSN is a probable value.
 				 */
-				if (!XLogRecPtrIsInvalid(opts.lsn))
+				if (XLogRecPtrIsValid(opts.lsn))
 				{
 					RepOriginId originid;
 					char		originname[NAMEDATALEN];
@@ -1907,7 +1907,7 @@ AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt,
 					remote_lsn = replorigin_get_progress(originid, false);
 
 					/* Check the given LSN is at least a future LSN */
-					if (!XLogRecPtrIsInvalid(remote_lsn) && opts.lsn < remote_lsn)
+					if (XLogRecPtrIsValid(remote_lsn) && opts.lsn < remote_lsn)
 						ereport(ERROR,
 								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 								 errmsg("skip WAL location (LSN %X/%08X) must be greater than origin LSN %X/%08X",
diff --git a/src/backend/postmaster/walsummarizer.c b/src/backend/postmaster/walsummarizer.c
index e1f142f20c7..c4a888a081c 100644
--- a/src/backend/postmaster/walsummarizer.c
+++ b/src/backend/postmaster/walsummarizer.c
@@ -342,7 +342,7 @@ WalSummarizerMain(const void *startup_data, size_t startup_data_len)
 	 * If we discover that WAL summarization is not enabled, just exit.
 	 */
 	current_lsn = GetOldestUnsummarizedLSN(&current_tli, &exact);
-	if (XLogRecPtrIsInvalid(current_lsn))
+	if (!XLogRecPtrIsValid(current_lsn))
 		proc_exit(0);
 
 	/*
@@ -379,7 +379,7 @@ WalSummarizerMain(const void *startup_data, size_t startup_data_len)
 		 * only have to do this once per timeline switch, we probably wouldn't
 		 * save any significant amount of work in practice.
 		 */
-		if (current_tli != latest_tli && XLogRecPtrIsInvalid(switch_lsn))
+		if (current_tli != latest_tli && !XLogRecPtrIsValid(switch_lsn))
 		{
 			List	   *tles = readTimeLineHistory(latest_tli);
 
@@ -394,7 +394,7 @@ WalSummarizerMain(const void *startup_data, size_t startup_data_len)
 		 * on this timeline. Switch to the next timeline and go around again,
 		 * backing up to the exact switch point if we passed it.
 		 */
-		if (!XLogRecPtrIsInvalid(switch_lsn) && current_lsn >= switch_lsn)
+		if (XLogRecPtrIsValid(switch_lsn) && current_lsn >= switch_lsn)
 		{
 			/* Restart summarization from switch point. */
 			current_tli = switch_tli;
@@ -419,7 +419,7 @@ WalSummarizerMain(const void *startup_data, size_t startup_data_len)
 		end_of_summary_lsn = SummarizeWAL(current_tli,
 										  current_lsn, exact,
 										  switch_lsn, latest_lsn);
-		Assert(!XLogRecPtrIsInvalid(end_of_summary_lsn));
+		Assert(XLogRecPtrIsValid(end_of_summary_lsn));
 		Assert(end_of_summary_lsn >= current_lsn);
 
 		/*
@@ -923,7 +923,7 @@ SummarizeWAL(TimeLineID tli, XLogRecPtr start_lsn, bool exact,
 	private_data = (SummarizerReadLocalXLogPrivate *)
 		palloc0(sizeof(SummarizerReadLocalXLogPrivate));
 	private_data->tli = tli;
-	private_data->historic = !XLogRecPtrIsInvalid(switch_lsn);
+	private_data->historic = XLogRecPtrIsValid(switch_lsn);
 	private_data->read_upto = maximum_lsn;
 
 	/* Create xlogreader. */
@@ -971,7 +971,7 @@ SummarizeWAL(TimeLineID tli, XLogRecPtr start_lsn, bool exact,
 	else
 	{
 		summary_start_lsn = XLogFindNextRecord(xlogreader, start_lsn);
-		if (XLogRecPtrIsInvalid(summary_start_lsn))
+		if (!XLogRecPtrIsValid(summary_start_lsn))
 		{
 			/*
 			 * If we hit end-of-WAL while trying to find the next valid
@@ -1058,7 +1058,7 @@ SummarizeWAL(TimeLineID tli, XLogRecPtr start_lsn, bool exact,
 		/* We shouldn't go backward. */
 		Assert(summary_start_lsn <= xlogreader->EndRecPtr);
 
-		if (!XLogRecPtrIsInvalid(switch_lsn) &&
+		if (XLogRecPtrIsValid(switch_lsn) &&
 			xlogreader->ReadRecPtr >= switch_lsn)
 		{
 			/*
@@ -1180,7 +1180,7 @@ SummarizeWAL(TimeLineID tli, XLogRecPtr start_lsn, bool exact,
 		 * If we have a switch LSN and have reached it, stop before reading
 		 * the next record.
 		 */
-		if (!XLogRecPtrIsInvalid(switch_lsn) &&
+		if (XLogRecPtrIsValid(switch_lsn) &&
 			xlogreader->EndRecPtr >= switch_lsn)
 			break;
 	}
@@ -1723,7 +1723,7 @@ MaybeRemoveOldWalSummaries(void)
 			 * If the WAL doesn't exist any more, we can remove it if the file
 			 * modification time is old enough.
 			 */
-			if (XLogRecPtrIsInvalid(oldest_lsn) || ws->end_lsn <= oldest_lsn)
+			if (!XLogRecPtrIsValid(oldest_lsn) || ws->end_lsn <= oldest_lsn)
 				RemoveWalSummaryIfOlderThan(ws, cutoff_time);
 
 			/*
diff --git a/src/backend/replication/logical/applyparallelworker.c b/src/backend/replication/logical/applyparallelworker.c
index 14325581afc..baa68c1ab6c 100644
--- a/src/backend/replication/logical/applyparallelworker.c
+++ b/src/backend/replication/logical/applyparallelworker.c
@@ -299,7 +299,7 @@ pa_can_start(void)
 	 * STREAM START message, and it doesn't seem worth sending the extra eight
 	 * bytes with the STREAM START to enable parallelism for this case.
 	 */
-	if (!XLogRecPtrIsInvalid(MySubscription->skiplsn))
+	if (XLogRecPtrIsValid(MySubscription->skiplsn))
 		return false;
 
 	/*
@@ -1640,7 +1640,7 @@ pa_xact_finish(ParallelApplyWorkerInfo *winfo, XLogRecPtr remote_lsn)
 	 */
 	pa_wait_for_xact_finish(winfo);
 
-	if (!XLogRecPtrIsInvalid(remote_lsn))
+	if (XLogRecPtrIsValid(remote_lsn))
 		store_flush_position(remote_lsn, winfo->shared->last_commit_end);
 
 	pa_free_worker(winfo);
diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c
index 6c6d4015ba7..6214028eda9 100644
--- a/src/backend/replication/logical/launcher.c
+++ b/src/backend/replication/logical/launcher.c
@@ -1661,7 +1661,7 @@ pg_stat_get_subscription(PG_FUNCTION_ARGS)
 		else
 			nulls[3] = true;
 
-		if (XLogRecPtrIsInvalid(worker.last_lsn))
+		if (!XLogRecPtrIsValid(worker.last_lsn))
 			nulls[4] = true;
 		else
 			values[4] = LSNGetDatum(worker.last_lsn);
@@ -1673,7 +1673,7 @@ pg_stat_get_subscription(PG_FUNCTION_ARGS)
 			nulls[6] = true;
 		else
 			values[6] = TimestampTzGetDatum(worker.last_recv_time);
-		if (XLogRecPtrIsInvalid(worker.reply_lsn))
+		if (!XLogRecPtrIsValid(worker.reply_lsn))
 			nulls[7] = true;
 		else
 			values[7] = LSNGetDatum(worker.reply_lsn);
diff --git a/src/backend/replication/logical/logical.c b/src/backend/replication/logical/logical.c
index 93ed2eb368e..79717b52941 100644
--- a/src/backend/replication/logical/logical.c
+++ b/src/backend/replication/logical/logical.c
@@ -388,7 +388,7 @@ CreateInitDecodingContext(const char *plugin,
 	slot->data.plugin = plugin_name;
 	SpinLockRelease(&slot->mutex);
 
-	if (XLogRecPtrIsInvalid(restart_lsn))
+	if (!XLogRecPtrIsValid(restart_lsn))
 		ReplicationSlotReserveWal();
 	else
 	{
diff --git a/src/backend/replication/logical/logicalfuncs.c b/src/backend/replication/logical/logicalfuncs.c
index 25f890ddeed..d78e486bca6 100644
--- a/src/backend/replication/logical/logicalfuncs.c
+++ b/src/backend/replication/logical/logicalfuncs.c
@@ -229,7 +229,7 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin
 		 * Wait for specified streaming replication standby servers (if any)
 		 * to confirm receipt of WAL up to wait_for_wal_lsn.
 		 */
-		if (XLogRecPtrIsInvalid(upto_lsn))
+		if (!XLogRecPtrIsValid(upto_lsn))
 			wait_for_wal_lsn = end_of_wal;
 		else
 			wait_for_wal_lsn = Min(upto_lsn, end_of_wal);
diff --git a/src/backend/replication/logical/slotsync.c b/src/backend/replication/logical/slotsync.c
index b122d99b009..8b4afd87dc9 100644
--- a/src/backend/replication/logical/slotsync.c
+++ b/src/backend/replication/logical/slotsync.c
@@ -493,7 +493,7 @@ reserve_wal_for_local_slot(XLogRecPtr restart_lsn)
 	ReplicationSlot *slot = MyReplicationSlot;
 
 	Assert(slot != NULL);
-	Assert(XLogRecPtrIsInvalid(slot->data.restart_lsn));
+	Assert(!XLogRecPtrIsValid(slot->data.restart_lsn));
 
 	while (true)
 	{
@@ -899,8 +899,8 @@ synchronize_slots(WalReceiverConn *wrconn)
 		 * pg_replication_slots view, then we can avoid fetching RS_EPHEMERAL
 		 * slots in the first place.
 		 */
-		if ((XLogRecPtrIsInvalid(remote_slot->restart_lsn) ||
-			 XLogRecPtrIsInvalid(remote_slot->confirmed_lsn) ||
+		if ((!XLogRecPtrIsValid(remote_slot->restart_lsn) ||
+			 !XLogRecPtrIsValid(remote_slot->confirmed_lsn) ||
 			 !TransactionIdIsValid(remote_slot->catalog_xmin)) &&
 			remote_slot->invalidated == RS_INVAL_NONE)
 			pfree(remote_slot);
diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c
index e1c757c911e..28f61f96a1a 100644
--- a/src/backend/replication/logical/worker.c
+++ b/src/backend/replication/logical/worker.c
@@ -514,7 +514,7 @@ bool		InitializingApplyWorker = false;
  * by the user.
  */
 static XLogRecPtr skip_xact_finish_lsn = InvalidXLogRecPtr;
-#define is_skipping_changes() (unlikely(!XLogRecPtrIsInvalid(skip_xact_finish_lsn)))
+#define is_skipping_changes() (unlikely(XLogRecPtrIsValid(skip_xact_finish_lsn)))
 
 /* BufFile handle of the current streaming file */
 static BufFile *stream_fd = NULL;
@@ -4126,7 +4126,7 @@ LogicalRepApplyLoop(XLogRecPtr last_received)
 						 * due to a bug, we don't want to proceed as it can
 						 * incorrectly advance oldest_nonremovable_xid.
 						 */
-						if (XLogRecPtrIsInvalid(rdt_data.remote_lsn))
+						if (!XLogRecPtrIsValid(rdt_data.remote_lsn))
 							elog(ERROR, "cannot get the latest WAL position from the publisher");
 
 						maybe_advance_nonremovable_xid(&rdt_data, true);
@@ -4613,7 +4613,7 @@ wait_for_publisher_status(RetainDeadTuplesData *rdt_data,
 static void
 wait_for_local_flush(RetainDeadTuplesData *rdt_data)
 {
-	Assert(!XLogRecPtrIsInvalid(rdt_data->remote_lsn) &&
+	Assert(XLogRecPtrIsValid(rdt_data->remote_lsn) &&
 		   TransactionIdIsValid(rdt_data->candidate_xid));
 
 	/*
@@ -6031,7 +6031,7 @@ maybe_start_skipping_changes(XLogRecPtr finish_lsn)
 	 * function is called for every remote transaction and we assume that
 	 * skipping the transaction is not used often.
 	 */
-	if (likely(XLogRecPtrIsInvalid(MySubscription->skiplsn) ||
+	if (likely(!XLogRecPtrIsValid(MySubscription->skiplsn) ||
 			   MySubscription->skiplsn != finish_lsn))
 		return;
 
@@ -6077,7 +6077,7 @@ clear_subscription_skip_lsn(XLogRecPtr finish_lsn)
 	XLogRecPtr	myskiplsn = MySubscription->skiplsn;
 	bool		started_tx = false;
 
-	if (likely(XLogRecPtrIsInvalid(myskiplsn)) || am_parallel_apply_worker())
+	if (likely(!XLogRecPtrIsValid(myskiplsn)) || am_parallel_apply_worker())
 		return;
 
 	if (!IsTransactionState())
@@ -6173,7 +6173,7 @@ apply_error_callback(void *arg)
 			errcontext("processing remote data for replication origin \"%s\" during message type \"%s\"",
 					   errarg->origin_name,
 					   logicalrep_message_type(errarg->command));
-		else if (XLogRecPtrIsInvalid(errarg->finish_lsn))
+		else if (!XLogRecPtrIsValid(errarg->finish_lsn))
 			errcontext("processing remote data for replication origin \"%s\" during message type \"%s\" in transaction %u",
 					   errarg->origin_name,
 					   logicalrep_message_type(errarg->command),
@@ -6189,7 +6189,7 @@ apply_error_callback(void *arg)
 	{
 		if (errarg->remote_attnum < 0)
 		{
-			if (XLogRecPtrIsInvalid(errarg->finish_lsn))
+			if (!XLogRecPtrIsValid(errarg->finish_lsn))
 				errcontext("processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" in transaction %u",
 						   errarg->origin_name,
 						   logicalrep_message_type(errarg->command),
@@ -6207,7 +6207,7 @@ apply_error_callback(void *arg)
 		}
 		else
 		{
-			if (XLogRecPtrIsInvalid(errarg->finish_lsn))
+			if (!XLogRecPtrIsValid(errarg->finish_lsn))
 				errcontext("processing remote data for replication origin \"%s\" during message type \"%s\" for replication target relation \"%s.%s\" column \"%s\" in transaction %u",
 						   errarg->origin_name,
 						   logicalrep_message_type(errarg->command),
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 6363030808f..0cb93dc90f2 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -1730,7 +1730,7 @@ static inline bool
 CanInvalidateIdleSlot(ReplicationSlot *s)
 {
 	return (idle_replication_slot_timeout_secs != 0 &&
-			!XLogRecPtrIsInvalid(s->data.restart_lsn) &&
+			XLogRecPtrIsValid(s->data.restart_lsn) &&
 			s->inactive_since > 0 &&
 			!(RecoveryInProgress() && s->data.synced));
 }
@@ -2922,7 +2922,7 @@ StandbySlotsHaveCaughtup(XLogRecPtr wait_for_lsn, int elevel)
 	 * Don't need to wait for the standbys to catch up if they are already
 	 * beyond the specified WAL location.
 	 */
-	if (!XLogRecPtrIsInvalid(ss_oldest_flush_lsn) &&
+	if (XLogRecPtrIsValid(ss_oldest_flush_lsn) &&
 		ss_oldest_flush_lsn >= wait_for_lsn)
 		return true;
 
@@ -2993,7 +2993,7 @@ StandbySlotsHaveCaughtup(XLogRecPtr wait_for_lsn, int elevel)
 			break;
 		}
 
-		if (XLogRecPtrIsInvalid(restart_lsn) || restart_lsn < wait_for_lsn)
+		if (!XLogRecPtrIsValid(restart_lsn) || restart_lsn < wait_for_lsn)
 		{
 			/* Log a message if no active_pid for this physical slot */
 			if (inactive)
@@ -3012,7 +3012,7 @@ StandbySlotsHaveCaughtup(XLogRecPtr wait_for_lsn, int elevel)
 
 		Assert(restart_lsn >= wait_for_lsn);
 
-		if (XLogRecPtrIsInvalid(min_restart_lsn) ||
+		if (!XLogRecPtrIsValid(min_restart_lsn) ||
 			min_restart_lsn > restart_lsn)
 			min_restart_lsn = restart_lsn;
 
@@ -3031,7 +3031,7 @@ StandbySlotsHaveCaughtup(XLogRecPtr wait_for_lsn, int elevel)
 		return false;
 
 	/* The ss_oldest_flush_lsn must not retreat. */
-	Assert(XLogRecPtrIsInvalid(ss_oldest_flush_lsn) ||
+	Assert(!XLogRecPtrIsValid(ss_oldest_flush_lsn) ||
 		   min_restart_lsn >= ss_oldest_flush_lsn);
 
 	ss_oldest_flush_lsn = min_restart_lsn;
diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c
index b8f21153e7b..5aecd5c6a50 100644
--- a/src/backend/replication/slotfuncs.c
+++ b/src/backend/replication/slotfuncs.c
@@ -46,7 +46,7 @@ create_physical_replication_slot(char *name, bool immediately_reserve,
 	if (immediately_reserve)
 	{
 		/* Reserve WAL as the user asked for it */
-		if (XLogRecPtrIsInvalid(restart_lsn))
+		if (!XLogRecPtrIsValid(restart_lsn))
 			ReplicationSlotReserveWal();
 		else
 			MyReplicationSlot->data.restart_lsn = restart_lsn;
@@ -357,7 +357,7 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
 				 *
 				 * If we do change it, save the state for safe_wal_size below.
 				 */
-				if (!XLogRecPtrIsInvalid(slot_contents.data.restart_lsn))
+				if (XLogRecPtrIsValid(slot_contents.data.restart_lsn))
 				{
 					int			pid;
 
@@ -407,7 +407,7 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
 		values[i++] = BoolGetDatum(slot_contents.data.two_phase);
 
 		if (slot_contents.data.two_phase &&
-			!XLogRecPtrIsInvalid(slot_contents.data.two_phase_at))
+			XLogRecPtrIsValid(slot_contents.data.two_phase_at))
 			values[i++] = LSNGetDatum(slot_contents.data.two_phase_at);
 		else
 			nulls[i++] = true;
@@ -523,7 +523,7 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 
 	CheckSlotPermissions();
 
-	if (XLogRecPtrIsInvalid(moveto))
+	if (!XLogRecPtrIsValid(moveto))
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("invalid target WAL LSN")));
@@ -545,7 +545,7 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
 	ReplicationSlotAcquire(NameStr(*slotname), true, true);
 
 	/* A slot whose restart_lsn has never been reserved cannot be advanced */
-	if (XLogRecPtrIsInvalid(MyReplicationSlot->data.restart_lsn))
+	if (!XLogRecPtrIsValid(MyReplicationSlot->data.restart_lsn))
 		ereport(ERROR,
 				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
 				 errmsg("replication slot \"%s\" cannot be advanced",
@@ -679,7 +679,7 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot)
 						NameStr(*src_name))));
 
 	/* Copying non-reserved slot doesn't make sense */
-	if (XLogRecPtrIsInvalid(src_restart_lsn))
+	if (!XLogRecPtrIsValid(src_restart_lsn))
 		ereport(ERROR,
 				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
 				 errmsg("cannot copy a replication slot that doesn't reserve WAL")));
@@ -785,7 +785,7 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot)
 					 errdetail("The source replication slot was modified incompatibly during the copy operation.")));
 
 		/* The source slot must have a consistent snapshot */
-		if (src_islogical && XLogRecPtrIsInvalid(copy_confirmed_flush))
+		if (src_islogical && !XLogRecPtrIsValid(copy_confirmed_flush))
 			ereport(ERROR,
 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 					 errmsg("cannot copy unfinished logical replication slot \"%s\"",
@@ -840,7 +840,7 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot)
 	/* All done.  Set up the return values */
 	values[0] = NameGetDatum(dst_name);
 	nulls[0] = false;
-	if (!XLogRecPtrIsInvalid(MyReplicationSlot->data.confirmed_flush))
+	if (XLogRecPtrIsValid(MyReplicationSlot->data.confirmed_flush))
 	{
 		values[1] = LSNGetDatum(MyReplicationSlot->data.confirmed_flush);
 		nulls[1] = false;
diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index 32cf3a48b89..a0c79958fd5 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -493,7 +493,7 @@ SyncRepReleaseWaiters(void)
 	if (MyWalSnd->sync_standby_priority == 0 ||
 		(MyWalSnd->state != WALSNDSTATE_STREAMING &&
 		 MyWalSnd->state != WALSNDSTATE_STOPPING) ||
-		XLogRecPtrIsInvalid(MyWalSnd->flush))
+		!XLogRecPtrIsValid(MyWalSnd->flush))
 	{
 		announce_next_takeover = true;
 		return;
@@ -676,11 +676,11 @@ SyncRepGetOldestSyncRecPtr(XLogRecPtr *writePtr,
 		XLogRecPtr	flush = sync_standbys[i].flush;
 		XLogRecPtr	apply = sync_standbys[i].apply;
 
-		if (XLogRecPtrIsInvalid(*writePtr) || *writePtr > write)
+		if (!XLogRecPtrIsValid(*writePtr) || *writePtr > write)
 			*writePtr = write;
-		if (XLogRecPtrIsInvalid(*flushPtr) || *flushPtr > flush)
+		if (!XLogRecPtrIsValid(*flushPtr) || *flushPtr > flush)
 			*flushPtr = flush;
-		if (XLogRecPtrIsInvalid(*applyPtr) || *applyPtr > apply)
+		if (!XLogRecPtrIsValid(*applyPtr) || *applyPtr > apply)
 			*applyPtr = apply;
 	}
 }
@@ -799,7 +799,7 @@ SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys)
 			continue;
 
 		/* Must have a valid flush position */
-		if (XLogRecPtrIsInvalid(stby->flush))
+		if (!XLogRecPtrIsValid(stby->flush))
 			continue;
 
 		/* OK, it's a candidate */
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index 7361ffc9dcf..2ee8fecee26 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -1469,16 +1469,16 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS)
 	{
 		values[1] = CStringGetTextDatum(WalRcvGetStateString(state));
 
-		if (XLogRecPtrIsInvalid(receive_start_lsn))
+		if (!XLogRecPtrIsValid(receive_start_lsn))
 			nulls[2] = true;
 		else
 			values[2] = LSNGetDatum(receive_start_lsn);
 		values[3] = Int32GetDatum(receive_start_tli);
-		if (XLogRecPtrIsInvalid(written_lsn))
+		if (!XLogRecPtrIsValid(written_lsn))
 			nulls[4] = true;
 		else
 			values[4] = LSNGetDatum(written_lsn);
-		if (XLogRecPtrIsInvalid(flushed_lsn))
+		if (!XLogRecPtrIsValid(flushed_lsn))
 			nulls[5] = true;
 		else
 			values[5] = LSNGetDatum(flushed_lsn);
@@ -1491,7 +1491,7 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS)
 			nulls[8] = true;
 		else
 			values[8] = TimestampTzGetDatum(last_receipt_time);
-		if (XLogRecPtrIsInvalid(latest_end_lsn))
+		if (!XLogRecPtrIsValid(latest_end_lsn))
 			nulls[9] = true;
 		else
 			values[9] = LSNGetDatum(latest_end_lsn);
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 548eafa7a73..b6dfb230d0d 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -529,7 +529,7 @@ ReadReplicationSlot(ReadReplicationSlotCmd *cmd)
 		i++;
 
 		/* start LSN */
-		if (!XLogRecPtrIsInvalid(slot_contents.data.restart_lsn))
+		if (XLogRecPtrIsValid(slot_contents.data.restart_lsn))
 		{
 			char		xloc[64];
 
@@ -541,7 +541,7 @@ ReadReplicationSlot(ReadReplicationSlotCmd *cmd)
 		i++;
 
 		/* timeline this WAL was produced on */
-		if (!XLogRecPtrIsInvalid(slot_contents.data.restart_lsn))
+		if (XLogRecPtrIsValid(slot_contents.data.restart_lsn))
 		{
 			TimeLineID	slots_position_timeline;
 			TimeLineID	current_timeline;
@@ -906,7 +906,7 @@ StartReplication(StartReplicationCmd *cmd)
 			 * that's older than the switchpoint, if it's still in the same
 			 * WAL segment.
 			 */
-			if (!XLogRecPtrIsInvalid(switchpoint) &&
+			if (XLogRecPtrIsValid(switchpoint) &&
 				switchpoint < cmd->startpoint)
 			{
 				ereport(ERROR,
@@ -1827,7 +1827,7 @@ WalSndWaitForWal(XLogRecPtr loc)
 	 * receipt of WAL up to RecentFlushPtr. This is particularly interesting
 	 * if we're far behind.
 	 */
-	if (!XLogRecPtrIsInvalid(RecentFlushPtr) &&
+	if (XLogRecPtrIsValid(RecentFlushPtr) &&
 		!NeedToWaitForWal(loc, RecentFlushPtr, &wait_event))
 		return RecentFlushPtr;
 
@@ -3597,7 +3597,7 @@ WalSndDone(WalSndSendDataCallback send_data)
 	 * flush location if valid, write otherwise. Tools like pg_receivewal will
 	 * usually (unless in synchronous mode) return an invalid flush location.
 	 */
-	replicatedPtr = XLogRecPtrIsInvalid(MyWalSnd->flush) ?
+	replicatedPtr = !XLogRecPtrIsValid(MyWalSnd->flush) ?
 		MyWalSnd->write : MyWalSnd->flush;
 
 	if (WalSndCaughtUp && sentPtr == replicatedPtr &&
@@ -4073,19 +4073,19 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
 		{
 			values[1] = CStringGetTextDatum(WalSndGetStateString(state));
 
-			if (XLogRecPtrIsInvalid(sent_ptr))
+			if (!XLogRecPtrIsValid(sent_ptr))
 				nulls[2] = true;
 			values[2] = LSNGetDatum(sent_ptr);
 
-			if (XLogRecPtrIsInvalid(write))
+			if (!XLogRecPtrIsValid(write))
 				nulls[3] = true;
 			values[3] = LSNGetDatum(write);
 
-			if (XLogRecPtrIsInvalid(flush))
+			if (!XLogRecPtrIsValid(flush))
 				nulls[4] = true;
 			values[4] = LSNGetDatum(flush);
 
-			if (XLogRecPtrIsInvalid(apply))
+			if (!XLogRecPtrIsValid(apply))
 				nulls[5] = true;
 			values[5] = LSNGetDatum(apply);
 
@@ -4094,7 +4094,7 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
 			 * which always returns an invalid flush location, as an
 			 * asynchronous standby.
 			 */
-			priority = XLogRecPtrIsInvalid(flush) ? 0 : priority;
+			priority = !XLogRecPtrIsValid(flush) ? 0 : priority;
 
 			if (writeLag < 0)
 				nulls[6] = true;
@@ -4165,7 +4165,7 @@ WalSndKeepalive(bool requestReply, XLogRecPtr writePtr)
 	/* construct the message... */
 	resetStringInfo(&output_message);
 	pq_sendbyte(&output_message, PqReplMsg_Keepalive);
-	pq_sendint64(&output_message, XLogRecPtrIsInvalid(writePtr) ? sentPtr : writePtr);
+	pq_sendint64(&output_message, !XLogRecPtrIsValid(writePtr) ? sentPtr : writePtr);
 	pq_sendint64(&output_message, GetCurrentTimestamp());
 	pq_sendbyte(&output_message, requestReply ? 1 : 0);
 
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 00719c7aea2..f830f2c6ff3 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -5545,7 +5545,7 @@ MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
 			 * checksum here. That will happen when the page is written
 			 * sometime later in this checkpoint cycle.
 			 */
-			if (!XLogRecPtrIsInvalid(lsn))
+			if (XLogRecPtrIsValid(lsn))
 				PageSetLSN(page, lsn);
 		}
 
diff --git a/src/bin/pg_basebackup/pg_receivewal.c b/src/bin/pg_basebackup/pg_receivewal.c
index 289ca14dcfe..3e6f4a7fc48 100644
--- a/src/bin/pg_basebackup/pg_receivewal.c
+++ b/src/bin/pg_basebackup/pg_receivewal.c
@@ -192,7 +192,7 @@ stop_streaming(XLogRecPtr xlogpos, uint32 timeline, bool segment_finished)
 					LSN_FORMAT_ARGS(xlogpos),
 					timeline);
 
-	if (!XLogRecPtrIsInvalid(endpos) && endpos < xlogpos)
+	if (XLogRecPtrIsValid(endpos) && endpos < xlogpos)
 	{
 		if (verbose)
 			pg_log_info("stopped log streaming at %X/%08X (timeline %u)",
diff --git a/src/bin/pg_basebackup/pg_recvlogical.c b/src/bin/pg_basebackup/pg_recvlogical.c
index 7a4d1a2d2ca..6739784a993 100644
--- a/src/bin/pg_basebackup/pg_recvlogical.c
+++ b/src/bin/pg_basebackup/pg_recvlogical.c
@@ -1080,7 +1080,7 @@ prepareToTerminate(PGconn *conn, XLogRecPtr endpos, StreamStopReason reason,
 							LSN_FORMAT_ARGS(endpos));
 				break;
 			case STREAM_STOP_END_OF_WAL:
-				Assert(!XLogRecPtrIsInvalid(lsn));
+				Assert(XLogRecPtrIsValid(lsn));
 				pg_log_info("end position %X/%08X reached by WAL record at %X/%08X",
 							LSN_FORMAT_ARGS(endpos), LSN_FORMAT_ARGS(lsn));
 				break;
diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c
index 1b953692b17..27c514f934a 100644
--- a/src/bin/pg_rewind/pg_rewind.c
+++ b/src/bin/pg_rewind/pg_rewind.c
@@ -850,9 +850,9 @@ progress_report(bool finished)
 static XLogRecPtr
 MinXLogRecPtr(XLogRecPtr a, XLogRecPtr b)
 {
-	if (XLogRecPtrIsInvalid(a))
+	if (!XLogRecPtrIsValid(a))
 		return b;
-	else if (XLogRecPtrIsInvalid(b))
+	else if (!XLogRecPtrIsValid(b))
 		return a;
 	else
 		return Min(a, b);
diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index 13d3ec2f5be..19cf5461eac 100644
--- a/src/bin/pg_waldump/pg_waldump.c
+++ b/src/bin/pg_waldump/pg_waldump.c
@@ -637,7 +637,7 @@ XLogDumpDisplayStats(XLogDumpConfig *config, XLogStats *stats)
 	/*
 	 * Leave if no stats have been computed yet, as tracked by the end LSN.
 	 */
-	if (XLogRecPtrIsInvalid(stats->endptr))
+	if (!XLogRecPtrIsValid(stats->endptr))
 		return;
 
 	/*
@@ -1136,7 +1136,7 @@ main(int argc, char **argv)
 		/* parse position from file */
 		XLogFromFileName(fname, &private.timeline, &segno, WalSegSz);
 
-		if (XLogRecPtrIsInvalid(private.startptr))
+		if (!XLogRecPtrIsValid(private.startptr))
 			XLogSegNoOffsetToRecPtr(segno, 0, WalSegSz, private.startptr);
 		else if (!XLByteInSeg(private.startptr, segno, WalSegSz))
 		{
@@ -1147,7 +1147,7 @@ main(int argc, char **argv)
 		}
 
 		/* no second file specified, set end position */
-		if (!(optind + 1 < argc) && XLogRecPtrIsInvalid(private.endptr))
+		if (!(optind + 1 < argc) && !XLogRecPtrIsValid(private.endptr))
 			XLogSegNoOffsetToRecPtr(segno + 1, 0, WalSegSz, private.endptr);
 
 		/* parse ENDSEG if passed */
@@ -1170,7 +1170,7 @@ main(int argc, char **argv)
 				pg_fatal("ENDSEG %s is before STARTSEG %s",
 						 argv[optind + 1], argv[optind]);
 
-			if (XLogRecPtrIsInvalid(private.endptr))
+			if (!XLogRecPtrIsValid(private.endptr))
 				XLogSegNoOffsetToRecPtr(endsegno + 1, 0, WalSegSz,
 										private.endptr);
 
@@ -1192,7 +1192,7 @@ main(int argc, char **argv)
 		waldir = identify_target_directory(waldir, NULL);
 
 	/* we don't know what to print */
-	if (XLogRecPtrIsInvalid(private.startptr))
+	if (!XLogRecPtrIsValid(private.startptr))
 	{
 		pg_log_error("no start WAL location given");
 		goto bad_argument;
diff --git a/src/include/access/xlogdefs.h b/src/include/access/xlogdefs.h
index 2397fb24115..b16b2a1c8a3 100644
--- a/src/include/access/xlogdefs.h
+++ b/src/include/access/xlogdefs.h
@@ -26,8 +26,16 @@ typedef uint64 XLogRecPtr;
  * record can begin at zero.
  */
 #define InvalidXLogRecPtr	0
-#define XLogRecPtrIsInvalid(r)	((r) == InvalidXLogRecPtr)
+#define XLogRecPtrIsValid(r) ((r) != InvalidXLogRecPtr)
 
+/*
+ * New code should use XLogRecPtrIsValid() instead of XLogRecPtrIsInvalid()
+ * for consistency with the affirmative form of other *IsValid() macros and to
+ * avoid awkward double negative.
+ * This macro is retained for convenience of third-party code but could
+ * be deprecated in the future.
+ */
+#define XLogRecPtrIsInvalid(r)	((r) == InvalidXLogRecPtr)
 /*
  * First LSN to use for "fake" LSNs.
  *
-- 
2.34.1

