@ -2702,7 +2702,7 @@ static HeapTuple GetTupleForTrigger(EState* estate, EPQState* epqstate, ResultRe
|
||||
TupleTableSlot* epqslot = NULL;
|
||||
|
||||
epqslot = EvalPlanQual(
|
||||
estate, epqstate, fakeRelation, relinfo->ri_RangeTableIndex, &tmfd.ctid, tmfd.xmax);
|
||||
estate, epqstate, fakeRelation, relinfo->ri_RangeTableIndex, &tmfd.ctid, tmfd.xmax, false);
|
||||
if (!TupIsNull(epqslot)) {
|
||||
*tid = tmfd.ctid;
|
||||
*newSlot = epqslot;
|
||||
|
||||
@ -2725,7 +2725,7 @@ ExecAuxRowMark *ExecBuildAuxRowMark(ExecRowMark *erm, List *targetlist)
|
||||
* NULL if we determine we shouldn't process the row.
|
||||
*/
|
||||
TupleTableSlot *EvalPlanQual(EState *estate, EPQState *epqstate, Relation relation, Index rti, ItemPointer tid,
|
||||
TransactionId priorXmax)
|
||||
TransactionId priorXmax, bool partRowMoveUpdate)
|
||||
{
|
||||
TupleTableSlot *slot = NULL;
|
||||
HeapTuple copyTuple;
|
||||
@ -2739,6 +2739,19 @@ TupleTableSlot *EvalPlanQual(EState *estate, EPQState *epqstate, Relation relati
|
||||
relation, LockTupleExclusive, tid, priorXmax);
|
||||
|
||||
if (copyTuple == NULL) {
|
||||
/*
|
||||
* The tuple has been deleted or update in row movement case.
|
||||
*/
|
||||
if (partRowMoveUpdate) {
|
||||
/*
|
||||
* the may be a row movement update action which delete tuple from original
|
||||
* partition and insert tuple to new partition or we can add lock on the tuple
|
||||
* to be delete or updated to avoid throw exception.
|
||||
*/
|
||||
ereport(ERROR, (errcode(ERRCODE_TRANSACTION_ROLLBACK),
|
||||
errmsg("partition table update conflict"),
|
||||
errdetail("disable row movement of table can avoid this conflict")));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -1194,7 +1194,8 @@ TupleTableSlot* ExecDelete(ItemPointer tupleid, Oid deletePartitionOid, int2 buc
|
||||
fake_relation,
|
||||
result_rel_info->ri_RangeTableIndex,
|
||||
&tmfd.ctid,
|
||||
tmfd.xmax);
|
||||
tmfd.xmax,
|
||||
false);
|
||||
if (!TupIsNull(epqslot)) {
|
||||
*tupleid = tmfd.ctid;
|
||||
goto ldelete;
|
||||
@ -1641,7 +1642,8 @@ TupleTableSlot* ExecUpdate(ItemPointer tupleid,
|
||||
fake_relation,
|
||||
result_rel_info->ri_RangeTableIndex,
|
||||
&tmfd.ctid,
|
||||
tmfd.xmax);
|
||||
tmfd.xmax,
|
||||
false);
|
||||
if (!TupIsNull(epq_slot)) {
|
||||
*tupleid = tmfd.ctid;
|
||||
|
||||
@ -1866,7 +1868,8 @@ TupleTableSlot* ExecUpdate(ItemPointer tupleid,
|
||||
fake_relation,
|
||||
result_rel_info->ri_RangeTableIndex,
|
||||
&tmfd.ctid,
|
||||
tmfd.xmax);
|
||||
tmfd.xmax,
|
||||
result_relation_desc->rd_rel->relrowmovement);
|
||||
|
||||
if (!TupIsNull(epq_slot)) {
|
||||
*tupleid = tmfd.ctid;
|
||||
@ -2022,7 +2025,8 @@ TupleTableSlot* ExecUpdate(ItemPointer tupleid,
|
||||
old_fake_relation,
|
||||
result_rel_info->ri_RangeTableIndex,
|
||||
&tmfd.ctid,
|
||||
tmfd.xmax);
|
||||
tmfd.xmax,
|
||||
result_relation_desc->rd_rel->relrowmovement);
|
||||
if (!TupIsNull(epq_slot)) {
|
||||
*tupleid = tmfd.ctid;
|
||||
goto ldelete;
|
||||
|
||||
@ -225,8 +225,8 @@ extern bool ExecContextForcesOids(PlanState* planstate, bool* hasoids);
|
||||
extern void ExecConstraints(ResultRelInfo* resultRelInfo, TupleTableSlot* slot, EState* estate);
|
||||
extern ExecRowMark* ExecFindRowMark(EState* estate, Index rti);
|
||||
extern ExecAuxRowMark* ExecBuildAuxRowMark(ExecRowMark* erm, List* targetlist);
|
||||
extern TupleTableSlot* EvalPlanQual(
|
||||
EState* estate, EPQState* epqstate, Relation relation, Index rti, ItemPointer tid, TransactionId priorXmax);
|
||||
extern TupleTableSlot* EvalPlanQual(EState* estate, EPQState* epqstate, Relation relation, Index rti,
|
||||
ItemPointer tid, TransactionId priorXmax, bool partRowMoveUpdate);
|
||||
extern HeapTuple heap_lock_updated(
|
||||
CommandId cid, Relation relation, int lockmode, ItemPointer tid, TransactionId priorXmax);
|
||||
extern void EvalPlanQualInit(EPQState* epqstate, EState* estate, Plan* subplan, List* auxrowmarks, int epqParam);
|
||||
|
||||
Reference in New Issue
Block a user