diff options
Diffstat (limited to 'src/include/nodes/execnodes.h')
-rw-r--r-- | src/include/nodes/execnodes.h | 83 |
1 files changed, 67 insertions, 16 deletions
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index f42189d2bf6..b593d22c48a 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -571,17 +571,12 @@ typedef struct EState ExprContext *es_per_tuple_exprcontext; /* - * These fields are for re-evaluating plan quals when an updated tuple is - * substituted in READ COMMITTED mode. es_epqTupleSlot[] contains test - * tuples that scan plan nodes should return instead of whatever they'd - * normally return, or an empty slot if there is nothing to return; if - * es_epqTupleSlot[] is not NULL if a particular array entry is valid; and - * es_epqScanDone[] is state to remember if the tuple has been returned - * already. Arrays are of size es_range_table_size and are indexed by - * scan node scanrelid - 1. + * If not NULL, this is an EPQState's EState. This is a field in EState + * both to allow EvalPlanQual aware executor nodes to detect that they + * need to perform EPQ related work, and to provide necessary information + * to do so. */ - TupleTableSlot **es_epqTupleSlot; /* array of EPQ substitute tuples */ - bool *es_epqScanDone; /* true if EPQ tuple has been fetched */ + struct EPQState *es_epq_active; bool es_use_parallel_mode; /* can we use parallel workers? */ @@ -1057,17 +1052,73 @@ typedef struct PlanState /* * EPQState is state for executing an EvalPlanQual recheck on a candidate - * tuple in ModifyTable or LockRows. The estate and planstate fields are - * NULL if inactive. + * tuples e.g. in ModifyTable or LockRows. + * + * To execute EPQ a separate EState is created (stored in ->recheckestate), + * which shares some resources, like the rangetable, with the main query's + * EState (stored in ->parentestate). The (sub-)tree of the plan that needs to + * be rechecked (in ->plan), is separately initialized (into + * ->recheckplanstate), but shares plan nodes with the corresponding nodes in + * the main query. The scan nodes in that separate executor tree are changed + * to return only the current tuple of interest for the respective + * table. Those tuples are either provided by the caller (using + * EvalPlanQualSlot), and/or found using the rowmark mechanism (non-locking + * rowmarks by the EPQ machinery itself, locking ones by the caller). + * + * While the plan to be checked may be changed using EvalPlanQualSetPlan() - + * e.g. so all source plans for a ModifyTable node can be processed - all such + * plans need to share the same EState. */ typedef struct EPQState { - EState *estate; /* subsidiary EState */ - PlanState *planstate; /* plan state tree ready to be executed */ - TupleTableSlot *origslot; /* original output tuple to be rechecked */ + /* Initialized at EvalPlanQualInit() time: */ + + EState *parentestate; /* main query's EState */ + int epqParam; /* ID of Param to force scan node re-eval */ + + /* + * Tuples to be substituted by scan nodes. They need to set up, before + * calling EvalPlanQual()/EvalPlanQualNext(), into the slot returned by + * EvalPlanQualSlot(scanrelid). The array is indexed by scanrelid - 1. + */ + List *tuple_table; /* tuple table for relsubs_slot */ + TupleTableSlot **relsubs_slot; + + /* + * Initialized by EvalPlanQualInit(), may be changed later with + * EvalPlanQualSetPlan(): + */ + Plan *plan; /* plan tree to be executed */ List *arowMarks; /* ExecAuxRowMarks (non-locking only) */ - int epqParam; /* ID of Param to force scan node re-eval */ + + + /* + * The original output tuple to be rechecked. Set by + * EvalPlanQualSetSlot(), before EvalPlanQualNext() or EvalPlanQual() may + * be called. + */ + TupleTableSlot *origslot; + + + /* Initialized or reset by EvalPlanQualBegin(): */ + + EState *recheckestate; /* EState for EPQ execution, see above */ + + /* + * Rowmarks that can be fetched on-demand using + * EvalPlanQualFetchRowMark(), indexed by scanrelid - 1. Only non-locking + * rowmarks. + */ + ExecAuxRowMark **relsubs_rowmark; + + /* + * True if a relation's EPQ tuple has been fetched for relation, indexed + * by scanrelid - 1. + */ + bool *relsubs_done; + + PlanState *recheckplanstate; /* EPQ specific exec nodes, for ->plan */ } EPQState; |