1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Revert "Get rid of the "new" and "old" entries in a view's rangetable."

This reverts commit 1b4d280ea1.
It's broken the buildfarm members that run cross-version-upgrade tests,
because they're not prepared to deal with cosmetic differences between
CREATE VIEW commands emitted by older servers and HEAD.  Even if we had
a solution to that, which we don't, it'd take some time to roll it out
to the affected animals.  This improvement isn't valuable enough to
justify addressing that problem on an emergency basis, so revert it
for now.
This commit is contained in:
Tom Lane
2023-01-11 22:56:34 -05:00
parent 5a26c7b310
commit f0e6d6d3c9
34 changed files with 890 additions and 774 deletions

View File

@ -633,6 +633,13 @@ checkRuleResultList(List *targetList, TupleDesc resultDesc, bool isSelect,
* setRuleCheckAsUser
* Recursively scan a query or expression tree and set the checkAsUser
* field to the given userid in all RTEPermissionInfos of the query.
*
* Note: for a view (ON SELECT rule), the checkAsUser field of the OLD
* RTE entry's RTEPermissionInfo will be overridden when the view rule is
* expanded, and the checkAsUser for the NEW RTE entry's RTEPermissionInfo is
* irrelevant because its requiredPerms bits will always be zero. However, for
* other types of rules it's important to set these fields to match the rule
* owner. So we just set them always.
*/
void
setRuleCheckAsUser(Node *node, Oid userid)

View File

@ -1715,7 +1715,10 @@ ApplyRetrieveRule(Query *parsetree,
List *activeRIRs)
{
Query *rule_action;
RangeTblEntry *rte;
RangeTblEntry *rte,
*subrte;
RTEPermissionInfo *perminfo,
*sub_perminfo;
RowMarkClause *rc;
if (list_length(rule->actions) != 1)
@ -1827,20 +1830,32 @@ ApplyRetrieveRule(Query *parsetree,
* original RTE to a subquery RTE.
*/
rte = rt_fetch(rt_index, parsetree->rtable);
perminfo = getRTEPermissionInfo(parsetree->rteperminfos, rte);
rte->rtekind = RTE_SUBQUERY;
rte->subquery = rule_action;
rte->security_barrier = RelationIsSecurityView(relation);
/* Clear fields that should not be set in a subquery RTE */
rte->relid = InvalidOid;
rte->relkind = 0;
rte->rellockmode = 0;
rte->tablesample = NULL;
rte->perminfoindex = 0; /* no permission checking for this RTE */
rte->inh = false; /* must not be set for a subquery */
/*
* Clear fields that should not be set in a subquery RTE. Note that we
* leave the relid, rellockmode, and perminfoindex fields set, so that the
* view relation can be appropriately locked before execution and its
* permissions checked.
* We move the view's permission check data down to its RTEPermissionInfo
* contained in the view query, which the OLD entry in its range table
* points to.
*/
rte->relkind = 0;
rte->tablesample = NULL;
rte->inh = false; /* must not be set for a subquery */
subrte = rt_fetch(PRS2_OLD_VARNO, rule_action->rtable);
Assert(subrte->relid == relation->rd_id);
sub_perminfo = getRTEPermissionInfo(rule_action->rteperminfos, subrte);
sub_perminfo->requiredPerms = perminfo->requiredPerms;
sub_perminfo->checkAsUser = perminfo->checkAsUser;
sub_perminfo->selectedCols = perminfo->selectedCols;
sub_perminfo->insertedCols = perminfo->insertedCols;
sub_perminfo->updatedCols = perminfo->updatedCols;
return parsetree;
}
@ -1852,10 +1867,9 @@ ApplyRetrieveRule(Query *parsetree,
* aggregate. We leave it to the planner to detect that.
*
* NB: this must agree with the parser's transformLockingClause() routine.
* However, we used to have to avoid marking a view's OLD and NEW rels for
* updating, which motivated scanning the jointree to determine which rels
* are used. Possibly that could now be simplified into just scanning the
* rangetable as the parser does.
* However, unlike the parser we have to be careful not to mark a view's
* OLD and NEW rels for updating. The best way to handle that seems to be
* to scan the jointree to determine which rels are used.
*/
static void
markQueryForLocking(Query *qry, Node *jtnode,