!2131 同步代码修复解决多表update在epq期间取出的slot与目标表不匹配的问题

Merge pull request !2131 from 吴禹均/master
This commit is contained in:
opengauss-bot
2022-09-07 02:19:10 +00:00
committed by Gitee
4 changed files with 25 additions and 19 deletions

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);

View File

@ -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;
/* ----------------