aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/util/relnode.c13
-rw-r--r--src/backend/utils/adt/selfuncs.c24
-rw-r--r--src/include/optimizer/pathnode.h1
-rw-r--r--src/test/regress/expected/with.out18
-rw-r--r--src/test/regress/sql/with.sql5
5 files changed, 56 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 &&
diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
index 03a0e46e706..c43d97b48a6 100644
--- a/src/include/optimizer/pathnode.h
+++ b/src/include/optimizer/pathnode.h
@@ -307,6 +307,7 @@ extern void expand_planner_arrays(PlannerInfo *root, int add_size);
extern RelOptInfo *build_simple_rel(PlannerInfo *root, int relid,
RelOptInfo *parent);
extern RelOptInfo *find_base_rel(PlannerInfo *root, int relid);
+extern RelOptInfo *find_base_rel_noerr(PlannerInfo *root, int relid);
extern RelOptInfo *find_base_rel_ignore_join(PlannerInfo *root, int relid);
extern RelOptInfo *find_join_rel(PlannerInfo *root, Relids relids);
extern RelOptInfo *build_join_rel(PlannerInfo *root,
diff --git a/src/test/regress/expected/with.out b/src/test/regress/expected/with.out
index 69c56ce2077..3cf969d9382 100644
--- a/src/test/regress/expected/with.out
+++ b/src/test/regress/expected/with.out
@@ -654,6 +654,24 @@ select count(*) from tenk1 a
-> CTE Scan on x
(8 rows)
+explain (costs off)
+with x as materialized (insert into tenk1 default values returning unique1)
+select count(*) from tenk1 a
+ where unique1 in (select * from x);
+ QUERY PLAN
+------------------------------------------------------------
+ Aggregate
+ CTE x
+ -> Insert on tenk1
+ -> Result
+ -> Nested Loop
+ -> HashAggregate
+ Group Key: x.unique1
+ -> CTE Scan on x
+ -> Index Only Scan using tenk1_unique1 on tenk1 a
+ Index Cond: (unique1 = x.unique1)
+(10 rows)
+
-- SEARCH clause
create temp table graph0( f int, t int, label text );
insert into graph0 values
diff --git a/src/test/regress/sql/with.sql b/src/test/regress/sql/with.sql
index 3ef98988663..ff68e21e2e6 100644
--- a/src/test/regress/sql/with.sql
+++ b/src/test/regress/sql/with.sql
@@ -354,6 +354,11 @@ with x as materialized (select unique1 from tenk1 b)
select count(*) from tenk1 a
where unique1 in (select * from x);
+explain (costs off)
+with x as materialized (insert into tenk1 default values returning unique1)
+select count(*) from tenk1 a
+ where unique1 in (select * from x);
+
-- SEARCH clause
create temp table graph0( f int, t int, label text );