diff options
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/executor/executor.h | 10 | ||||
| -rw-r--r-- | src/include/nodes/execnodes.h | 34 | ||||
| -rw-r--r-- | src/include/nodes/plannodes.h | 21 | 
3 files changed, 47 insertions, 18 deletions
| diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index b2424a0d087..13b6aa57bea 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -138,6 +138,8 @@ extern JunkFilter *ExecInitJunkFilterConversion(List *targetList,  							 TupleTableSlot *slot);  extern AttrNumber ExecFindJunkAttribute(JunkFilter *junkfilter,  					  const char *attrName); +extern AttrNumber ExecFindJunkAttributeInTlist(List *targetlist, +					  const char *attrName);  extern Datum ExecGetJunkAttribute(TupleTableSlot *slot, AttrNumber attno,  					 bool *isNull);  extern TupleTableSlot *ExecFilterJunk(JunkFilter *junkfilter, @@ -166,15 +168,17 @@ extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid);  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 HeapTuple EvalPlanQualFetch(EState *estate, Relation relation,  				  int lockmode, ItemPointer tid, TransactionId priorXmax);  extern void EvalPlanQualInit(EPQState *epqstate, EState *estate, -				 Plan *subplan, int epqParam); -extern void EvalPlanQualSetPlan(EPQState *epqstate, Plan *subplan); -extern void EvalPlanQualAddRowMark(EPQState *epqstate, ExecRowMark *erm); +				 Plan *subplan, List *auxrowmarks, int epqParam); +extern void EvalPlanQualSetPlan(EPQState *epqstate, +								Plan *subplan, List *auxrowmarks);  extern void EvalPlanQualSetTuple(EPQState *epqstate, Index rti,  					 HeapTuple tuple);  extern HeapTuple EvalPlanQualGetTuple(EPQState *epqstate, Index rti); diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 928cf4c5a55..fda44255b08 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -407,12 +407,10 @@ typedef struct EState   * When doing UPDATE, DELETE, or SELECT FOR UPDATE/SHARE, we should have an   * ExecRowMark for each non-target relation in the query (except inheritance   * parent RTEs, which can be ignored at runtime).  See PlanRowMark for details - * about most of the fields. + * about most of the fields.  In addition to fields directly derived from + * PlanRowMark, we store curCtid, which is used by the WHERE CURRENT OF code.   * - * es_rowMarks is a list of these structs.	Each LockRows node has its own - * list, which is the subset of locks that it is supposed to enforce; note - * that the per-node lists point to the same structs that are in the global - * list. + * EState->es_rowMarks is a list of these structs.   */  typedef struct ExecRowMark  { @@ -421,11 +419,28 @@ typedef struct ExecRowMark  	Index		prti;			/* parent range table index, if child */  	RowMarkType markType;		/* see enum in nodes/plannodes.h */  	bool		noWait;			/* NOWAIT option */ +	ItemPointerData curCtid;	/* ctid of currently locked tuple, if any */ +} ExecRowMark; + +/* + * ExecAuxRowMark - + *	   additional runtime representation of FOR UPDATE/SHARE clauses + * + * Each LockRows and ModifyTable node keeps a list of the rowmarks it needs to + * deal with.  In addition to a pointer to the related entry in es_rowMarks, + * this struct carries the column number(s) of the resjunk columns associated + * with the rowmark (see comments for PlanRowMark for more detail).  In the + * case of ModifyTable, there has to be a separate ExecAuxRowMark list for + * each child plan, because the resjunk columns could be at different physical + * column positions in different subplans. + */ +typedef struct ExecAuxRowMark +{ +	ExecRowMark *rowmark;		/* related entry in es_rowMarks */  	AttrNumber	ctidAttNo;		/* resno of ctid junk attribute, if any */  	AttrNumber	toidAttNo;		/* resno of tableoid junk attribute, if any */  	AttrNumber	wholeAttNo;		/* resno of whole-row junk attribute, if any */ -	ItemPointerData curCtid;	/* ctid of currently locked tuple, if any */ -} ExecRowMark; +} ExecAuxRowMark;  /* ---------------------------------------------------------------- @@ -1002,7 +1017,7 @@ typedef struct EPQState  	PlanState  *planstate;		/* plan state tree ready to be executed */  	TupleTableSlot *origslot;	/* original output tuple to be rechecked */  	Plan	   *plan;			/* plan tree to be executed */ -	List	   *rowMarks;		/* ExecRowMarks (non-locking only) */ +	List	   *arowMarks;		/* ExecAuxRowMarks (non-locking only) */  	int			epqParam;		/* ID of Param to force scan node re-eval */  } EPQState; @@ -1030,6 +1045,7 @@ typedef struct ModifyTableState  	PlanState **mt_plans;		/* subplans (one per target rel) */  	int			mt_nplans;		/* number of plans in the array */  	int			mt_whichplan;	/* which one is being executed (0..n-1) */ +	List	  **mt_arowmarks;	/* per-subplan ExecAuxRowMark lists */  	EPQState	mt_epqstate;	/* for evaluating EvalPlanQual rechecks */  	bool		fireBSTriggers; /* do we need to fire stmt triggers? */  } ModifyTableState; @@ -1706,7 +1722,7 @@ typedef struct SetOpState  typedef struct LockRowsState  {  	PlanState	ps;				/* its first field is NodeTag */ -	List	   *lr_rowMarks;	/* List of ExecRowMarks */ +	List	   *lr_arowMarks;	/* List of ExecAuxRowMarks */  	EPQState	lr_epqstate;	/* for evaluating EvalPlanQual rechecks */  } LockRowsState; diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index 79876100d5a..e14257932e6 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -158,6 +158,9 @@ typedef struct Result   *	 ModifyTable node -   *		Apply rows produced by subplan(s) to result table(s),   *		by inserting, updating, or deleting. + * + * Note that rowMarks and epqParam are presumed to be valid for all the + * subplan(s); they can't contain any info that varies across subplans.   * ----------------   */  typedef struct ModifyTable @@ -690,9 +693,18 @@ typedef enum RowMarkType   * prti == parent's RT index, and can therefore be recognized as children by   * the fact that prti != rti.   * - * The AttrNumbers are filled in during preprocess_targetlist.	We use - * different subsets of them for plain relations, inheritance children, - * and non-table relations. + * The planner also adds resjunk output columns to the plan that carry + * information sufficient to identify the locked or fetched rows.  For + * tables (markType != ROW_MARK_COPY), these columns are named + *		tableoid%u			OID of table + *		ctid%u				TID of row + * The tableoid column is only present for an inheritance hierarchy. + * When markType == ROW_MARK_COPY, there is instead a single column named + *		wholerow%u			whole-row value of relation + * In all three cases, %u represents the parent rangetable index (prti). + * Note this means that all tables in an inheritance hierarchy share the + * same resjunk column names.  However, in an inherited UPDATE/DELETE the + * columns could have different physical column numbers in each subplan.   */  typedef struct PlanRowMark  { @@ -702,9 +714,6 @@ typedef struct PlanRowMark  	RowMarkType markType;		/* see enum above */  	bool		noWait;			/* NOWAIT option */  	bool		isParent;		/* true if this is a "dummy" parent entry */ -	AttrNumber	ctidAttNo;		/* resno of ctid junk attribute, if any */ -	AttrNumber	toidAttNo;		/* resno of tableoid junk attribute, if any */ -	AttrNumber	wholeAttNo;		/* resno of whole-row junk attribute, if any */  } PlanRowMark; | 
