diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c index 3e100aa..848e7e8 100644 --- a/src/backend/access/nbtree/nbtinsert.c +++ b/src/backend/access/nbtree/nbtinsert.c @@ -22,6 +22,7 @@ #include "miscadmin.h" #include "storage/lmgr.h" #include "storage/predicate.h" +#include "utils/snapmgr.h" #include "utils/tqual.h" @@ -328,6 +329,7 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, &all_dead)) { TransactionId xwait; + ItemPointerData myHtid; /* * It is a duplicate. If we are only doing a partial @@ -377,8 +379,8 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, * not part of this chain because it had a different index * entry. */ - htid = itup->t_tid; - if (heap_hot_search(&htid, heapRel, SnapshotSelf, NULL)) + myHtid = itup->t_tid; + if (heap_hot_search(&myHtid, heapRel, SnapshotSelf, NULL)) { /* Normal case --- it's still live */ } @@ -398,6 +400,21 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, * otherwise be masked by this unique constraint violation. */ CheckForSerializableConflictIn(rel, NULL, buf); + /* + * Cause a conflict-out check by simply reading the heap + * tuple. + */ + { + Buffer heapBuf; + HeapTupleData heapTuple; + bool visible; + + heapTuple.t_self = htid; + visible = heap_fetch(heapRel, GetTransactionSnapshot(), + &heapTuple, &heapBuf, false, NULL); + if (visible) + ReleaseBuffer(heapBuf); + } /* * This is a definite conflict. Break the tuple down into