From 2847e83ef91bfa3e3ebda6a8acd60bd835950716 Mon Sep 17 00:00:00 2001
From: Pavel Borisov <pashkin.elfe@gmail.com>
Date: Thu, 25 Apr 2024 13:08:39 +0400
Subject: [PATCH v1 1/5] Amcheck: optimize speed of checking unique constraint

Check heap visibility only for non-equal non-deduplicated index
tuples. For deduplicated tuples we still need to check visibility
of all posting list entries because they represent equal
key values.

Reported-by: Noah Misch
---
 contrib/amcheck/verify_nbtree.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c
index 20da4a46ba..ae8012f15b 100644
--- a/contrib/amcheck/verify_nbtree.c
+++ b/contrib/amcheck/verify_nbtree.c
@@ -1428,6 +1428,7 @@ bt_target_page_check(BtreeCheckState *state)
 		BTScanInsert skey;
 		bool		lowersizelimit;
 		ItemPointer scantid;
+		bool		unique_checked = false;
 
 		CHECK_FOR_INTERRUPTS();
 
@@ -1774,10 +1775,14 @@ bt_target_page_check(BtreeCheckState *state)
 		 * heap tuples visibility.
 		 */
 		if (state->checkunique && state->indexinfo->ii_Unique &&
-			P_ISLEAF(topaque) && !skey->anynullkeys)
+			P_ISLEAF(topaque) && !skey->anynullkeys &&
+			(BTreeTupleIsPosting(itup) || ItemPointerIsValid(lVis_tid)))
+		{
 			bt_entry_unique_check(state, itup, state->targetblock, offset,
 								  &lVis_i, &lVis_tid, &lVis_offset,
 								  &lVis_block);
+			unique_checked = true;
+		}
 
 		if (state->checkunique && state->indexinfo->ii_Unique &&
 			P_ISLEAF(topaque) && OffsetNumberNext(offset) <= max)
@@ -1805,6 +1810,12 @@ bt_target_page_check(BtreeCheckState *state)
 				lVis_block = InvalidBlockNumber;
 				lVis_offset = InvalidOffsetNumber;
 			}
+			else if (!unique_checked)
+			{
+				bt_entry_unique_check(state, itup, state->targetblock, offset,
+									  &lVis_i, &lVis_tid, &lVis_offset,
+									  &lVis_block);
+			}
 			skey->scantid = scantid;	/* Restore saved scan key state */
 		}
 
@@ -1889,6 +1900,11 @@ bt_target_page_check(BtreeCheckState *state)
 				/* The first key on the next page is the same */
 				if (_bt_compare(state->rel, rightkey, state->target, max) == 0 && !rightkey->anynullkeys)
 				{
+					if (!unique_checked)
+						bt_entry_unique_check(state, itup, state->targetblock, offset,
+											  &lVis_i, &lVis_tid, &lVis_offset,
+											  &lVis_block);
+
 					elog(DEBUG2, "cross page equal keys");
 					state->target = palloc_btree_page(state,
 													  rightblock_number);
-- 
2.34.1

