From 1c68f8f7bd50ab1ef0b8a08b5b6e8d80646259a6 Mon Sep 17 00:00:00 2001 From: passwdwasforgotten <809389860@qq.com> Date: Mon, 15 Sep 2025 15:57:59 +0800 Subject: [PATCH] Fix: missing validation for tids when index's deduplicate is on In the '_bt_validate_tid' method, the IndexTuple 'ituple' is not deformed when processing the posting tuple, resulting in missing validation for certain TIDs. --- src/backend/access/nbtree/nbtree.c | 32 +++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 7c3563024db..5dc783846cb 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -223,7 +223,37 @@ _bt_validate_tid(Relation irel, ItemPointer h_tid) { itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum)); - if (ItemPointerEquals(&itup->t_tid, h_tid)) + if(BTreeTupleIsPosting(itup)) + { + ItemPointer current; + for (int i = 0; i < BTreeTupleGetNPosting(itup); i++) + { + + current = BTreeTupleGetPostingN(itup, i); + + if (ItemPointerEquals(current, h_tid) ) + { + Form_pg_attribute key_att = TupleDescAttr(RelationGetDescr(irel), 0); + Oid key = InvalidOid; + bool isnull; + if (key_att->atttypid == OIDOID) + { + key = DatumGetInt32( + index_getattr(itup, 1, RelationGetDescr(irel), &isnull)); + elog(ERROR, "found tid (%d,%d), %s (%d) already in index (%s)", + ItemPointerGetBlockNumber(h_tid), ItemPointerGetOffsetNumber(h_tid), + NameStr(key_att->attname), key, RelationGetRelationName(irel)); + } + else + { + elog(ERROR, "found tid (%d,%d) already in index (%s)", + ItemPointerGetBlockNumber(h_tid), ItemPointerGetOffsetNumber(h_tid), + RelationGetRelationName(irel)); + } + } + } + } + else if (ItemPointerEquals(&itup->t_tid, h_tid)) { Form_pg_attribute key_att = TupleDescAttr(RelationGetDescr(irel), 0); Oid key = InvalidOid;