{
case TM_Ok:
Assert(context->tmfd.traversed);
-
- /*
- * Save locked tuple for further processing of
- * RETURNING clause.
- */
- if (processReturning &&
- resultRelInfo->ri_projectReturning &&
- !resultRelInfo->ri_FdwRoutine)
- {
- TupleTableSlot *returningSlot;
-
- returningSlot = ExecGetReturningSlot(estate, resultRelInfo);
- ExecCopySlot(returningSlot, inputslot);
- ExecMaterializeSlot(returningSlot);
- }
-
epqslot = EvalPlanQual(context->epqstate,
resultRelationDesc,
resultRelInfo->ri_RangeTableIndex,
}
else
{
- /*
- * Tuple can be already fetched to the returning slot in case
- * we've previously locked it. Fetch the tuple only if the slot
- * is empty.
- */
slot = ExecGetReturningSlot(estate, resultRelInfo);
if (oldtuple != NULL)
{
ExecForceStoreHeapTuple(oldtuple, slot, false);
}
- else if (TupIsNull(slot))
+ else
{
if (!table_tuple_fetch_row_version(resultRelationDesc, tupleid,
SnapshotAny, slot))
case TM_Ok:
Assert(context->tmfd.traversed);
- /* Make sure ri_oldTupleSlot is initialized. */
- if (unlikely(!resultRelInfo->ri_projectNewInfoValid))
- ExecInitUpdateProjection(context->mtstate,
- resultRelInfo);
-
- /*
- * Save the locked tuple for further calculation
- * of the new tuple.
- */
- oldSlot = resultRelInfo->ri_oldTupleSlot;
- ExecCopySlot(oldSlot, inputslot);
- ExecMaterializeSlot(oldSlot);
-
epqslot = EvalPlanQual(context->epqstate,
resultRelationDesc,
resultRelInfo->ri_RangeTableIndex,
/* Tuple not passing quals anymore, exiting... */
return NULL;
+ /* Make sure ri_oldTupleSlot is initialized. */
+ if (unlikely(!resultRelInfo->ri_projectNewInfoValid))
+ ExecInitUpdateProjection(context->mtstate,
+ resultRelInfo);
+
+ /* Fetch the most recent version of old tuple. */
+ oldSlot = resultRelInfo->ri_oldTupleSlot;
+ if (!table_tuple_fetch_row_version(resultRelationDesc,
+ tupleid,
+ SnapshotAny,
+ oldSlot))
+ elog(ERROR, "failed to fetch tuple being updated");
slot = ExecGetUpdateNewTuple(resultRelInfo,
epqslot, oldSlot);
goto redo_act;