diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 307c12ee69..074593b1cc 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1170,42 +1170,6 @@ lreplace:; true /* wait for commit */, &hufd, &lockmode, &update_indexes); - if (result == HeapTupleUpdated && !IsolationUsesXactSnapshot()) - { - TupleTableSlot *inputslot; - - EvalPlanQualBegin(epqstate, estate); - - inputslot = EvalPlanQualSlot(epqstate, resultRelationDesc, resultRelInfo->ri_RangeTableIndex); - ExecCopySlot(inputslot, slot); - - result = table_lock_tuple(resultRelationDesc, tupleid, - estate->es_snapshot, - inputslot, estate->es_output_cid, - lockmode, LockWaitBlock, - TUPLE_LOCK_FLAG_FIND_LAST_VERSION, - &hufd); - /* hari FIXME*/ - /*Assert(result != HeapTupleUpdated && hufd.traversed);*/ - if (result == HeapTupleMayBeUpdated) - { - TupleTableSlot *epqslot; - - epqslot = EvalPlanQual(estate, - epqstate, - resultRelationDesc, - resultRelInfo->ri_RangeTableIndex, - inputslot); - if (TupIsNull(epqslot)) - { - /* Tuple no more passing quals, exiting... */ - return NULL; - } - slot = ExecFilterJunk(resultRelInfo->ri_junkFilter, epqslot); - goto lreplace; - } - } - switch (result) { case HeapTupleSelfUpdated: @@ -1250,10 +1214,37 @@ lreplace:; ereport(ERROR, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), errmsg("could not serialize access due to concurrent update"))); - else - /* shouldn't get there */ - elog(ERROR, "wrong heap_delete status: %u", result); - break; + + if (ItemPointerIndicatesMovedPartitions(&hufd.ctid)) + ereport(ERROR, + (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), + errmsg("tuple to be updated was already moved to another partition due to concurrent update"))); + + if (!ItemPointerEquals(tupleid, &hufd.ctid)) + { + TupleTableSlot *epqslot; + TupleTableSlot *inputslot; + + EvalPlanQualBegin(epqstate, estate); + + inputslot = EvalPlanQualSlot(epqstate, resultRelationDesc, resultRelInfo->ri_RangeTableIndex); + ExecCopySlot(inputslot, slot); + + epqslot = EvalPlanQual(estate, + epqstate, + resultRelationDesc, + resultRelInfo->ri_RangeTableIndex, + inputslot); + if (!TupIsNull(epqslot)) + { + *tupleid = hufd.ctid; + slot = ExecFilterJunk(resultRelInfo->ri_junkFilter, epqslot); + slot = ExecFilterJunk(resultRelInfo->ri_junkFilter, epqslot); + goto lreplace; + } + } + /* tuple already deleted; nothing to do */ + return NULL; case HeapTupleDeleted: if (IsolationUsesXactSnapshot())