diff options
Diffstat (limited to 'src/backend/parser/analyze.c')
-rw-r--r-- | src/backend/parser/analyze.c | 68 |
1 files changed, 46 insertions, 22 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 6688c2a865b..2e593aed2bc 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -518,6 +518,7 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt) /* done building the range table and jointree */ qry->rtable = pstate->p_rtable; + qry->rteperminfos = pstate->p_rteperminfos; qry->jointree = makeFromExpr(pstate->p_joinlist, qual); qry->hasSubLinks = pstate->p_hasSubLinks; @@ -546,11 +547,12 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) List *exprList = NIL; bool isGeneralSelect; List *sub_rtable; + List *sub_rteperminfos; List *sub_namespace; List *icolumns; List *attrnos; ParseNamespaceItem *nsitem; - RangeTblEntry *rte; + RTEPermissionInfo *perminfo; ListCell *icols; ListCell *attnos; ListCell *lc; @@ -594,17 +596,19 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) /* * If a non-nil rangetable/namespace was passed in, and we are doing - * INSERT/SELECT, arrange to pass the rangetable/namespace down to the - * SELECT. This can only happen if we are inside a CREATE RULE, and in - * that case we want the rule's OLD and NEW rtable entries to appear as - * part of the SELECT's rtable, not as outer references for it. (Kluge!) - * The SELECT's joinlist is not affected however. We must do this before - * adding the target table to the INSERT's rtable. + * INSERT/SELECT, arrange to pass the rangetable/rteperminfos/namespace + * down to the SELECT. This can only happen if we are inside a CREATE + * RULE, and in that case we want the rule's OLD and NEW rtable entries to + * appear as part of the SELECT's rtable, not as outer references for it. + * (Kluge!) The SELECT's joinlist is not affected however. We must do + * this before adding the target table to the INSERT's rtable. */ if (isGeneralSelect) { sub_rtable = pstate->p_rtable; pstate->p_rtable = NIL; + sub_rteperminfos = pstate->p_rteperminfos; + pstate->p_rteperminfos = NIL; sub_namespace = pstate->p_namespace; pstate->p_namespace = NIL; } @@ -669,6 +673,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) * the target column's type, which we handle below. */ sub_pstate->p_rtable = sub_rtable; + sub_pstate->p_rteperminfos = sub_rteperminfos; sub_pstate->p_joinexprs = NIL; /* sub_rtable has no joins */ sub_pstate->p_namespace = sub_namespace; sub_pstate->p_resolve_unknowns = false; @@ -894,7 +899,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) * Generate query's target list using the computed list of expressions. * Also, mark all the target columns as needing insert permissions. */ - rte = pstate->p_target_nsitem->p_rte; + perminfo = pstate->p_target_nsitem->p_perminfo; qry->targetList = NIL; Assert(list_length(exprList) <= list_length(icolumns)); forthree(lc, exprList, icols, icolumns, attnos, attrnos) @@ -910,8 +915,8 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) false); qry->targetList = lappend(qry->targetList, tle); - rte->insertedCols = bms_add_member(rte->insertedCols, - attr_num - FirstLowInvalidHeapAttributeNumber); + perminfo->insertedCols = bms_add_member(perminfo->insertedCols, + attr_num - FirstLowInvalidHeapAttributeNumber); } /* @@ -938,6 +943,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) /* done building the range table and jointree */ qry->rtable = pstate->p_rtable; + qry->rteperminfos = pstate->p_rteperminfos; qry->jointree = makeFromExpr(pstate->p_joinlist, NULL); qry->hasTargetSRFs = pstate->p_hasTargetSRFs; @@ -1096,8 +1102,6 @@ transformOnConflictClause(ParseState *pstate, * (We'll check the actual target relation, instead.) */ exclRte->relkind = RELKIND_COMPOSITE_TYPE; - exclRte->requiredPerms = 0; - /* other permissions fields in exclRte are already empty */ /* Create EXCLUDED rel's targetlist for use by EXPLAIN */ exclRelTlist = BuildOnConflictExcludedTargetlist(targetrel, @@ -1391,6 +1395,7 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt) resolveTargetListUnknowns(pstate, qry->targetList); qry->rtable = pstate->p_rtable; + qry->rteperminfos = pstate->p_rteperminfos; qry->jointree = makeFromExpr(pstate->p_joinlist, qual); qry->hasSubLinks = pstate->p_hasSubLinks; @@ -1619,6 +1624,7 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt) linitial(stmt->lockingClause))->strength)))); qry->rtable = pstate->p_rtable; + qry->rteperminfos = pstate->p_rteperminfos; qry->jointree = makeFromExpr(pstate->p_joinlist, NULL); qry->hasSubLinks = pstate->p_hasSubLinks; @@ -1865,6 +1871,7 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt) qry->limitOption = stmt->limitOption; qry->rtable = pstate->p_rtable; + qry->rteperminfos = pstate->p_rteperminfos; qry->jointree = makeFromExpr(pstate->p_joinlist, NULL); qry->hasSubLinks = pstate->p_hasSubLinks; @@ -2339,6 +2346,7 @@ transformReturnStmt(ParseState *pstate, ReturnStmt *stmt) if (pstate->p_resolve_unknowns) resolveTargetListUnknowns(pstate, qry->targetList); qry->rtable = pstate->p_rtable; + qry->rteperminfos = pstate->p_rteperminfos; qry->jointree = makeFromExpr(pstate->p_joinlist, NULL); qry->hasSubLinks = pstate->p_hasSubLinks; qry->hasWindowFuncs = pstate->p_hasWindowFuncs; @@ -2405,6 +2413,7 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt) qry->targetList = transformUpdateTargetList(pstate, stmt->targetList); qry->rtable = pstate->p_rtable; + qry->rteperminfos = pstate->p_rteperminfos; qry->jointree = makeFromExpr(pstate->p_joinlist, qual); qry->hasTargetSRFs = pstate->p_hasTargetSRFs; @@ -2423,7 +2432,7 @@ List * transformUpdateTargetList(ParseState *pstate, List *origTlist) { List *tlist = NIL; - RangeTblEntry *target_rte; + RTEPermissionInfo *target_perminfo; ListCell *orig_tl; ListCell *tl; @@ -2435,7 +2444,7 @@ transformUpdateTargetList(ParseState *pstate, List *origTlist) pstate->p_next_resno = RelationGetNumberOfAttributes(pstate->p_target_relation) + 1; /* Prepare non-junk columns for assignment to target table */ - target_rte = pstate->p_target_nsitem->p_rte; + target_perminfo = pstate->p_target_nsitem->p_perminfo; orig_tl = list_head(origTlist); foreach(tl, tlist) @@ -2476,8 +2485,8 @@ transformUpdateTargetList(ParseState *pstate, List *origTlist) origTarget->location); /* Mark the target column as requiring update permissions */ - target_rte->updatedCols = bms_add_member(target_rte->updatedCols, - attrno - FirstLowInvalidHeapAttributeNumber); + target_perminfo->updatedCols = bms_add_member(target_perminfo->updatedCols, + attrno - FirstLowInvalidHeapAttributeNumber); orig_tl = lnext(origTlist, orig_tl); } @@ -2764,6 +2773,7 @@ transformPLAssignStmt(ParseState *pstate, PLAssignStmt *stmt) &qry->targetList); qry->rtable = pstate->p_rtable; + qry->rteperminfos = pstate->p_rteperminfos; qry->jointree = makeFromExpr(pstate->p_joinlist, qual); qry->hasSubLinks = pstate->p_hasSubLinks; @@ -3242,9 +3252,16 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc, switch (rte->rtekind) { case RTE_RELATION: - applyLockingClause(qry, i, lc->strength, lc->waitPolicy, - pushedDown); - rte->requiredPerms |= ACL_SELECT_FOR_UPDATE; + { + RTEPermissionInfo *perminfo; + + applyLockingClause(qry, i, + lc->strength, + lc->waitPolicy, + pushedDown); + perminfo = getRTEPermissionInfo(qry->rteperminfos, rte); + perminfo->requiredPerms |= ACL_SELECT_FOR_UPDATE; + } break; case RTE_SUBQUERY: applyLockingClause(qry, i, lc->strength, lc->waitPolicy, @@ -3324,9 +3341,16 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc, switch (rte->rtekind) { case RTE_RELATION: - applyLockingClause(qry, i, lc->strength, - lc->waitPolicy, pushedDown); - rte->requiredPerms |= ACL_SELECT_FOR_UPDATE; + { + RTEPermissionInfo *perminfo; + + applyLockingClause(qry, i, + lc->strength, + lc->waitPolicy, + pushedDown); + perminfo = getRTEPermissionInfo(qry->rteperminfos, rte); + perminfo->requiredPerms |= ACL_SELECT_FOR_UPDATE; + } break; case RTE_SUBQUERY: applyLockingClause(qry, i, lc->strength, |