aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/selfuncs.c
diff options
context:
space:
mode:
authorDean Rasheed <dean.a.rasheed@gmail.com>2019-05-06 12:01:44 +0100
committerDean Rasheed <dean.a.rasheed@gmail.com>2019-05-06 12:01:44 +0100
commit01256815a6304c114c47c2ca70fb752a3ec81ac3 (patch)
tree0af956e4596d331026f01a647f524125c3cdfc7c /src/backend/utils/adt/selfuncs.c
parent93c36145ad10f3b4795d8e411720ae55180ad274 (diff)
downloadpostgresql-01256815a6304c114c47c2ca70fb752a3ec81ac3.tar.gz
postgresql-01256815a6304c114c47c2ca70fb752a3ec81ac3.zip
Use checkAsUser for selectivity estimator checks, if it's set.
In examine_variable() and examine_simple_variable(), when checking the user's table and column privileges to determine whether to grant access to the pg_statistic data, use checkAsUser for the privilege checks, if it's set. This will be the case if we're accessing the table via a view, to indicate that we should perform privilege checks as the view owner rather than the current user. This change makes this planner check consistent with the check in the executor, so the planner will be able to make use of statistics if the table is accessible via the view. This fixes a performance regression introduced by commit e2d4ef8de8, which affects queries against non-security barrier views in the case where the user doesn't have privileges on the underlying table, but the view owner does. Note that it continues to provide the same safeguards controlling access to pg_statistic for direct table access (in which case checkAsUser won't be set) and for security barrier views, because of the nearby checks on rte->security_barrier and rte->securityQuals. Back-patch to all supported branches because e2d4ef8de8 was. Dean Rasheed, reviewed by Jonathan Katz and Stephen Frost.
Diffstat (limited to 'src/backend/utils/adt/selfuncs.c')
-rw-r--r--src/backend/utils/adt/selfuncs.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 1b16ebc27b2..da299a884ff 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -4560,11 +4560,18 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid,
{
/* Get index's table for permission check */
RangeTblEntry *rte;
+ Oid userid;
rte = planner_rt_fetch(index->rel->relid, root);
Assert(rte->rtekind == RTE_RELATION);
/*
+ * Use checkAsUser if it's set, in case we're
+ * accessing the table via a view.
+ */
+ userid = rte->checkAsUser ? rte->checkAsUser : GetUserId();
+
+ /*
* For simplicity, we insist on the whole
* table being selectable, rather than trying
* to identify which column(s) the index
@@ -4575,7 +4582,7 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid,
*/
vardata->acl_ok =
rte->securityQuals == NIL &&
- (pg_class_aclcheck(rte->relid, GetUserId(),
+ (pg_class_aclcheck(rte->relid, userid,
ACL_SELECT) == ACLCHECK_OK);
}
else
@@ -4638,16 +4645,21 @@ examine_simple_variable(PlannerInfo *root, Var *var,
if (HeapTupleIsValid(vardata->statsTuple))
{
+ Oid userid;
+
/*
* Check if user has permission to read this column. We require
* all rows to be accessible, so there must be no securityQuals
- * from security barrier views or RLS policies.
+ * from security barrier views or RLS policies. Use checkAsUser
+ * if it's set, in case we're accessing the table via a view.
*/
+ userid = rte->checkAsUser ? rte->checkAsUser : GetUserId();
+
vardata->acl_ok =
rte->securityQuals == NIL &&
- ((pg_class_aclcheck(rte->relid, GetUserId(),
+ ((pg_class_aclcheck(rte->relid, userid,
ACL_SELECT) == ACLCHECK_OK) ||
- (pg_attribute_aclcheck(rte->relid, var->varattno, GetUserId(),
+ (pg_attribute_aclcheck(rte->relid, var->varattno, userid,
ACL_SELECT) == ACLCHECK_OK));
}
else