aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/optimizer/prep/prepsecurity.c11
-rw-r--r--src/test/regress/expected/rowsecurity.out20
-rw-r--r--src/test/regress/sql/rowsecurity.sql4
3 files changed, 34 insertions, 1 deletions
diff --git a/src/backend/optimizer/prep/prepsecurity.c b/src/backend/optimizer/prep/prepsecurity.c
index c4b61df3003..ee1e1e40ef8 100644
--- a/src/backend/optimizer/prep/prepsecurity.c
+++ b/src/backend/optimizer/prep/prepsecurity.c
@@ -56,6 +56,12 @@ static bool security_barrier_replace_vars_walker(Node *node,
* the others, providing protection against malicious user-defined security
* barriers. The first security barrier qual in the list will be used in the
* innermost subquery.
+ *
+ * In practice, the only RTEs that will have security barrier quals are those
+ * that refer to tables with row-level security, or which are the target
+ * relation of an update to an auto-updatable security barrier view. RTEs
+ * that read from a security barrier view will have already been expanded by
+ * the rewriter.
*/
void
expand_security_quals(PlannerInfo *root, List *tlist)
@@ -263,7 +269,8 @@ expand_security_qual(PlannerInfo *root, List *tlist, int rt_index,
* Replace any variables in the outer query that refer to the
* original relation RTE with references to columns that we will
* expose in the new subquery, building the subquery's targetlist
- * as we go.
+ * as we go. Also replace any references in the translated_vars
+ * lists of any appendrels.
*/
context.rt_index = rt_index;
context.sublevels_up = 0;
@@ -274,6 +281,8 @@ expand_security_qual(PlannerInfo *root, List *tlist, int rt_index,
security_barrier_replace_vars((Node *) parse, &context);
security_barrier_replace_vars((Node *) tlist, &context);
+ security_barrier_replace_vars((Node *) root->append_rel_list,
+ &context);
heap_close(context.rel, NoLock);
diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out
index 6becf5967be..c8444999e13 100644
--- a/src/test/regress/expected/rowsecurity.out
+++ b/src/test/regress/expected/rowsecurity.out
@@ -640,6 +640,26 @@ EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) FOR SHARE;
Filter: ((a % 2) = 0)
(12 rows)
+-- union all query
+SELECT a, b, oid FROM t2 UNION ALL SELECT a, b, oid FROM t3;
+ a | b | oid
+---+-----+-----
+ 1 | abc | 201
+ 3 | cde | 203
+ 1 | xxx | 301
+ 2 | yyy | 302
+ 3 | zzz | 303
+(5 rows)
+
+EXPLAIN (COSTS OFF) SELECT a, b, oid FROM t2 UNION ALL SELECT a, b, oid FROM t3;
+ QUERY PLAN
+-------------------------------
+ Append
+ -> Seq Scan on t2
+ Filter: ((a % 2) = 1)
+ -> Seq Scan on t3
+(4 rows)
+
-- superuser is allowed to bypass RLS checks
RESET SESSION AUTHORIZATION;
SET row_security TO OFF;
diff --git a/src/test/regress/sql/rowsecurity.sql b/src/test/regress/sql/rowsecurity.sql
index 662f5203107..b230a0f6d98 100644
--- a/src/test/regress/sql/rowsecurity.sql
+++ b/src/test/regress/sql/rowsecurity.sql
@@ -255,6 +255,10 @@ EXPLAIN (COSTS OFF) SELECT * FROM t1 FOR SHARE;
SELECT * FROM t1 WHERE f_leak(b) FOR SHARE;
EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) FOR SHARE;
+-- union all query
+SELECT a, b, oid FROM t2 UNION ALL SELECT a, b, oid FROM t3;
+EXPLAIN (COSTS OFF) SELECT a, b, oid FROM t2 UNION ALL SELECT a, b, oid FROM t3;
+
-- superuser is allowed to bypass RLS checks
RESET SESSION AUTHORIZATION;
SET row_security TO OFF;