!2131 同步代码修复解决多表update在epq期间取出的slot与目标表不匹配的问题
Merge pull request !2131 from 吴禹均/master
This commit is contained in:
@ -3154,9 +3154,11 @@ HeapTuple heap_lock_updated(CommandId cid, Relation relation, int lockmode, Item
|
||||
* that might need to invoke EPQ processing.
|
||||
*
|
||||
* Note: subplan/auxrowmarks can be NULL/NIL if they will be set later
|
||||
* with EvalPlanQualSetPlan.
|
||||
* with EvalPlanQualSetPlan. projInfos is used for Multiple-Modify to
|
||||
* fetch the slot corresponding to the target table.
|
||||
*/
|
||||
void EvalPlanQualInit(EPQState *epqstate, EState *estate, Plan *subplan, List *auxrowmarks, int epqParam)
|
||||
void EvalPlanQualInit(EPQState *epqstate, EState *estate, Plan *subplan, List *auxrowmarks, int epqParam,
|
||||
ProjectionInfo** projInfos)
|
||||
{
|
||||
/* Mark the EPQ state inactive */
|
||||
epqstate->estate = NULL;
|
||||
@ -3167,6 +3169,7 @@ void EvalPlanQualInit(EPQState *epqstate, EState *estate, Plan *subplan, List *a
|
||||
epqstate->arowMarks = auxrowmarks;
|
||||
epqstate->epqParam = epqParam;
|
||||
epqstate->parentestate = estate;
|
||||
epqstate->projInfos = projInfos;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3564,7 +3567,7 @@ void EvalPlanQualFetchRowMarks(EPQState *epqstate)
|
||||
TupleTableSlot *EvalPlanQualNext(EPQState *epqstate)
|
||||
{
|
||||
MemoryContext old_context = MemoryContextSwitchTo(epqstate->estate->es_query_cxt);
|
||||
TupleTableSlot *slot = ExecProcNode(epqstate->planstate);
|
||||
TupleTableSlot *slot = FetchPlanSlot(epqstate->planstate, epqstate->projInfos);
|
||||
(void)MemoryContextSwitchTo(old_context);
|
||||
|
||||
return slot;
|
||||
@ -3791,3 +3794,14 @@ void EvalPlanQualEnd(EPQState *epqstate)
|
||||
epqstate->planstate = NULL;
|
||||
epqstate->origslot = NULL;
|
||||
}
|
||||
|
||||
TupleTableSlot* FetchPlanSlot(PlanState* subPlanState, ProjectionInfo** projInfos)
|
||||
{
|
||||
int result_rel_index = subPlanState->state->result_rel_index;
|
||||
|
||||
if (result_rel_index > 0) {
|
||||
return ExecProject(projInfos[result_rel_index], NULL);
|
||||
} else {
|
||||
return ExecProcNode(subPlanState);
|
||||
}
|
||||
}
|
@ -3120,17 +3120,6 @@ uint64 GetDeleteLimitCount(ExprContext* econtext, PlanState* scan, Limit *limitP
|
||||
return (uint64)iCount;
|
||||
}
|
||||
|
||||
static TupleTableSlot* FetchPlanSlot(ModifyTableState* node, PlanState* subPlanState)
|
||||
{
|
||||
EState* estate = node->ps.state;
|
||||
|
||||
if (estate->result_rel_index > 0) {
|
||||
return ExecProject(node->mt_ProjInfos[estate->result_rel_index], NULL);
|
||||
} else {
|
||||
return ExecProcNode(subPlanState);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* ExecModifyTable
|
||||
*
|
||||
@ -3287,7 +3276,7 @@ TupleTableSlot* ExecModifyTable(ModifyTableState* node)
|
||||
*/
|
||||
ResetPerTupleExprContext(estate);
|
||||
t_thrd.xact_cxt.ActiveLobRelid = result_rel_info->ri_RelationDesc->rd_id;
|
||||
plan_slot = FetchPlanSlot(node, subPlanState);
|
||||
plan_slot = FetchPlanSlot(subPlanState, node->mt_ProjInfos);
|
||||
t_thrd.xact_cxt.ActiveLobRelid = InvalidOid;
|
||||
if (TupIsNull(plan_slot)) {
|
||||
record_first_time();
|
||||
@ -3662,8 +3651,6 @@ ModifyTableState* ExecInitModifyTable(ModifyTable* node, EState* estate, int efl
|
||||
upsertState->us_updateWhere = NIL;
|
||||
mt_state->mt_upsert = upsertState;
|
||||
|
||||
/* set up epqstate with dummy subplan data for the moment */
|
||||
EvalPlanQualInit(&mt_state->mt_epqstate, estate, NULL, NIL, node->epqParam);
|
||||
mt_state->fireBSTriggers = true;
|
||||
|
||||
/*
|
||||
@ -3809,6 +3796,8 @@ ModifyTableState* ExecInitModifyTable(ModifyTable* node, EState* estate, int efl
|
||||
i++;
|
||||
}
|
||||
#endif
|
||||
/* set up epqstate with dummy subplan data for the moment */
|
||||
EvalPlanQualInit(&mt_state->mt_epqstate, estate, NULL, NIL, node->epqParam);
|
||||
|
||||
estate->es_result_relation_info = saved_result_rel_info;
|
||||
#ifdef PGXC
|
||||
|
@ -237,7 +237,8 @@ extern TupleTableSlot* EvalPlanQualUHeap(EState* estate, EPQState* epqstate, Rel
|
||||
extern TupleTableSlot *EvalPlanQualUSlot(EPQState *epqstate, Relation relation, Index rti);
|
||||
extern HeapTuple EvalPlanQualFetch(
|
||||
EState* estate, Relation relation, int lockmode, ItemPointer tid, TransactionId priorXmax);
|
||||
extern void EvalPlanQualInit(EPQState* epqstate, EState* estate, Plan* subplan, List* auxrowmarks, int epqParam);
|
||||
extern void EvalPlanQualInit(EPQState* epqstate, EState* estate, Plan* subplan, List* auxrowmarks, int epqParam,
|
||||
ProjectionInfo** projInfos = NULL);
|
||||
extern void EvalPlanQualSetPlan(EPQState* epqstate, Plan* subplan, List* auxrowmarks);
|
||||
extern void EvalPlanQualSetTuple(EPQState* epqstate, Index rti, Tuple tuple);
|
||||
extern Tuple EvalPlanQualGetTuple(EPQState* epqstate, Index rti);
|
||||
@ -257,6 +258,7 @@ extern TupleTableSlot* ExecProcNode(PlanState* node);
|
||||
extern Node* MultiExecProcNode(PlanState* node);
|
||||
extern void ExecEndNode(PlanState* node);
|
||||
extern bool NeedStubExecution(Plan* plan);
|
||||
extern TupleTableSlot* FetchPlanSlot(PlanState* subPlanState, ProjectionInfo** projInfos);
|
||||
|
||||
extern long ExecGetPlanMemCost(Plan* node);
|
||||
|
||||
|
@ -1325,6 +1325,7 @@ typedef struct EPQState {
|
||||
* We need its memory context to palloc es_epqTupleSlot if needed
|
||||
*/
|
||||
EState *parentestate;
|
||||
ProjectionInfo** projInfos; /* for multiple modifying to fetch slot. */
|
||||
} EPQState;
|
||||
|
||||
/* ----------------
|
||||
|
Reference in New Issue
Block a user