diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/optimizer/util/relnode.c | 13 | ||||
-rw-r--r-- | src/backend/utils/adt/selfuncs.c | 24 |
2 files changed, 32 insertions, 5 deletions
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 5a9ce44532d..22d01cef5b3 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -421,6 +421,19 @@ find_base_rel(PlannerInfo *root, int relid) } /* + * find_base_rel_noerr + * Find a base or otherrel relation entry, returning NULL if there's none + */ +RelOptInfo * +find_base_rel_noerr(PlannerInfo *root, int relid) +{ + /* use an unsigned comparison to prevent negative array element access */ + if ((uint32) relid < (uint32) root->simple_rel_array_size) + return root->simple_rel_array[relid]; + return NULL; +} + +/* * find_base_rel_ignore_join * Find a base or otherrel relation entry, which must already exist. * diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index dbcd98d9851..cea777e9d40 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -119,6 +119,7 @@ #include "optimizer/paths.h" #include "optimizer/plancat.h" #include "parser/parse_clause.h" +#include "parser/parse_relation.h" #include "parser/parsetree.h" #include "statistics/statistics.h" #include "storage/bufmgr.h" @@ -5434,17 +5435,30 @@ examine_simple_variable(PlannerInfo *root, Var *var, if (HeapTupleIsValid(vardata->statsTuple)) { - RelOptInfo *onerel = find_base_rel(root, var->varno); + RelOptInfo *onerel = find_base_rel_noerr(root, var->varno); 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. Use - * onerel->userid if it's set, in case we're accessing the table - * via a view. + * from security barrier views or RLS policies. + * + * Normally the Var will have an associated RelOptInfo from which + * we can find out which userid to do the check as; but it might + * not if it's a RETURNING Var for an INSERT target relation. In + * that case use the RTEPermissionInfo associated with the RTE. */ - userid = OidIsValid(onerel->userid) ? onerel->userid : GetUserId(); + if (onerel) + userid = onerel->userid; + else + { + RTEPermissionInfo *perminfo; + + perminfo = getRTEPermissionInfo(root->parse->rteperminfos, rte); + userid = perminfo->checkAsUser; + } + if (!OidIsValid(userid)) + userid = GetUserId(); vardata->acl_ok = rte->securityQuals == NIL && |