diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/backend/executor/execMain.c | 13 | ||||
| -rw-r--r-- | src/backend/nodes/copyfuncs.c | 1 | ||||
| -rw-r--r-- | src/backend/nodes/outfuncs.c | 2 | ||||
| -rw-r--r-- | src/backend/optimizer/plan/planner.c | 3 | ||||
| -rw-r--r-- | src/backend/optimizer/plan/setrefs.c | 2 | ||||
| -rw-r--r-- | src/backend/optimizer/prep/preptlist.c | 6 | ||||
| -rw-r--r-- | src/backend/optimizer/prep/prepunion.c | 1 | ||||
| -rw-r--r-- | src/include/nodes/execnodes.h | 1 | ||||
| -rw-r--r-- | src/include/nodes/plannodes.h | 7 | ||||
| -rw-r--r-- | src/include/nodes/relation.h | 2 | 
10 files changed, 30 insertions, 8 deletions
| diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 6d4a77328a4..c477314efa3 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -726,6 +726,7 @@ InitPlan(QueryDesc *queryDesc, int eflags)  		erm->relation = relation;  		erm->rti = rc->rti;  		erm->prti = rc->prti; +		erm->rowmarkId = rc->rowmarkId;  		erm->markType = rc->markType;  		erm->noWait = rc->noWait;  		ItemPointerSetInvalid(&(erm->curCtid)); @@ -1373,23 +1374,29 @@ ExecBuildAuxRowMark(ExecRowMark *erm, List *targetlist)  		/* if child rel, need tableoid */  		if (erm->rti != erm->prti)  		{ -			snprintf(resname, sizeof(resname), "tableoid%u", erm->prti); +			snprintf(resname, sizeof(resname), "tableoid%u", erm->rowmarkId);  			aerm->toidAttNo = ExecFindJunkAttributeInTlist(targetlist,  														   resname); +			if (!AttributeNumberIsValid(aerm->toidAttNo)) +				elog(ERROR, "could not find junk %s column", resname);  		}  		/* always need ctid for real relations */ -		snprintf(resname, sizeof(resname), "ctid%u", erm->prti); +		snprintf(resname, sizeof(resname), "ctid%u", erm->rowmarkId);  		aerm->ctidAttNo = ExecFindJunkAttributeInTlist(targetlist,  													   resname); +		if (!AttributeNumberIsValid(aerm->ctidAttNo)) +			elog(ERROR, "could not find junk %s column", resname);  	}  	else  	{  		Assert(erm->markType == ROW_MARK_COPY); -		snprintf(resname, sizeof(resname), "wholerow%u", erm->prti); +		snprintf(resname, sizeof(resname), "wholerow%u", erm->rowmarkId);  		aerm->wholeAttNo = ExecFindJunkAttributeInTlist(targetlist,  														resname); +		if (!AttributeNumberIsValid(aerm->wholeAttNo)) +			elog(ERROR, "could not find junk %s column", resname);  	}  	return aerm; diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 0b2aa3dfff8..778c53063ec 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -856,6 +856,7 @@ _copyPlanRowMark(PlanRowMark *from)  	COPY_SCALAR_FIELD(rti);  	COPY_SCALAR_FIELD(prti); +	COPY_SCALAR_FIELD(rowmarkId);  	COPY_SCALAR_FIELD(markType);  	COPY_SCALAR_FIELD(noWait);  	COPY_SCALAR_FIELD(isParent); diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 032150e1bb7..15a9aa2f939 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -756,6 +756,7 @@ _outPlanRowMark(StringInfo str, PlanRowMark *node)  	WRITE_UINT_FIELD(rti);  	WRITE_UINT_FIELD(prti); +	WRITE_UINT_FIELD(rowmarkId);  	WRITE_ENUM_FIELD(markType, RowMarkType);  	WRITE_BOOL_FIELD(noWait);  	WRITE_BOOL_FIELD(isParent); @@ -1524,6 +1525,7 @@ _outPlannerGlobal(StringInfo str, PlannerGlobal *node)  	WRITE_NODE_FIELD(relationOids);  	WRITE_NODE_FIELD(invalItems);  	WRITE_UINT_FIELD(lastPHId); +	WRITE_UINT_FIELD(lastRowMarkId);  	WRITE_BOOL_FIELD(transientPlan);  } diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 45ba902fbab..55206573c72 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -165,6 +165,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)  	glob->relationOids = NIL;  	glob->invalItems = NIL;  	glob->lastPHId = 0; +	glob->lastRowMarkId = 0;  	glob->transientPlan = false;  	/* Determine what fraction of the plan is likely to be scanned */ @@ -1852,6 +1853,7 @@ preprocess_rowmarks(PlannerInfo *root)  		newrc = makeNode(PlanRowMark);  		newrc->rti = newrc->prti = rc->rti; +		newrc->rowmarkId = ++(root->glob->lastRowMarkId);  		if (rc->forUpdate)  			newrc->markType = ROW_MARK_EXCLUSIVE;  		else @@ -1877,6 +1879,7 @@ preprocess_rowmarks(PlannerInfo *root)  		newrc = makeNode(PlanRowMark);  		newrc->rti = newrc->prti = i; +		newrc->rowmarkId = ++(root->glob->lastRowMarkId);  		/* real tables support REFERENCE, anything else needs COPY */  		if (rte->rtekind == RTE_RELATION)  			newrc->markType = ROW_MARK_REFERENCE; diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index 70be2e66f2d..2618ef14a83 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -252,7 +252,7 @@ set_plan_references(PlannerGlobal *glob, Plan *plan,  		newrc = (PlanRowMark *) palloc(sizeof(PlanRowMark));  		memcpy(newrc, rc, sizeof(PlanRowMark)); -		/* adjust indexes */ +		/* adjust indexes ... but *not* the rowmarkId */  		newrc->rti += rtoffset;  		newrc->prti += rtoffset; diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c index 7a09d1f8309..425d80c6244 100644 --- a/src/backend/optimizer/prep/preptlist.c +++ b/src/backend/optimizer/prep/preptlist.c @@ -132,7 +132,7 @@ preprocess_targetlist(PlannerInfo *root, List *tlist)  						  TIDOID,  						  -1,  						  0); -			snprintf(resname, sizeof(resname), "ctid%u", rc->rti); +			snprintf(resname, sizeof(resname), "ctid%u", rc->rowmarkId);  			tle = makeTargetEntry((Expr *) var,  								  list_length(tlist) + 1,  								  pstrdup(resname), @@ -147,7 +147,7 @@ preprocess_targetlist(PlannerInfo *root, List *tlist)  							  OIDOID,  							  -1,  							  0); -				snprintf(resname, sizeof(resname), "tableoid%u", rc->rti); +				snprintf(resname, sizeof(resname), "tableoid%u", rc->rowmarkId);  				tle = makeTargetEntry((Expr *) var,  									  list_length(tlist) + 1,  									  pstrdup(resname), @@ -161,7 +161,7 @@ preprocess_targetlist(PlannerInfo *root, List *tlist)  			var = makeWholeRowVar(rt_fetch(rc->rti, range_table),  								  rc->rti,  								  0); -			snprintf(resname, sizeof(resname), "wholerow%u", rc->rti); +			snprintf(resname, sizeof(resname), "wholerow%u", rc->rowmarkId);  			tle = makeTargetEntry((Expr *) var,  								  list_length(tlist) + 1,  								  pstrdup(resname), diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index 35f9f980e90..cabc93d5df9 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -1288,6 +1288,7 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)  			newrc->rti = childRTindex;  			newrc->prti = rti; +			newrc->rowmarkId = oldrc->rowmarkId;  			newrc->markType = oldrc->markType;  			newrc->noWait = oldrc->noWait;  			newrc->isParent = false; diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index fda44255b08..ac0de093f16 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -417,6 +417,7 @@ typedef struct ExecRowMark  	Relation	relation;		/* opened and suitably locked relation */  	Index		rti;			/* its range table index */  	Index		prti;			/* parent range table index, if child */ +	Index		rowmarkId;		/* unique identifier for resjunk columns */  	RowMarkType markType;		/* see enum in nodes/plannodes.h */  	bool		noWait;			/* NOWAIT option */  	ItemPointerData curCtid;	/* ctid of currently locked tuple, if any */ diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index e14257932e6..729e35557d8 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -701,7 +701,11 @@ typedef enum RowMarkType   * 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). + * In all three cases, %u represents the rowmark ID number (rowmarkId). + * This number is unique within a plan tree, except that child relation + * entries copy their parent's rowmarkId.  (Assigning unique numbers + * means we needn't renumber rowmarkIds when flattening subqueries, which + * would require finding and renaming the resjunk columns as well.)   * 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. @@ -711,6 +715,7 @@ typedef struct PlanRowMark  	NodeTag		type;  	Index		rti;			/* range table index of markable relation */  	Index		prti;			/* range table index of parent relation */ +	Index		rowmarkId;		/* unique identifier for resjunk columns */  	RowMarkType markType;		/* see enum above */  	bool		noWait;			/* NOWAIT option */  	bool		isParent;		/* true if this is a "dummy" parent entry */ diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index a3678a5b58d..f109a1de520 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -82,6 +82,8 @@ typedef struct PlannerGlobal  	Index		lastPHId;		/* highest PlaceHolderVar ID assigned */ +	Index		lastRowMarkId;	/* highest PlanRowMark ID assigned */ +  	bool		transientPlan;	/* redo plan when TransactionXmin changes? */  } PlannerGlobal; | 
