add_is_empty.diff

application/octet-stream

Filename: add_is_empty.diff
Type: application/octet-stream
Part: 0
Message: RE: Re:BUG #18369: logical decoding core on AssertTXNLsnOrder()

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
File+
src/backend/replication/logical/reorderbuffer.c 31 2
diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index 3a68a393d2..275ccc03be 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -222,6 +222,9 @@ static void ReorderBufferTransferSnapToParent(ReorderBufferTXN *txn,
 											  ReorderBufferTXN *subtxn);
 
 static void AssertTXNLsnOrder(ReorderBuffer *rb);
+#ifdef USE_ASSERT_CHECKING
+static bool ReorderBufferTXNIsEmpty(ReorderBufferTXN *txn);
+#endif
 
 /* ---------------------------------------
  * support functions for lsn-order iterating over the ->changes of a
@@ -918,9 +921,18 @@ AssertTXNLsnOrder(ReorderBuffer *rb)
 		if (cur_txn->end_lsn != InvalidXLogRecPtr)
 			Assert(cur_txn->first_lsn <= cur_txn->end_lsn);
 
-		/* Current initial LSN must be strictly higher than previous */
+		/*
+		 * Current initial LSN must be strictly higher than previous, except
+		 * the transaction is empty. In such a case, the initial LSN must be
+		 * the same as the previous one.
+		 */
 		if (prev_first_lsn != InvalidXLogRecPtr)
-			Assert(prev_first_lsn < cur_txn->first_lsn);
+		{
+			if (prev_first_lsn == cur_txn->first_lsn)
+				Assert(ReorderBufferTXNIsEmpty(cur_txn));
+			else
+				Assert(prev_first_lsn < cur_txn->first_lsn);
+		}
 
 		/* known-as-subtxn txns must not be listed */
 		Assert(!rbtxn_is_known_subxact(cur_txn));
@@ -950,6 +962,23 @@ AssertTXNLsnOrder(ReorderBuffer *rb)
 #endif
 }
 
+#ifdef USE_ASSERT_CHECKING
+/*
+ * ReorderBufferTXNIsEmpty
+ *
+ * Check the transaction is empty or not.
+ */
+static bool
+ReorderBufferTXNIsEmpty(ReorderBufferTXN *txn)
+{
+	return txn->nentries == 0 &&
+		   txn->nentries_mem == 0 &&
+		   txn->ntuplecids == 0 &&
+		   txn->nsubtxns == 0 &&
+		   txn->ninvalidations == 0;
+}
+#endif
+
 /*
  * AssertChangeLsnOrder
  *