Re: ExecRTCheckPerms() and many prunable partitions
Amit Langote <amitlangote09@gmail.com>
From: Amit Langote <amitlangote09@gmail.com>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2021-08-20T13:46:17Z
Lists: pgsql-hackers
Attachments
- v3-0002-Remove-UpdateRangeTableOfViewParse.patch (application/octet-stream) patch v3-0002
- v3-0001-Rework-query-relation-permission-checking.patch (application/octet-stream) patch v3-0001
On Thu, Jul 29, 2021 at 5:40 PM Amit Langote <amitlangote09@gmail.com> wrote:
> On Fri, Jul 2, 2021 at 9:40 AM Amit Langote <amitlangote09@gmail.com> wrote:
> > On Fri, Jul 2, 2021 at 12:45 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
> > > Perhaps, if we separated the rtable from the required-permissions data
> > > structure, then we could avoid pulling up otherwise-useless RTEs when
> > > flattening a view (or even better, not make the extra RTEs in the
> > > first place??), and thus possibly avoid that exponential planning-time
> > > growth for nested views.
>
> Think I've managed to get the first part done -- getting the
> permission-checking info out of the range table -- but have not
> seriously attempted the second -- doing away with the OLD/NEW range
> table entries in the view/rule action queries, assuming that is what
> you meant in the quoted.
I took a stab at the 2nd part, implemented in the attached 0002.
The patch removes UpdateRangeTableOfViewParse() which would add the
dummy OLD/NEW entries to a view rule's action query's rtable, citing
these reasons:
- * These extra RT entries are not actually used in the query,
- * except for run-time locking and permission checking.
0001 makes them unnecessary for permission checking. Though, a
RELATION-kind RTE still be must be present in the rtable for run-time
locking, so I adjusted ApplyRetrieveRule() as follows:
@@ -1803,16 +1804,26 @@ ApplyRetrieveRule(Query *parsetree,
* original RTE to a subquery RTE.
*/
rte = rt_fetch(rt_index, parsetree->rtable);
+ subquery_rte = rte;
- rte->rtekind = RTE_SUBQUERY;
- rte->subquery = rule_action;
- rte->security_barrier = RelationIsSecurityView(relation);
+ /*
+ * Before modifying, store a copy of itself so as to serve as the entry
+ * to be used by the executor to lock the view relation and for the
+ * planner to be able to record the view relation OID in the PlannedStmt
+ * that it produces for the query.
+ */
+ rte = copyObject(rte);
+ parsetree->rtable = lappend(parsetree->rtable, rte);
+
+ subquery_rte->rtekind = RTE_SUBQUERY;
+ subquery_rte->subquery = rule_action;
+ subquery_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->inh = false; /* must not be set for a subquery */
+ subquery_rte->relid = InvalidOid;
+ subquery_rte->relkind = 0;
+ subquery_rte->rellockmode = 0;
+ subquery_rte->tablesample = NULL;
+ subquery_rte->inh = false; /* must not be set for a subquery */
return parsetree;
}
Outputs for a bunch of regression tests needed to be adjusted to
account for that pg_get_viewdef() no longer qualifies view column
names in the deparsed queries, that is, if they reference only a
single relation. Previously, those dummy OLD/NEW entries tricked
make_ruledef(), get_query_def() et al into setting
deparse_context.varprefix to true. contrib/postgre_fdw test output
likewise needed adjustment due to its deparse code being impacted by
those dummy entries no longer being present, I believe.
I haven't yet checked how this further improves the performance for
the case discussed at [1] that prompted this.
--
Amit Langote
EDB: http://www.enterprisedb.com
[1] https://www.postgresql.org/message-id/flat/797aff54-b49b-4914-9ff9-aa42564a4d7d%40www.fastmail.com
Commits
-
Add a test case for a316a3bc
- 054ff3b33a85 17.0 landed
- 0a14bca662a4 16.0 landed
-
Correctly set userid of subquery relations' child rels
- a316a3bc6d3f 16.0 landed
-
Fix buggy recursion in flatten_rtes_walker().
- c7468c73f7b6 16.0 landed
-
Remove some dead code in selfuncs.c
- 438e6b724090 16.0 landed
-
Update outdated comment in ApplyRetrieveRule
- 29861e228a47 16.0 landed
-
Rework query relation permission checking
- a61b1f74823c 16.0 landed
-
Generalize ri_RootToPartitionMap to use for non-partition children
- fb958b5da86d 16.0 landed
-
Stop accessing checkAsUser via RTE in some cases
- 599b33b9492d 16.0 landed
-
Add 'missing_ok' argument to build_attrmap_by_name
- ad86d159b6ab 16.0 landed