unrecognized_heap_status.patch
application/octet-stream
Filename: unrecognized_heap_status.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/executor/nodeModifyTable.c | 31 | 40 |
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())