Skip to content

Commit

Permalink
Reduce API changes to tableam and ModifyTable routines
Browse files Browse the repository at this point in the history
  • Loading branch information
alvherre committed Jan 28, 2022
1 parent a1861f3 commit 1bc92bd
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 128 deletions.
29 changes: 13 additions & 16 deletions src/backend/access/heap/heapam.c
Original file line number Diff line number Diff line change
Expand Up @@ -2898,7 +2898,6 @@ heap_delete(Relation relation, ItemPointer tid,
Assert(!(tp.t_data->t_infomask & HEAP_XMAX_INVALID));
Assert(result != TM_Updated ||
!ItemPointerEquals(&tp.t_self, &tp.t_data->t_ctid));
tmfd->result = result;
tmfd->ctid = tp.t_data->t_ctid;
tmfd->xmax = HeapTupleHeaderGetUpdateXid(tp.t_data);
if (result == TM_SelfModified)
Expand Down Expand Up @@ -3148,12 +3147,12 @@ simple_heap_delete(Relation relation, ItemPointer tid)
* In the failure cases, the routine fills *tmfd with the tuple's t_ctid,
* t_xmax (resolving a possible MultiXact, if necessary), and t_cmax (the last
* only for TM_SelfModified, since we cannot obtain cmax from a combo CID
* generated by another transaction). XXX and stuff added by MERGE.
* generated by another transaction).
*/
TM_Result
heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
CommandId cid, Snapshot crosscheck, bool wait,
TM_FailureData *tmfd)
TM_FailureData *tmfd, LockTupleMode *lockmode)
{
TM_Result result;
TransactionId xid = GetCurrentTransactionId();
Expand Down Expand Up @@ -3191,7 +3190,6 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
infomask2_old_tuple,
infomask_new_tuple,
infomask2_new_tuple;
LockTupleMode lockmode;

Assert(ItemPointerIsValid(otid));
Assert(tmfd != NULL);
Expand Down Expand Up @@ -3282,7 +3280,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
*/
if (!bms_overlap(modified_attrs, key_attrs))
{
lockmode = tmfd->lockmode = LockTupleNoKeyExclusive;
*lockmode = LockTupleNoKeyExclusive;
mxact_status = MultiXactStatusNoKeyUpdate;
key_intact = true;

Expand All @@ -3299,7 +3297,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
}
else
{
lockmode = tmfd->lockmode = LockTupleExclusive;
*lockmode = LockTupleExclusive;
mxact_status = MultiXactStatusUpdate;
key_intact = false;
}
Expand Down Expand Up @@ -3378,7 +3376,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
bool current_is_member = false;

if (DoesMultiXactIdConflict((MultiXactId) xwait, infomask,
lockmode, &current_is_member))
*lockmode, &current_is_member))
{
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);

Expand All @@ -3387,7 +3385,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
* requesting a lock and already have one; avoids deadlock).
*/
if (!current_is_member)
heap_acquire_tuplock(relation, &(oldtup.t_self), lockmode,
heap_acquire_tuplock(relation, &(oldtup.t_self), *lockmode,
LockWaitBlock, &have_tuple_lock);

/* wait for multixact */
Expand Down Expand Up @@ -3472,7 +3470,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
* lock.
*/
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
heap_acquire_tuplock(relation, &(oldtup.t_self), lockmode,
heap_acquire_tuplock(relation, &(oldtup.t_self), *lockmode,
LockWaitBlock, &have_tuple_lock);
XactLockTableWait(xwait, relation, &oldtup.t_self,
XLTW_Update);
Expand Down Expand Up @@ -3522,7 +3520,6 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
Assert(!(oldtup.t_data->t_infomask & HEAP_XMAX_INVALID));
Assert(result != TM_Updated ||
!ItemPointerEquals(&oldtup.t_self, &oldtup.t_data->t_ctid));
tmfd->result = result;
tmfd->ctid = oldtup.t_data->t_ctid;
tmfd->xmax = HeapTupleHeaderGetUpdateXid(oldtup.t_data);
if (result == TM_SelfModified)
Expand All @@ -3531,7 +3528,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
tmfd->cmax = InvalidCommandId;
UnlockReleaseBuffer(buffer);
if (have_tuple_lock)
UnlockTupleTuplock(relation, &(oldtup.t_self), lockmode);
UnlockTupleTuplock(relation, &(oldtup.t_self), *lockmode);
if (vmbuffer != InvalidBuffer)
ReleaseBuffer(vmbuffer);
bms_free(hot_attrs);
Expand Down Expand Up @@ -3568,7 +3565,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
compute_new_xmax_infomask(HeapTupleHeaderGetRawXmax(oldtup.t_data),
oldtup.t_data->t_infomask,
oldtup.t_data->t_infomask2,
xid, lockmode, true,
xid, *lockmode, true,
&xmax_old_tuple, &infomask_old_tuple,
&infomask2_old_tuple);

Expand Down Expand Up @@ -3685,7 +3682,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
compute_new_xmax_infomask(HeapTupleHeaderGetRawXmax(oldtup.t_data),
oldtup.t_data->t_infomask,
oldtup.t_data->t_infomask2,
xid, lockmode, false,
xid, *lockmode, false,
&xmax_lock_old_tuple, &infomask_lock_old_tuple,
&infomask2_lock_old_tuple);

Expand Down Expand Up @@ -4000,7 +3997,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
* Release the lmgr tuple lock, if we had it.
*/
if (have_tuple_lock)
UnlockTupleTuplock(relation, &(oldtup.t_self), lockmode);
UnlockTupleTuplock(relation, &(oldtup.t_self), *lockmode);

pgstat_count_heap_update(relation, use_hot_update);

Expand Down Expand Up @@ -4145,11 +4142,12 @@ simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup)
{
TM_Result result;
TM_FailureData tmfd;
LockTupleMode lockmode;

result = heap_update(relation, otid, tup,
GetCurrentCommandId(true), InvalidSnapshot,
true /* wait for commit */ ,
&tmfd);
&tmfd, &lockmode);
switch (result)
{
case TM_SelfModified:
Expand Down Expand Up @@ -4766,7 +4764,6 @@ heap_lock_tuple(Relation relation, HeapTuple tuple,
!(tuple->t_data->t_infomask & HEAP_XMAX_INVALID));
Assert(result != TM_Updated ||
!ItemPointerEquals(&tuple->t_self, &tuple->t_data->t_ctid));
tmfd->result = result;
tmfd->ctid = tuple->t_data->t_ctid;
tmfd->xmax = HeapTupleHeaderGetUpdateXid(tuple->t_data);
if (result == TM_SelfModified)
Expand Down
3 changes: 1 addition & 2 deletions src/backend/access/heap/heapam_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,7 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot,
tuple->t_tableOid = slot->tts_tableOid;

result = heap_update(relation, otid, tuple, cid, crosscheck, wait,
tmfd);
*lockmode = tmfd->lockmode;
tmfd, lockmode);
ItemPointerCopy(&tuple->t_self, &slot->tts_tid);

/*
Expand Down
12 changes: 6 additions & 6 deletions src/backend/commands/trigger.c
Original file line number Diff line number Diff line change
Expand Up @@ -2700,7 +2700,7 @@ ExecBRDeleteTriggers(EState *estate, EPQState *epqstate,
ItemPointer tupleid,
HeapTuple fdw_trigtuple,
TupleTableSlot **epqslot,
TM_FailureData *tmfdp)
TM_FailureData *tmfd)
{
TupleTableSlot *slot = ExecGetTriggerOldSlot(estate, relinfo);
TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
Expand All @@ -2716,7 +2716,8 @@ ExecBRDeleteTriggers(EState *estate, EPQState *epqstate,
TupleTableSlot *epqslot_candidate = NULL;

if (!GetTupleForTrigger(estate, epqstate, relinfo, tupleid,
LockTupleExclusive, slot, &epqslot_candidate, tmfdp))
LockTupleExclusive, slot, &epqslot_candidate,
tmfd))
return false;

/*
Expand All @@ -2731,7 +2732,6 @@ ExecBRDeleteTriggers(EState *estate, EPQState *epqstate,
}

trigtuple = ExecFetchSlotHeapTuple(slot, true, &should_free);

}
else
{
Expand Down Expand Up @@ -2939,7 +2939,7 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate,
ItemPointer tupleid,
HeapTuple fdw_trigtuple,
TupleTableSlot *newslot,
TM_FailureData *tmfdp)
TM_FailureData *tmfd)
{
TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
TupleTableSlot *oldslot = ExecGetTriggerOldSlot(estate, relinfo);
Expand All @@ -2963,7 +2963,7 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate,
/* get a copy of the on-disk tuple we are planning to update */
if (!GetTupleForTrigger(estate, epqstate, relinfo, tupleid,
lockmode, oldslot, &epqslot_candidate,
tmfdp))
tmfd))
return false; /* cancel the update action */

/*
Expand Down Expand Up @@ -3272,7 +3272,7 @@ GetTupleForTrigger(EState *estate,
lockflags,
&tmfd);

/* Let the caller know about failure reason, if any. */
/* Let the caller know about the status of this operation */
if (tmfdp)
*tmfdp = tmfd;

Expand Down
44 changes: 23 additions & 21 deletions src/backend/executor/execMerge.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,6 @@ ExecMergeMatched(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo,
{
ExprContext *econtext = mtstate->ps.ps_ExprContext;
bool isNull;
TM_FailureData tmfd;
bool tuple_updated,
tuple_deleted;
EPQState *epqstate = &mtstate->mt_epqstate;
ListCell *l;

Expand Down Expand Up @@ -216,6 +213,7 @@ ExecMergeMatched(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo,
{
MergeActionState *relaction = (MergeActionState *) lfirst(l);
CmdType commandType = relaction->mas_action->commandType;
ExecMergeActionInfo actionInfo = {0};

/*
* Test condition, if any.
Expand Down Expand Up @@ -259,24 +257,26 @@ ExecMergeMatched(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo,
* have any.
*/
ExecProject(relaction->mas_proj);
actionInfo.actionState = relaction;
slot = ExecUpdate(mtstate, resultRelInfo,
tupleid, NULL,
resultRelInfo->ri_newTupleSlot,
slot, epqstate, estate,
&tuple_updated, &tmfd,
relaction, mtstate->canSetTag);
&actionInfo,
mtstate->canSetTag);
break;

case CMD_DELETE:
actionInfo.actionState = relaction;
slot = ExecDelete(mtstate, resultRelInfo,
tupleid, NULL,
slot, epqstate, estate,
false,
mtstate->canSetTag,
false /* changingPart */ ,
&tmfd,
relaction,
&tuple_deleted, NULL /* epqslot */ );
NULL,
&actionInfo,
NULL /* epqslot */ );

break;

Expand All @@ -294,10 +294,10 @@ ExecMergeMatched(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo,
* prevented our update/delete. We also check for situations where we
* might be trying to update/delete the same tuple twice.
*/
if ((commandType == CMD_UPDATE && !tuple_updated) ||
(commandType == CMD_DELETE && !tuple_deleted))
if ((commandType == CMD_UPDATE && !actionInfo.updated) ||
(commandType == CMD_DELETE && !actionInfo.deleted))
{
switch (tmfd.result)
switch (actionInfo.result)
{
case TM_Ok:
/* all good */
Expand All @@ -318,7 +318,7 @@ ExecMergeMatched(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo,
/*
* The SQL standard disallows this for MERGE.
*/
if (TransactionIdIsCurrentTransactionId(tmfd.xmax))
if (TransactionIdIsCurrentTransactionId(actionInfo.failureData.xmax))
ereport(ERROR,
(errcode(ERRCODE_CARDINALITY_VIOLATION),
errmsg("MERGE command cannot affect row a second time"),
Expand Down Expand Up @@ -348,7 +348,7 @@ ExecMergeMatched(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo,
* actions, starting from the top, and execute the first
* qualifying action.
*/
if (!ItemPointerEquals(tupleid, &tmfd.ctid))
if (!ItemPointerEquals(tupleid, &actionInfo.failureData.ctid))
{
Relation resultRelationDesc = resultRelInfo->ri_RelationDesc;
TupleTableSlot *epqslot,
Expand All @@ -364,7 +364,7 @@ ExecMergeMatched(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo,
inputslot, estate->es_output_cid,
lockmode, LockWaitBlock,
TUPLE_LOCK_FLAG_FIND_LAST_VERSION,
&tmfd);
&actionInfo.failureData);
switch (result)
{
case TM_Ok:
Expand Down Expand Up @@ -397,7 +397,7 @@ ExecMergeMatched(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo,
* to which the tuple moved, and setting our
* current resultRelInfo to that.
*/
if (ItemPointerIndicatesMovedPartitions(&tmfd.ctid))
if (ItemPointerIndicatesMovedPartitions(&actionInfo.failureData.ctid))
ereport(ERROR,
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
errmsg("tuple to be deleted was already moved to another partition due to concurrent update")));
Expand All @@ -412,7 +412,7 @@ ExecMergeMatched(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo,
* Update *tupleid to that of the new tuple,
* for the refetch we do at the top.
*/
*tupleid = tmfd.ctid;
*tupleid = actionInfo.failureData.ctid;
goto lmerge_matched;

case TM_Deleted:
Expand All @@ -436,7 +436,7 @@ ExecMergeMatched(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo,
* See also response to TM_SelfModified in
* ExecUpdate().
*/
if (tmfd.cmax != estate->es_output_cid)
if (actionInfo.failureData.cmax != estate->es_output_cid)
ereport(ERROR,
(errcode(ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION),
errmsg("tuple to be updated or deleted was already modified by an operation triggered by the current command"),
Expand All @@ -456,7 +456,7 @@ ExecMergeMatched(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo,
* Tell the caller about the updated TID, restore the
* state back and return.
*/
*tupleid = tmfd.ctid;
*tupleid = actionInfo.failureData.ctid;
return false;

default:
Expand All @@ -465,9 +465,9 @@ ExecMergeMatched(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo,
}
}

if (commandType == CMD_UPDATE && tuple_updated)
if (commandType == CMD_UPDATE && actionInfo.updated)
InstrCountFiltered2(&mtstate->ps, 1);
if (commandType == CMD_DELETE && tuple_deleted)
if (commandType == CMD_DELETE && actionInfo.deleted)
InstrCountFiltered3(&mtstate->ps, 1);

/*
Expand Down Expand Up @@ -520,6 +520,7 @@ ExecMergeNotMatched(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo,
{
MergeActionState *action = (MergeActionState *) lfirst(l);
CmdType commandType = action->mas_action->commandType;
ExecMergeActionInfo actionInfo = {0};

/*
* Test condition, if any.
Expand All @@ -541,11 +542,12 @@ ExecMergeNotMatched(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo,
* projection was already built to use the root's descriptor,
* so we don't need to map the tuple here.
*/
actionInfo.actionState = action;
insert_slot = ExecProject(action->mas_proj);

(void) ExecInsert(mtstate, rootRelInfo,
insert_slot, slot,
estate, action,
estate, &actionInfo,
mtstate->canSetTag);
InstrCountFiltered1(&mtstate->ps, 1);
break;
Expand Down
Loading

0 comments on commit 1bc92bd

Please sign in to comment.