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 600f7e03345..7df7f5cdf0d 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -742,6 +742,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)); @@ -1425,23 +1426,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 3d898326d7a..83630924f63 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -906,6 +906,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 3b3e5448fd5..5c943bc2543 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -808,6 +808,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); @@ -1609,6 +1610,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 b52eebe2aac..01b90383cf3 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -166,6 +166,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 */ @@ -1885,6 +1886,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 @@ -1910,6 +1912,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 867238ecc8b..d004f6cf12f 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 34b38eb3298..63447aa536e 100644 --- a/src/backend/optimizer/prep/preptlist.c +++ b/src/backend/optimizer/prep/preptlist.c @@ -102,7 +102,7 @@ preprocess_targetlist(PlannerInfo *root, List *tlist) -1, InvalidOid, 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), @@ -118,7 +118,7 @@ preprocess_targetlist(PlannerInfo *root, List *tlist) -1, InvalidOid, 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), @@ -132,7 +132,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 f62af6c37da..606e5fe60a5 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -1294,6 +1294,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 546b581b6d8..44da70ff608 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 6ba2f6005a2..b4fb4f211b5 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -749,7 +749,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. @@ -759,6 +763,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 b3ca5b5e329..49ce441e624 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; |