in src/backend/executor/cypher_set.c [92:185]
static HeapTuple update_entity_tuple(ResultRelInfo *resultRelInfo,
TupleTableSlot *elemTupleSlot,
EState *estate, HeapTuple old_tuple)
{
HeapTuple tuple = NULL;
LockTupleMode lockmode;
TM_FailureData hufd;
TM_Result lock_result;
Buffer buffer;
TU_UpdateIndexes update_indexes;
TM_Result result;
CommandId cid = GetCurrentCommandId(true);
ResultRelInfo **saved_resultRels = estate->es_result_relations;
estate->es_result_relations = &resultRelInfo;
lockmode = ExecUpdateLockMode(estate, resultRelInfo);
lock_result = heap_lock_tuple(resultRelInfo->ri_RelationDesc, old_tuple,
GetCurrentCommandId(false), lockmode,
LockWaitBlock, false, &buffer, &hufd);
if (lock_result == TM_Ok)
{
ExecOpenIndices(resultRelInfo, false);
ExecStoreVirtualTuple(elemTupleSlot);
tuple = ExecFetchSlotHeapTuple(elemTupleSlot, true, NULL);
tuple->t_self = old_tuple->t_self;
/* Check the constraints of the tuple */
tuple->t_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
if (resultRelInfo->ri_RelationDesc->rd_att->constr != NULL)
{
ExecConstraints(resultRelInfo, elemTupleSlot, estate);
}
result = table_tuple_update(resultRelInfo->ri_RelationDesc,
&tuple->t_self, elemTupleSlot,
cid, estate->es_snapshot,
estate->es_crosscheck_snapshot,
true /* wait for commit */ ,
&hufd, &lockmode, &update_indexes);
if (result == TM_SelfModified)
{
if (hufd.cmax != cid)
{
ereport(ERROR,
(errcode(ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION),
errmsg("tuple to be updated was already modified")));
}
ExecCloseIndices(resultRelInfo);
estate->es_result_relations = saved_resultRels;
return tuple;
}
if (result != TM_Ok)
{
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR),
errmsg("Entity failed to be updated: %i", result)));
}
/* Insert index entries for the tuple */
if (resultRelInfo->ri_NumIndices > 0 && update_indexes != TU_None)
{
ExecInsertIndexTuples(resultRelInfo, elemTupleSlot, estate, false, false, NULL, NIL,
(update_indexes == TU_Summarizing));
}
ExecCloseIndices(resultRelInfo);
}
else if (lock_result == TM_SelfModified)
{
if (hufd.cmax != cid)
{
ereport(ERROR,
(errcode(ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION),
errmsg("tuple to be updated was already modified")));
}
}
else
{
ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR),
errmsg("Entity failed to be updated: %i", lock_result)));
}
ReleaseBuffer(buffer);
estate->es_result_relations = saved_resultRels;
return tuple;
}