aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/modules/test_rls_hooks/expected/test_rls_hooks.out24
-rw-r--r--src/test/regress/expected/equivclass.out42
-rw-r--r--src/test/regress/expected/rowsecurity.out877
-rw-r--r--src/test/regress/expected/updatable_views.out304
-rw-r--r--src/test/regress/sql/equivclass.sql32
-rw-r--r--src/test/regress/sql/updatable_views.sql4
6 files changed, 543 insertions, 740 deletions
diff --git a/src/test/modules/test_rls_hooks/expected/test_rls_hooks.out b/src/test/modules/test_rls_hooks/expected/test_rls_hooks.out
index 19284c18d48..b8c6d385814 100644
--- a/src/test/modules/test_rls_hooks/expected/test_rls_hooks.out
+++ b/src/test/modules/test_rls_hooks/expected/test_rls_hooks.out
@@ -145,13 +145,11 @@ ERROR: new row violates row-level security policy for table "rls_test_permissiv
SET ROLE regress_s1;
-- With both internal and hook policies, restrictive
EXPLAIN (costs off) SELECT * FROM rls_test_restrictive;
- QUERY PLAN
----------------------------------------------------------------
- Subquery Scan on rls_test_restrictive
- Filter: ((rls_test_restrictive.data % 2) = 0)
- -> Seq Scan on rls_test_restrictive rls_test_restrictive_1
- Filter: ("current_user"() = supervisor)
-(4 rows)
+ QUERY PLAN
+------------------------------------------------------------------
+ Seq Scan on rls_test_restrictive
+ Filter: (("current_user"() = supervisor) AND ((data % 2) = 0))
+(2 rows)
SELECT * FROM rls_test_restrictive;
username | supervisor | data
@@ -173,13 +171,11 @@ ERROR: new row violates row-level security policy for table "rls_test_restricti
-- With both internal and hook policies, both permissive
-- and restrictive hook policies
EXPLAIN (costs off) SELECT * FROM rls_test_both;
- QUERY PLAN
--------------------------------------------------------------------------------------------
- Subquery Scan on rls_test_both
- Filter: (((rls_test_both.data % 2) = 0) OR ("current_user"() = rls_test_both.username))
- -> Seq Scan on rls_test_both rls_test_both_1
- Filter: ("current_user"() = supervisor)
-(4 rows)
+ QUERY PLAN
+-----------------------------------------------------------------------------------------------------
+ Seq Scan on rls_test_both
+ Filter: (("current_user"() = supervisor) AND (((data % 2) = 0) OR ("current_user"() = username)))
+(2 rows)
SELECT * FROM rls_test_both;
username | supervisor | data
diff --git a/src/test/regress/expected/equivclass.out b/src/test/regress/expected/equivclass.out
index 0391b8eec19..564218b767a 100644
--- a/src/test/regress/expected/equivclass.out
+++ b/src/test/regress/expected/equivclass.out
@@ -381,3 +381,45 @@ explain (costs off)
Index Cond: (ff = '42'::bigint)
(14 rows)
+-- check effects of row-level security
+set enable_nestloop = on;
+set enable_mergejoin = off;
+alter table ec1 enable row level security;
+create policy p1 on ec1 using (f1 < '5'::int8alias1);
+create user regress_user_ectest;
+grant select on ec0 to regress_user_ectest;
+grant select on ec1 to regress_user_ectest;
+-- without any RLS, we'll treat {a.ff, b.ff, 43} as an EquivalenceClass
+explain (costs off)
+ select * from ec0 a, ec1 b
+ where a.ff = b.ff and a.ff = 43::bigint::int8alias1;
+ QUERY PLAN
+---------------------------------------------
+ Nested Loop
+ -> Index Scan using ec0_pkey on ec0 a
+ Index Cond: (ff = '43'::int8alias1)
+ -> Index Scan using ec1_pkey on ec1 b
+ Index Cond: (ff = '43'::int8alias1)
+(5 rows)
+
+set session authorization regress_user_ectest;
+-- with RLS active, the non-leakproof a.ff = 43 clause is not treated
+-- as a suitable source for an EquivalenceClass; currently, this is true
+-- even though the RLS clause has nothing to do directly with the EC
+explain (costs off)
+ select * from ec0 a, ec1 b
+ where a.ff = b.ff and a.ff = 43::bigint::int8alias1;
+ QUERY PLAN
+---------------------------------------------
+ Nested Loop
+ -> Index Scan using ec0_pkey on ec0 a
+ Index Cond: (ff = '43'::int8alias1)
+ -> Index Scan using ec1_pkey on ec1 b
+ Index Cond: (ff = a.ff)
+ Filter: (f1 < '5'::int8alias1)
+(6 rows)
+
+reset session authorization;
+revoke select on ec0 from regress_user_ectest;
+revoke select on ec1 from regress_user_ectest;
+drop user regress_user_ectest;
diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out
index 471e405c7ab..25407bf9ddd 100644
--- a/src/test/regress/expected/rowsecurity.out
+++ b/src/test/regress/expected/rowsecurity.out
@@ -265,32 +265,28 @@ NOTICE: f_leak => awesome science fiction
(5 rows)
EXPLAIN (COSTS OFF) SELECT * FROM document WHERE f_leak(dtitle);
- QUERY PLAN
-----------------------------------------------------------
- Subquery Scan on document
- Filter: f_leak(document.dtitle)
- -> Seq Scan on document document_1
- Filter: (dlevel <= $0)
- InitPlan 1 (returns $0)
- -> Index Scan using uaccount_pkey on uaccount
- Index Cond: (pguser = CURRENT_USER)
-(7 rows)
+ QUERY PLAN
+----------------------------------------------------
+ Seq Scan on document
+ Filter: ((dlevel <= $0) AND f_leak(dtitle))
+ InitPlan 1 (returns $0)
+ -> Index Scan using uaccount_pkey on uaccount
+ Index Cond: (pguser = CURRENT_USER)
+(5 rows)
EXPLAIN (COSTS OFF) SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle);
- QUERY PLAN
-----------------------------------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------------
Hash Join
Hash Cond: (category.cid = document.cid)
+ InitPlan 1 (returns $0)
+ -> Index Scan using uaccount_pkey on uaccount
+ Index Cond: (pguser = CURRENT_USER)
-> Seq Scan on category
-> Hash
- -> Subquery Scan on document
- Filter: f_leak(document.dtitle)
- -> Seq Scan on document document_1
- Filter: (dlevel <= $0)
- InitPlan 1 (returns $0)
- -> Index Scan using uaccount_pkey on uaccount
- Index Cond: (pguser = CURRENT_USER)
-(11 rows)
+ -> Seq Scan on document
+ Filter: ((dlevel <= $0) AND f_leak(dtitle))
+(9 rows)
-- viewpoint from regress_rls_dave
SET SESSION AUTHORIZATION regress_rls_dave;
@@ -333,32 +329,28 @@ NOTICE: f_leak => awesome technology book
(7 rows)
EXPLAIN (COSTS OFF) SELECT * FROM document WHERE f_leak(dtitle);
- QUERY PLAN
----------------------------------------------------------------------------------
- Subquery Scan on document
- Filter: f_leak(document.dtitle)
- -> Seq Scan on document document_1
- Filter: ((cid <> 44) AND (cid <> 44) AND (cid < 50) AND (dlevel <= $0))
- InitPlan 1 (returns $0)
- -> Index Scan using uaccount_pkey on uaccount
- Index Cond: (pguser = CURRENT_USER)
-(7 rows)
+ QUERY PLAN
+----------------------------------------------------------------------------------------------
+ Seq Scan on document
+ Filter: ((cid <> 44) AND (cid <> 44) AND (cid < 50) AND (dlevel <= $0) AND f_leak(dtitle))
+ InitPlan 1 (returns $0)
+ -> Index Scan using uaccount_pkey on uaccount
+ Index Cond: (pguser = CURRENT_USER)
+(5 rows)
EXPLAIN (COSTS OFF) SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle);
- QUERY PLAN
----------------------------------------------------------------------------------------------
+ QUERY PLAN
+----------------------------------------------------------------------------------------------------------
Hash Join
Hash Cond: (category.cid = document.cid)
+ InitPlan 1 (returns $0)
+ -> Index Scan using uaccount_pkey on uaccount
+ Index Cond: (pguser = CURRENT_USER)
-> Seq Scan on category
-> Hash
- -> Subquery Scan on document
- Filter: f_leak(document.dtitle)
- -> Seq Scan on document document_1
- Filter: ((cid <> 44) AND (cid <> 44) AND (cid < 50) AND (dlevel <= $0))
- InitPlan 1 (returns $0)
- -> Index Scan using uaccount_pkey on uaccount
- Index Cond: (pguser = CURRENT_USER)
-(11 rows)
+ -> Seq Scan on document
+ Filter: ((cid <> 44) AND (cid <> 44) AND (cid < 50) AND (dlevel <= $0) AND f_leak(dtitle))
+(9 rows)
-- 44 would technically fail for both p2r and p1r, but we should get an error
-- back from p1r for this because it sorts first
@@ -431,25 +423,21 @@ NOTICE: f_leak => great manga
(3 rows)
EXPLAIN (COSTS OFF) SELECT * FROM document WHERE f_leak(dtitle);
- QUERY PLAN
-------------------------------------------
- Subquery Scan on document
- Filter: f_leak(document.dtitle)
- -> Seq Scan on document document_1
- Filter: (dauthor = CURRENT_USER)
-(4 rows)
+ QUERY PLAN
+---------------------------------------------------------
+ Seq Scan on document
+ Filter: ((dauthor = CURRENT_USER) AND f_leak(dtitle))
+(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM document NATURAL JOIN category WHERE f_leak(dtitle);
- QUERY PLAN
---------------------------------------------------
+ QUERY PLAN
+---------------------------------------------------------------
Nested Loop
- -> Subquery Scan on document
- Filter: f_leak(document.dtitle)
- -> Seq Scan on document document_1
- Filter: (dauthor = CURRENT_USER)
+ -> Seq Scan on document
+ Filter: ((dauthor = CURRENT_USER) AND f_leak(dtitle))
-> Index Scan using category_pkey on category
Index Cond: (cid = document.cid)
-(7 rows)
+(5 rows)
-- interaction of FK/PK constraints
SET SESSION AUTHORIZATION regress_rls_alice;
@@ -698,18 +686,16 @@ NOTICE: f_leak => yyy
(5 rows)
EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b);
- QUERY PLAN
--------------------------------------
- Subquery Scan on t1
- Filter: f_leak(t1.b)
- -> Append
- -> Seq Scan on t1 t1_1
- Filter: ((a % 2) = 0)
- -> Seq Scan on t2
- Filter: ((a % 2) = 0)
- -> Seq Scan on t3
- Filter: ((a % 2) = 0)
-(9 rows)
+ QUERY PLAN
+-----------------------------------------------
+ Append
+ -> Seq Scan on t1
+ Filter: (((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t2
+ Filter: (((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t3
+ Filter: (((a % 2) = 0) AND f_leak(b))
+(7 rows)
-- reference to system column
SELECT oid, * FROM t1;
@@ -769,20 +755,17 @@ SELECT * FROM t1 FOR SHARE;
(5 rows)
EXPLAIN (COSTS OFF) SELECT * FROM t1 FOR SHARE;
- QUERY PLAN
--------------------------------------------------------
+ QUERY PLAN
+-------------------------------------
LockRows
- -> Subquery Scan on t1
- -> LockRows
- -> Result
- -> Append
- -> Seq Scan on t1 t1_1
- Filter: ((a % 2) = 0)
- -> Seq Scan on t2
- Filter: ((a % 2) = 0)
- -> Seq Scan on t3
- Filter: ((a % 2) = 0)
-(11 rows)
+ -> Append
+ -> Seq Scan on t1
+ Filter: ((a % 2) = 0)
+ -> Seq Scan on t2
+ Filter: ((a % 2) = 0)
+ -> Seq Scan on t3
+ Filter: ((a % 2) = 0)
+(8 rows)
SELECT * FROM t1 WHERE f_leak(b) FOR SHARE;
NOTICE: f_leak => bbb
@@ -800,21 +783,17 @@ NOTICE: f_leak => yyy
(5 rows)
EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) FOR SHARE;
- QUERY PLAN
--------------------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------
LockRows
- -> Subquery Scan on t1
- Filter: f_leak(t1.b)
- -> LockRows
- -> Result
- -> Append
- -> Seq Scan on t1 t1_1
- Filter: ((a % 2) = 0)
- -> Seq Scan on t2
- Filter: ((a % 2) = 0)
- -> Seq Scan on t3
- Filter: ((a % 2) = 0)
-(12 rows)
+ -> Append
+ -> Seq Scan on t1
+ Filter: (((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t2
+ Filter: (((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t3
+ Filter: (((a % 2) = 0) AND f_leak(b))
+(8 rows)
-- union all query
SELECT a, b, oid FROM t2 UNION ALL SELECT a, b, oid FROM t3;
@@ -1024,21 +1003,14 @@ NOTICE: f_leak => a87ff679a2f3e71d9181a67b7542122c
(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM only s1 WHERE f_leak(b);
- QUERY PLAN
-----------------------------------------------------------
- Subquery Scan on s1
- Filter: f_leak(s1.b)
- -> Hash Join
- Hash Cond: (s1_1.a = s2.x)
- -> Seq Scan on s1 s1_1
- -> Hash
- -> HashAggregate
- Group Key: s2.x
- -> Subquery Scan on s2
- Filter: (s2.y ~~ '%2f%'::text)
- -> Seq Scan on s2 s2_1
- Filter: ((x % 2) = 0)
-(12 rows)
+ QUERY PLAN
+-----------------------------------------------------------
+ Seq Scan on s1
+ Filter: ((hashed SubPlan 1) AND f_leak(b))
+ SubPlan 1
+ -> Seq Scan on s2
+ Filter: (((x % 2) = 0) AND (y ~~ '%2f%'::text))
+(5 rows)
SET SESSION AUTHORIZATION regress_rls_alice;
ALTER POLICY p1 ON s1 USING (a in (select x from v2)); -- using VIEW in RLS policy
@@ -1053,21 +1025,14 @@ NOTICE: f_leak => 1679091c5a880faf6fb5e6087eb1b2dc
(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM s1 WHERE f_leak(b);
- QUERY PLAN
-----------------------------------------------------------
- Subquery Scan on s1
- Filter: f_leak(s1.b)
- -> Hash Join
- Hash Cond: (s1_1.a = s2.x)
- -> Seq Scan on s1 s1_1
- -> Hash
- -> HashAggregate
- Group Key: s2.x
- -> Subquery Scan on s2
- Filter: (s2.y ~~ '%af%'::text)
- -> Seq Scan on s2 s2_1
- Filter: ((x % 2) = 0)
-(12 rows)
+ QUERY PLAN
+-----------------------------------------------------------
+ Seq Scan on s1
+ Filter: ((hashed SubPlan 1) AND f_leak(b))
+ SubPlan 1
+ -> Seq Scan on s2
+ Filter: (((x % 2) = 0) AND (y ~~ '%af%'::text))
+(5 rows)
SELECT (SELECT x FROM s1 LIMIT 1) xx, * FROM s2 WHERE y like '%28%';
xx | x | y
@@ -1078,24 +1043,18 @@ SELECT (SELECT x FROM s1 LIMIT 1) xx, * FROM s2 WHERE y like '%28%';
(3 rows)
EXPLAIN (COSTS OFF) SELECT (SELECT x FROM s1 LIMIT 1) xx, * FROM s2 WHERE y like '%28%';
- QUERY PLAN
---------------------------------------------------------------------
- Subquery Scan on s2
- Filter: (s2.y ~~ '%28%'::text)
- -> Seq Scan on s2 s2_1
- Filter: ((x % 2) = 0)
- SubPlan 1
+ QUERY PLAN
+-------------------------------------------------------------------------
+ Seq Scan on s2
+ Filter: (((x % 2) = 0) AND (y ~~ '%28%'::text))
+ SubPlan 2
-> Limit
- -> Subquery Scan on s1
- -> Nested Loop Semi Join
- Join Filter: (s1_1.a = s2_2.x)
- -> Seq Scan on s1 s1_1
- -> Materialize
- -> Subquery Scan on s2_2
- Filter: (s2_2.y ~~ '%af%'::text)
- -> Seq Scan on s2 s2_3
- Filter: ((x % 2) = 0)
-(15 rows)
+ -> Seq Scan on s1
+ Filter: (hashed SubPlan 1)
+ SubPlan 1
+ -> Seq Scan on s2 s2_1
+ Filter: (((x % 2) = 0) AND (y ~~ '%af%'::text))
+(9 rows)
SET SESSION AUTHORIZATION regress_rls_alice;
ALTER POLICY p2 ON s2 USING (x in (select a from s1 where b like '%d2%'));
@@ -1239,28 +1198,19 @@ EXPLAIN (COSTS OFF) EXECUTE p2(2);
--
SET SESSION AUTHORIZATION regress_rls_bob;
EXPLAIN (COSTS OFF) UPDATE t1 SET b = b || b WHERE f_leak(b);
- QUERY PLAN
--------------------------------------------
- Update on t1 t1_3
- Update on t1 t1_3
- Update on t2 t1
- Update on t3 t1
- -> Subquery Scan on t1
- Filter: f_leak(t1.b)
- -> LockRows
- -> Seq Scan on t1 t1_4
- Filter: ((a % 2) = 0)
- -> Subquery Scan on t1_1
- Filter: f_leak(t1_1.b)
- -> LockRows
- -> Seq Scan on t2
- Filter: ((a % 2) = 0)
- -> Subquery Scan on t1_2
- Filter: f_leak(t1_2.b)
- -> LockRows
- -> Seq Scan on t3
- Filter: ((a % 2) = 0)
-(19 rows)
+ QUERY PLAN
+-----------------------------------------------
+ Update on t1
+ Update on t1
+ Update on t2
+ Update on t3
+ -> Seq Scan on t1
+ Filter: (((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t2
+ Filter: (((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t3
+ Filter: (((a % 2) = 0) AND f_leak(b))
+(10 rows)
UPDATE t1 SET b = b || b WHERE f_leak(b);
NOTICE: f_leak => bbb
@@ -1269,15 +1219,12 @@ NOTICE: f_leak => bcd
NOTICE: f_leak => def
NOTICE: f_leak => yyy
EXPLAIN (COSTS OFF) UPDATE only t1 SET b = b || '_updt' WHERE f_leak(b);
- QUERY PLAN
--------------------------------------------
- Update on t1 t1_1
- -> Subquery Scan on t1
- Filter: f_leak(t1.b)
- -> LockRows
- -> Seq Scan on t1 t1_2
- Filter: ((a % 2) = 0)
-(6 rows)
+ QUERY PLAN
+-----------------------------------------------
+ Update on t1
+ -> Seq Scan on t1
+ Filter: (((a % 2) = 0) AND f_leak(b))
+(3 rows)
UPDATE only t1 SET b = b || '_updt' WHERE f_leak(b);
NOTICE: f_leak => bbbbbb
@@ -1325,89 +1272,63 @@ NOTICE: f_leak => yyyyyy
-- updates with from clause
EXPLAIN (COSTS OFF) UPDATE t2 SET b=t2.b FROM t3
WHERE t2.a = 3 and t3.a = 2 AND f_leak(t2.b) AND f_leak(t3.b);
- QUERY PLAN
----------------------------------------------------------------
- Update on t2 t2_1
+ QUERY PLAN
+-----------------------------------------------------------------
+ Update on t2
-> Nested Loop
- -> Subquery Scan on t2
- Filter: f_leak(t2.b)
- -> LockRows
- -> Seq Scan on t2 t2_2
- Filter: ((a = 3) AND ((a % 2) = 1))
+ -> Seq Scan on t2
+ Filter: ((a = 3) AND ((a % 2) = 1) AND f_leak(b))
-> Seq Scan on t3
- Filter: (f_leak(b) AND (a = 2))
-(9 rows)
+ Filter: ((a = 2) AND f_leak(b))
+(6 rows)
UPDATE t2 SET b=t2.b FROM t3
WHERE t2.a = 3 and t3.a = 2 AND f_leak(t2.b) AND f_leak(t3.b);
NOTICE: f_leak => cde
-NOTICE: f_leak => xxx
-NOTICE: f_leak => zzz
NOTICE: f_leak => yyyyyy
EXPLAIN (COSTS OFF) UPDATE t1 SET b=t1.b FROM t2
WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b);
- QUERY PLAN
----------------------------------------------------------------
- Update on t1 t1_3
- Update on t1 t1_3
- Update on t2 t1
- Update on t3 t1
+ QUERY PLAN
+-----------------------------------------------------------------
+ Update on t1
+ Update on t1
+ Update on t2 t2_1
+ Update on t3
-> Nested Loop
- -> Subquery Scan on t1
- Filter: f_leak(t1.b)
- -> LockRows
- -> Seq Scan on t1 t1_4
- Filter: ((a = 3) AND ((a % 2) = 0))
- -> Subquery Scan on t2
- Filter: f_leak(t2.b)
- -> Seq Scan on t2 t2_3
- Filter: ((a = 3) AND ((a % 2) = 1))
+ -> Seq Scan on t1
+ Filter: ((a = 3) AND ((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t2
+ Filter: ((a = 3) AND ((a % 2) = 1) AND f_leak(b))
-> Nested Loop
- -> Subquery Scan on t1_1
- Filter: f_leak(t1_1.b)
- -> LockRows
- -> Seq Scan on t2 t2_4
- Filter: ((a = 3) AND ((a % 2) = 0))
- -> Subquery Scan on t2_1
- Filter: f_leak(t2_1.b)
- -> Seq Scan on t2 t2_5
- Filter: ((a = 3) AND ((a % 2) = 1))
+ -> Seq Scan on t2 t2_1
+ Filter: ((a = 3) AND ((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t2
+ Filter: ((a = 3) AND ((a % 2) = 1) AND f_leak(b))
-> Nested Loop
- -> Subquery Scan on t1_2
- Filter: f_leak(t1_2.b)
- -> LockRows
- -> Seq Scan on t3
- Filter: ((a = 3) AND ((a % 2) = 0))
- -> Subquery Scan on t2_2
- Filter: f_leak(t2_2.b)
- -> Seq Scan on t2 t2_6
- Filter: ((a = 3) AND ((a % 2) = 1))
-(34 rows)
+ -> Seq Scan on t3
+ Filter: ((a = 3) AND ((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t2
+ Filter: ((a = 3) AND ((a % 2) = 1) AND f_leak(b))
+(19 rows)
UPDATE t1 SET b=t1.b FROM t2
WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b);
EXPLAIN (COSTS OFF) UPDATE t2 SET b=t2.b FROM t1
WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b);
- QUERY PLAN
----------------------------------------------------------------------
- Update on t2 t2_1
+ QUERY PLAN
+-----------------------------------------------------------------------
+ Update on t2
-> Nested Loop
- -> Subquery Scan on t2
- Filter: f_leak(t2.b)
- -> LockRows
- -> Seq Scan on t2 t2_2
- Filter: ((a = 3) AND ((a % 2) = 1))
- -> Subquery Scan on t1
- Filter: f_leak(t1.b)
- -> Result
- -> Append
- -> Seq Scan on t1 t1_1
- Filter: ((a = 3) AND ((a % 2) = 0))
- -> Seq Scan on t2 t2_3
- Filter: ((a = 3) AND ((a % 2) = 0))
- -> Seq Scan on t3
- Filter: ((a = 3) AND ((a % 2) = 0))
-(17 rows)
+ -> Seq Scan on t2
+ Filter: ((a = 3) AND ((a % 2) = 1) AND f_leak(b))
+ -> Append
+ -> Seq Scan on t1
+ Filter: ((a = 3) AND ((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t2 t2_1
+ Filter: ((a = 3) AND ((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t3
+ Filter: ((a = 3) AND ((a % 2) = 0) AND f_leak(b))
+(11 rows)
UPDATE t2 SET b=t2.b FROM t1
WHERE t1.a = 3 and t2.a = 3 AND f_leak(t1.b) AND f_leak(t2.b);
@@ -1416,21 +1337,16 @@ NOTICE: f_leak => cde
EXPLAIN (COSTS OFF) UPDATE t2 t2_1 SET b = t2_2.b FROM t2 t2_2
WHERE t2_1.a = 3 AND t2_2.a = t2_1.a AND t2_2.b = t2_1.b
AND f_leak(t2_1.b) AND f_leak(t2_2.b) RETURNING *, t2_1, t2_2;
- QUERY PLAN
----------------------------------------------------------------
- Update on t2 t2_1_1
+ QUERY PLAN
+-----------------------------------------------------------------
+ Update on t2 t2_1
-> Nested Loop
Join Filter: (t2_1.b = t2_2.b)
- -> Subquery Scan on t2_1
- Filter: f_leak(t2_1.b)
- -> LockRows
- -> Seq Scan on t2 t2_1_2
- Filter: ((a = 3) AND ((a % 2) = 1))
- -> Subquery Scan on t2_2
- Filter: f_leak(t2_2.b)
- -> Seq Scan on t2 t2_2_1
- Filter: ((a = 3) AND ((a % 2) = 1))
-(12 rows)
+ -> Seq Scan on t2 t2_1
+ Filter: ((a = 3) AND ((a % 2) = 1) AND f_leak(b))
+ -> Seq Scan on t2 t2_2
+ Filter: ((a = 3) AND ((a % 2) = 1) AND f_leak(b))
+(7 rows)
UPDATE t2 t2_1 SET b = t2_2.b FROM t2 t2_2
WHERE t2_1.a = 3 AND t2_2.a = t2_1.a AND t2_2.b = t2_1.b
@@ -1445,61 +1361,46 @@ NOTICE: f_leak => cde
EXPLAIN (COSTS OFF) UPDATE t1 t1_1 SET b = t1_2.b FROM t1 t1_2
WHERE t1_1.a = 4 AND t1_2.a = t1_1.a AND t1_2.b = t1_1.b
AND f_leak(t1_1.b) AND f_leak(t1_2.b) RETURNING *, t1_1, t1_2;
- QUERY PLAN
----------------------------------------------------------------
- Update on t1 t1_1_3
- Update on t1 t1_1_3
- Update on t2 t1_1
- Update on t3 t1_1
+ QUERY PLAN
+-----------------------------------------------------------------------
+ Update on t1 t1_1
+ Update on t1 t1_1
+ Update on t2 t1_1_1
+ Update on t3 t1_1_2
-> Nested Loop
Join Filter: (t1_1.b = t1_2.b)
- -> Subquery Scan on t1_1
- Filter: f_leak(t1_1.b)
- -> LockRows
- -> Seq Scan on t1 t1_1_4
- Filter: ((a = 4) AND ((a % 2) = 0))
- -> Subquery Scan on t1_2
- Filter: f_leak(t1_2.b)
- -> Append
- -> Seq Scan on t1 t1_2_3
- Filter: ((a = 4) AND ((a % 2) = 0))
- -> Seq Scan on t2 t1_2_4
- Filter: ((a = 4) AND ((a % 2) = 0))
- -> Seq Scan on t3 t1_2_5
- Filter: ((a = 4) AND ((a % 2) = 0))
+ -> Seq Scan on t1 t1_1
+ Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
+ -> Append
+ -> Seq Scan on t1 t1_2
+ Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t2 t1_2_1
+ Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t3 t1_2_2
+ Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
-> Nested Loop
- Join Filter: (t1_1_1.b = t1_2_1.b)
- -> Subquery Scan on t1_1_1
- Filter: f_leak(t1_1_1.b)
- -> LockRows
- -> Seq Scan on t2 t1_1_5
- Filter: ((a = 4) AND ((a % 2) = 0))
- -> Subquery Scan on t1_2_1
- Filter: f_leak(t1_2_1.b)
- -> Append
- -> Seq Scan on t1 t1_2_6
- Filter: ((a = 4) AND ((a % 2) = 0))
- -> Seq Scan on t2 t1_2_7
- Filter: ((a = 4) AND ((a % 2) = 0))
- -> Seq Scan on t3 t1_2_8
- Filter: ((a = 4) AND ((a % 2) = 0))
+ Join Filter: (t1_1_1.b = t1_2.b)
+ -> Seq Scan on t2 t1_1_1
+ Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
+ -> Append
+ -> Seq Scan on t1 t1_2
+ Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t2 t1_2_1
+ Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t3 t1_2_2
+ Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
-> Nested Loop
- Join Filter: (t1_1_2.b = t1_2_2.b)
- -> Subquery Scan on t1_1_2
- Filter: f_leak(t1_1_2.b)
- -> LockRows
- -> Seq Scan on t3 t1_1_6
- Filter: ((a = 4) AND ((a % 2) = 0))
- -> Subquery Scan on t1_2_2
- Filter: f_leak(t1_2_2.b)
- -> Append
- -> Seq Scan on t1 t1_2_9
- Filter: ((a = 4) AND ((a % 2) = 0))
- -> Seq Scan on t2 t1_2_10
- Filter: ((a = 4) AND ((a % 2) = 0))
- -> Seq Scan on t3 t1_2_11
- Filter: ((a = 4) AND ((a % 2) = 0))
-(52 rows)
+ Join Filter: (t1_1_2.b = t1_2.b)
+ -> Seq Scan on t3 t1_1_2
+ Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
+ -> Append
+ -> Seq Scan on t1 t1_2
+ Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t2 t1_2_1
+ Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t3 t1_2_2
+ Filter: ((a = 4) AND ((a % 2) = 0) AND f_leak(b))
+(37 rows)
UPDATE t1 t1_1 SET b = t1_2.b FROM t1 t1_2
WHERE t1_1.a = 4 AND t1_2.a = t1_1.a AND t1_2.b = t1_1.b
@@ -1537,39 +1438,27 @@ SELECT * FROM t1 ORDER BY a,b;
SET SESSION AUTHORIZATION regress_rls_bob;
SET row_security TO ON;
EXPLAIN (COSTS OFF) DELETE FROM only t1 WHERE f_leak(b);
- QUERY PLAN
--------------------------------------------
- Delete on t1 t1_1
- -> Subquery Scan on t1
- Filter: f_leak(t1.b)
- -> LockRows
- -> Seq Scan on t1 t1_2
- Filter: ((a % 2) = 0)
-(6 rows)
+ QUERY PLAN
+-----------------------------------------------
+ Delete on t1
+ -> Seq Scan on t1
+ Filter: (((a % 2) = 0) AND f_leak(b))
+(3 rows)
EXPLAIN (COSTS OFF) DELETE FROM t1 WHERE f_leak(b);
- QUERY PLAN
--------------------------------------------
- Delete on t1 t1_3
- Delete on t1 t1_3
- Delete on t2 t1
- Delete on t3 t1
- -> Subquery Scan on t1
- Filter: f_leak(t1.b)
- -> LockRows
- -> Seq Scan on t1 t1_4
- Filter: ((a % 2) = 0)
- -> Subquery Scan on t1_1
- Filter: f_leak(t1_1.b)
- -> LockRows
- -> Seq Scan on t2
- Filter: ((a % 2) = 0)
- -> Subquery Scan on t1_2
- Filter: f_leak(t1_2.b)
- -> LockRows
- -> Seq Scan on t3
- Filter: ((a % 2) = 0)
-(19 rows)
+ QUERY PLAN
+-----------------------------------------------
+ Delete on t1
+ Delete on t1
+ Delete on t2
+ Delete on t3
+ -> Seq Scan on t1
+ Filter: (((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t2
+ Filter: (((a % 2) = 0) AND f_leak(b))
+ -> Seq Scan on t3
+ Filter: (((a % 2) = 0) AND f_leak(b))
+(10 rows)
DELETE FROM only t1 WHERE f_leak(b) RETURNING oid, *, t1;
NOTICE: f_leak => bbbbbb_updt
@@ -1634,30 +1523,22 @@ INSERT INTO bv1 VALUES (11, 'xxx'); -- should fail RLS check
ERROR: new row violates row-level security policy for table "b1"
INSERT INTO bv1 VALUES (12, 'xxx'); -- ok
EXPLAIN (COSTS OFF) UPDATE bv1 SET b = 'yyy' WHERE a = 4 AND f_leak(b);
- QUERY PLAN
----------------------------------------------------------------------------
- Update on b1 b1_1
- -> Subquery Scan on b1
- Filter: f_leak(b1.b)
- -> Subquery Scan on b1_2
- -> LockRows
- -> Seq Scan on b1 b1_3
- Filter: ((a > 0) AND (a = 4) AND ((a % 2) = 0))
-(7 rows)
+ QUERY PLAN
+-----------------------------------------------------------------------
+ Update on b1
+ -> Seq Scan on b1
+ Filter: ((a > 0) AND (a = 4) AND ((a % 2) = 0) AND f_leak(b))
+(3 rows)
UPDATE bv1 SET b = 'yyy' WHERE a = 4 AND f_leak(b);
NOTICE: f_leak => a87ff679a2f3e71d9181a67b7542122c
EXPLAIN (COSTS OFF) DELETE FROM bv1 WHERE a = 6 AND f_leak(b);
- QUERY PLAN
----------------------------------------------------------------------------
- Delete on b1 b1_1
- -> Subquery Scan on b1
- Filter: f_leak(b1.b)
- -> Subquery Scan on b1_2
- -> LockRows
- -> Seq Scan on b1 b1_3
- Filter: ((a > 0) AND (a = 6) AND ((a % 2) = 0))
-(7 rows)
+ QUERY PLAN
+-----------------------------------------------------------------------
+ Delete on b1
+ -> Seq Scan on b1
+ Filter: ((a > 0) AND (a = 6) AND ((a % 2) = 0) AND f_leak(b))
+(3 rows)
DELETE FROM bv1 WHERE a = 6 AND f_leak(b);
NOTICE: f_leak => 1679091c5a880faf6fb5e6087eb1b2dc
@@ -1848,53 +1729,45 @@ NOTICE: f_leak => dad
(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b);
- QUERY PLAN
--------------------------------
- Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 0)
-(4 rows)
+ QUERY PLAN
+-----------------------------------------
+ Seq Scan on z1
+ Filter: (((a % 2) = 0) AND f_leak(b))
+(2 rows)
PREPARE plancache_test AS SELECT * FROM z1 WHERE f_leak(b);
EXPLAIN (COSTS OFF) EXECUTE plancache_test;
- QUERY PLAN
--------------------------------
- Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 0)
-(4 rows)
+ QUERY PLAN
+-----------------------------------------
+ Seq Scan on z1
+ Filter: (((a % 2) = 0) AND f_leak(b))
+(2 rows)
PREPARE plancache_test2 AS WITH q AS (SELECT * FROM z1 WHERE f_leak(b)) SELECT * FROM q,z2;
EXPLAIN (COSTS OFF) EXECUTE plancache_test2;
- QUERY PLAN
----------------------------------------
+ QUERY PLAN
+-------------------------------------------------
Nested Loop
CTE q
- -> Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 0)
+ -> Seq Scan on z1
+ Filter: (((a % 2) = 0) AND f_leak(b))
-> CTE Scan on q
-> Materialize
-> Seq Scan on z2
-(9 rows)
+(7 rows)
PREPARE plancache_test3 AS WITH q AS (SELECT * FROM z2) SELECT * FROM q,z1 WHERE f_leak(z1.b);
EXPLAIN (COSTS OFF) EXECUTE plancache_test3;
- QUERY PLAN
--------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------
Nested Loop
CTE q
-> Seq Scan on z2
-> CTE Scan on q
-> Materialize
- -> Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 0)
-(9 rows)
+ -> Seq Scan on z1
+ Filter: (((a % 2) = 0) AND f_leak(b))
+(7 rows)
SET ROLE regress_rls_group1;
SELECT * FROM z1 WHERE f_leak(b);
@@ -1907,50 +1780,42 @@ NOTICE: f_leak => dad
(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b);
- QUERY PLAN
--------------------------------
- Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 0)
-(4 rows)
+ QUERY PLAN
+-----------------------------------------
+ Seq Scan on z1
+ Filter: (((a % 2) = 0) AND f_leak(b))
+(2 rows)
EXPLAIN (COSTS OFF) EXECUTE plancache_test;
- QUERY PLAN
--------------------------------
- Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 0)
-(4 rows)
+ QUERY PLAN
+-----------------------------------------
+ Seq Scan on z1
+ Filter: (((a % 2) = 0) AND f_leak(b))
+(2 rows)
EXPLAIN (COSTS OFF) EXECUTE plancache_test2;
- QUERY PLAN
----------------------------------------
+ QUERY PLAN
+-------------------------------------------------
Nested Loop
CTE q
- -> Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 0)
+ -> Seq Scan on z1
+ Filter: (((a % 2) = 0) AND f_leak(b))
-> CTE Scan on q
-> Materialize
-> Seq Scan on z2
-(9 rows)
+(7 rows)
EXPLAIN (COSTS OFF) EXECUTE plancache_test3;
- QUERY PLAN
--------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------
Nested Loop
CTE q
-> Seq Scan on z2
-> CTE Scan on q
-> Materialize
- -> Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 0)
-(9 rows)
+ -> Seq Scan on z1
+ Filter: (((a % 2) = 0) AND f_leak(b))
+(7 rows)
SET SESSION AUTHORIZATION regress_rls_carol;
SELECT * FROM z1 WHERE f_leak(b);
@@ -1963,50 +1828,42 @@ NOTICE: f_leak => ccc
(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b);
- QUERY PLAN
--------------------------------
- Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 1)
-(4 rows)
+ QUERY PLAN
+-----------------------------------------
+ Seq Scan on z1
+ Filter: (((a % 2) = 1) AND f_leak(b))
+(2 rows)
EXPLAIN (COSTS OFF) EXECUTE plancache_test;
- QUERY PLAN
--------------------------------
- Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 1)
-(4 rows)
+ QUERY PLAN
+-----------------------------------------
+ Seq Scan on z1
+ Filter: (((a % 2) = 1) AND f_leak(b))
+(2 rows)
EXPLAIN (COSTS OFF) EXECUTE plancache_test2;
- QUERY PLAN
----------------------------------------
+ QUERY PLAN
+-------------------------------------------------
Nested Loop
CTE q
- -> Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 1)
+ -> Seq Scan on z1
+ Filter: (((a % 2) = 1) AND f_leak(b))
-> CTE Scan on q
-> Materialize
-> Seq Scan on z2
-(9 rows)
+(7 rows)
EXPLAIN (COSTS OFF) EXECUTE plancache_test3;
- QUERY PLAN
--------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------
Nested Loop
CTE q
-> Seq Scan on z2
-> CTE Scan on q
-> Materialize
- -> Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 1)
-(9 rows)
+ -> Seq Scan on z1
+ Filter: (((a % 2) = 1) AND f_leak(b))
+(7 rows)
SET ROLE regress_rls_group2;
SELECT * FROM z1 WHERE f_leak(b);
@@ -2019,50 +1876,42 @@ NOTICE: f_leak => ccc
(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b);
- QUERY PLAN
--------------------------------
- Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 1)
-(4 rows)
+ QUERY PLAN
+-----------------------------------------
+ Seq Scan on z1
+ Filter: (((a % 2) = 1) AND f_leak(b))
+(2 rows)
EXPLAIN (COSTS OFF) EXECUTE plancache_test;
- QUERY PLAN
--------------------------------
- Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 1)
-(4 rows)
+ QUERY PLAN
+-----------------------------------------
+ Seq Scan on z1
+ Filter: (((a % 2) = 1) AND f_leak(b))
+(2 rows)
EXPLAIN (COSTS OFF) EXECUTE plancache_test2;
- QUERY PLAN
----------------------------------------
+ QUERY PLAN
+-------------------------------------------------
Nested Loop
CTE q
- -> Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 1)
+ -> Seq Scan on z1
+ Filter: (((a % 2) = 1) AND f_leak(b))
-> CTE Scan on q
-> Materialize
-> Seq Scan on z2
-(9 rows)
+(7 rows)
EXPLAIN (COSTS OFF) EXECUTE plancache_test3;
- QUERY PLAN
--------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------
Nested Loop
CTE q
-> Seq Scan on z2
-> CTE Scan on q
-> Materialize
- -> Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 1)
-(9 rows)
+ -> Seq Scan on z1
+ Filter: (((a % 2) = 1) AND f_leak(b))
+(7 rows)
--
-- Views should follow policy for view owner.
@@ -2133,13 +1982,11 @@ NOTICE: f_leak => dad
(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM rls_view;
- QUERY PLAN
--------------------------------
- Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 0)
-(4 rows)
+ QUERY PLAN
+-----------------------------------------
+ Seq Scan on z1
+ Filter: (((a % 2) = 0) AND f_leak(b))
+(2 rows)
-- Query as role that is not owner of table but is owner of view.
-- Should return records based on view owner policies.
@@ -2154,13 +2001,11 @@ NOTICE: f_leak => dad
(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM rls_view;
- QUERY PLAN
--------------------------------
- Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 0)
-(4 rows)
+ QUERY PLAN
+-----------------------------------------
+ Seq Scan on z1
+ Filter: (((a % 2) = 0) AND f_leak(b))
+(2 rows)
-- Query as role that is not the owner of the table or view without permissions.
SET SESSION AUTHORIZATION regress_rls_carol;
@@ -2181,13 +2026,11 @@ NOTICE: f_leak => dad
(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM rls_view;
- QUERY PLAN
--------------------------------
- Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 0)
-(4 rows)
+ QUERY PLAN
+-----------------------------------------
+ Seq Scan on z1
+ Filter: (((a % 2) = 0) AND f_leak(b))
+(2 rows)
SET SESSION AUTHORIZATION regress_rls_bob;
DROP VIEW rls_view;
@@ -2333,13 +2176,11 @@ SET SESSION AUTHORIZATION regress_rls_bob;
CREATE VIEW rls_sbv WITH (security_barrier) AS
SELECT * FROM y1 WHERE f_leak(b);
EXPLAIN (COSTS OFF) SELECT * FROM rls_sbv WHERE (a = 1);
- QUERY PLAN
-----------------------------------------------------------
- Subquery Scan on y1
- Filter: f_leak(y1.b)
- -> Seq Scan on y1 y1_1
- Filter: ((a = 1) AND ((a > 2) OR ((a % 2) = 0)))
-(4 rows)
+ QUERY PLAN
+------------------------------------------------------------------
+ Seq Scan on y1
+ Filter: ((a = 1) AND ((a > 2) OR ((a % 2) = 0)) AND f_leak(b))
+(2 rows)
DROP VIEW rls_sbv;
--
@@ -2384,13 +2225,11 @@ NOTICE: f_leak => 98f13708210194c475687be6106a3b84
(14 rows)
EXPLAIN (COSTS OFF) SELECT * FROM y2 WHERE f_leak(b);
- QUERY PLAN
--------------------------------------------------------------------
- Subquery Scan on y2
- Filter: f_leak(y2.b)
- -> Seq Scan on y2 y2_1
- Filter: (((a % 4) = 0) OR ((a % 3) = 0) OR ((a % 2) = 0))
-(4 rows)
+ QUERY PLAN
+-----------------------------------------------------------------------------
+ Seq Scan on y2
+ Filter: ((((a % 4) = 0) OR ((a % 3) = 0) OR ((a % 2) = 0)) AND f_leak(b))
+(2 rows)
--
-- Qual push-down of leaky functions, when not referring to table
@@ -2485,17 +2324,15 @@ NOTICE: f_leak => 98f13708210194c475687be6106a3b84
(0 rows)
EXPLAIN (COSTS OFF) SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(b);
- QUERY PLAN
--------------------------------------------------------------------------------
+ QUERY PLAN
+-----------------------------------------------------------------------------------------
Hash Join
Hash Cond: (test_qual_pushdown.abc = y2.b)
-> Seq Scan on test_qual_pushdown
-> Hash
- -> Subquery Scan on y2
- Filter: f_leak(y2.b)
- -> Seq Scan on y2 y2_1
- Filter: (((a % 4) = 0) OR ((a % 3) = 0) OR ((a % 2) = 0))
-(8 rows)
+ -> Seq Scan on y2
+ Filter: ((((a % 4) = 0) OR ((a % 3) = 0) OR ((a % 2) = 0)) AND f_leak(b))
+(6 rows)
DROP TABLE test_qual_pushdown;
--
@@ -2581,15 +2418,13 @@ NOTICE: f_leak => 98f13708210194c475687be6106a3b84
(11 rows)
EXPLAIN (COSTS OFF) WITH cte1 AS (SELECT * FROM t1 WHERE f_leak(b)) SELECT * FROM cte1;
- QUERY PLAN
----------------------------------------
+ QUERY PLAN
+-------------------------------------------------
CTE Scan on cte1
CTE cte1
- -> Subquery Scan on t1
- Filter: f_leak(t1.b)
- -> Seq Scan on t1 t1_1
- Filter: ((a % 2) = 0)
-(6 rows)
+ -> Seq Scan on t1
+ Filter: (((a % 2) = 0) AND f_leak(b))
+(4 rows)
WITH cte1 AS (UPDATE t1 SET a = a + 1 RETURNING *) SELECT * FROM cte1; --fail
ERROR: new row violates row-level security policy for table "t1"
@@ -3100,17 +2935,13 @@ SELECT * FROM current_check;
-- Plan should be a subquery TID scan
EXPLAIN (COSTS OFF) UPDATE current_check SET payload = payload WHERE CURRENT OF current_check_cursor;
- QUERY PLAN
----------------------------------------------------------------------
- Update on current_check current_check_1
- -> Subquery Scan on current_check
- -> Subquery Scan on current_check_2
- Filter: ((current_check_2.currentid % 2) = 0)
- -> LockRows
- -> Tid Scan on current_check current_check_3
- TID Cond: CURRENT OF current_check_cursor
- Filter: (currentid = 4)
-(8 rows)
+ QUERY PLAN
+-------------------------------------------------------------
+ Update on current_check
+ -> Tid Scan on current_check
+ TID Cond: CURRENT OF current_check_cursor
+ Filter: ((currentid = 4) AND ((currentid % 2) = 0))
+(4 rows)
-- Similarly can only delete row 4
FETCH ABSOLUTE 1 FROM current_check_cursor;
diff --git a/src/test/regress/expected/updatable_views.out b/src/test/regress/expected/updatable_views.out
index 6fba613f0f5..2da3c069e11 100644
--- a/src/test/regress/expected/updatable_views.out
+++ b/src/test/regress/expected/updatable_views.out
@@ -1896,26 +1896,20 @@ EXPLAIN (costs off) SELECT * FROM rw_view1 WHERE snoop(person);
(4 rows)
EXPLAIN (costs off) UPDATE rw_view1 SET person=person WHERE snoop(person);
- QUERY PLAN
------------------------------------------------------------
- Update on base_tbl base_tbl_1
- -> Subquery Scan on base_tbl
- Filter: snoop(base_tbl.person)
- -> LockRows
- -> Seq Scan on base_tbl base_tbl_2
- Filter: (visibility = 'public'::text)
-(6 rows)
+ QUERY PLAN
+-------------------------------------------------------------------
+ Update on base_tbl
+ -> Seq Scan on base_tbl
+ Filter: ((visibility = 'public'::text) AND snoop(person))
+(3 rows)
EXPLAIN (costs off) DELETE FROM rw_view1 WHERE NOT snoop(person);
- QUERY PLAN
------------------------------------------------------------
- Delete on base_tbl base_tbl_1
- -> Subquery Scan on base_tbl
- Filter: (NOT snoop(base_tbl.person))
- -> LockRows
- -> Seq Scan on base_tbl base_tbl_2
- Filter: (visibility = 'public'::text)
-(6 rows)
+ QUERY PLAN
+-------------------------------------------------------------------------
+ Delete on base_tbl
+ -> Seq Scan on base_tbl
+ Filter: ((visibility = 'public'::text) AND (NOT snoop(person)))
+(3 rows)
-- security barrier view on top of security barrier view
CREATE VIEW rw_view2 WITH (security_barrier = true) AS
@@ -1978,30 +1972,20 @@ EXPLAIN (costs off) SELECT * FROM rw_view2 WHERE snoop(person);
(6 rows)
EXPLAIN (costs off) UPDATE rw_view2 SET person=person WHERE snoop(person);
- QUERY PLAN
------------------------------------------------------------------
- Update on base_tbl base_tbl_1
- -> Subquery Scan on base_tbl
- Filter: snoop(base_tbl.person)
- -> Subquery Scan on base_tbl_2
- Filter: snoop(base_tbl_2.person)
- -> LockRows
- -> Seq Scan on base_tbl base_tbl_3
- Filter: (visibility = 'public'::text)
-(8 rows)
+ QUERY PLAN
+-------------------------------------------------------------------------------------
+ Update on base_tbl
+ -> Seq Scan on base_tbl
+ Filter: ((visibility = 'public'::text) AND snoop(person) AND snoop(person))
+(3 rows)
EXPLAIN (costs off) DELETE FROM rw_view2 WHERE NOT snoop(person);
- QUERY PLAN
------------------------------------------------------------------
- Delete on base_tbl base_tbl_1
- -> Subquery Scan on base_tbl
- Filter: (NOT snoop(base_tbl.person))
- -> Subquery Scan on base_tbl_2
- Filter: snoop(base_tbl_2.person)
- -> LockRows
- -> Seq Scan on base_tbl base_tbl_3
- Filter: (visibility = 'public'::text)
-(8 rows)
+ QUERY PLAN
+-------------------------------------------------------------------------------------------
+ Delete on base_tbl
+ -> Seq Scan on base_tbl
+ Filter: ((visibility = 'public'::text) AND snoop(person) AND (NOT snoop(person)))
+(3 rows)
DROP TABLE base_tbl CASCADE;
NOTICE: drop cascades to 2 other objects
@@ -2026,18 +2010,16 @@ SELECT * FROM rw_view1;
(1 row)
EXPLAIN (costs off) DELETE FROM rw_view1 WHERE id = 1 AND snoop(data);
- QUERY PLAN
--------------------------------------------------------------------------
+ QUERY PLAN
+-------------------------------------------------------------------
Update on base_tbl base_tbl_1
-> Nested Loop
-> Index Scan using base_tbl_pkey on base_tbl base_tbl_1
Index Cond: (id = 1)
- -> Subquery Scan on base_tbl
- Filter: snoop(base_tbl.data)
- -> Index Scan using base_tbl_pkey on base_tbl base_tbl_2
- Index Cond: (id = 1)
- Filter: (NOT deleted)
-(9 rows)
+ -> Index Scan using base_tbl_pkey on base_tbl
+ Index Cond: (id = 1)
+ Filter: ((NOT deleted) AND snoop(data))
+(7 rows)
DELETE FROM rw_view1 WHERE id = 1 AND snoop(data);
NOTICE: snooped value: Row 1
@@ -2114,85 +2096,45 @@ SELECT * FROM v1 WHERE a=8;
(4 rows)
EXPLAIN (VERBOSE, COSTS OFF)
-UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a = 3;
- QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------
- Update on public.t1 t1_4
- Update on public.t1 t1_4
- Update on public.t11 t1
- Update on public.t12 t1
- Update on public.t111 t1
- -> Subquery Scan on t1
+UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6;
+ QUERY PLAN
+---------------------------------------------------------------------------------------------------------------------------
+ Update on public.t1
+ Update on public.t1
+ Update on public.t11
+ Update on public.t12
+ Update on public.t111
+ -> Index Scan using t1_a_idx on public.t1
Output: 100, t1.b, t1.c, t1.ctid
- Filter: snoop(t1.a)
- -> LockRows
- Output: t1_5.ctid, t1_5.a, t1_5.b, t1_5.c, t1_5.ctid, t12.ctid, t12.tableoid
- -> Nested Loop Semi Join
- Output: t1_5.ctid, t1_5.a, t1_5.b, t1_5.c, t1_5.ctid, t12.ctid, t12.tableoid
- -> Seq Scan on public.t1 t1_5
- Output: t1_5.ctid, t1_5.a, t1_5.b, t1_5.c
- Filter: ((t1_5.a > 5) AND (t1_5.a = 3) AND leakproof(t1_5.a))
- -> Append
- -> Seq Scan on public.t12
- Output: t12.ctid, t12.tableoid, t12.a
- Filter: (t12.a = 3)
- -> Seq Scan on public.t111
- Output: t111.ctid, t111.tableoid, t111.a
- Filter: (t111.a = 3)
- -> Subquery Scan on t1_1
- Output: 100, t1_1.b, t1_1.c, t1_1.d, t1_1.ctid
- Filter: snoop(t1_1.a)
- -> LockRows
- Output: t11.ctid, t11.a, t11.b, t11.c, t11.d, t11.ctid, t12_1.ctid, t12_1.tableoid
- -> Nested Loop Semi Join
- Output: t11.ctid, t11.a, t11.b, t11.c, t11.d, t11.ctid, t12_1.ctid, t12_1.tableoid
- -> Seq Scan on public.t11
- Output: t11.ctid, t11.a, t11.b, t11.c, t11.d
- Filter: ((t11.a > 5) AND (t11.a = 3) AND leakproof(t11.a))
- -> Append
- -> Seq Scan on public.t12 t12_1
- Output: t12_1.ctid, t12_1.tableoid, t12_1.a
- Filter: (t12_1.a = 3)
- -> Seq Scan on public.t111 t111_1
- Output: t111_1.ctid, t111_1.tableoid, t111_1.a
- Filter: (t111_1.a = 3)
- -> Subquery Scan on t1_2
- Output: 100, t1_2.b, t1_2.c, t1_2.e, t1_2.ctid
- Filter: snoop(t1_2.a)
- -> LockRows
- Output: t12_2.ctid, t12_2.a, t12_2.b, t12_2.c, t12_2.e, t12_2.ctid, t12_3.ctid, t12_3.tableoid
- -> Nested Loop Semi Join
- Output: t12_2.ctid, t12_2.a, t12_2.b, t12_2.c, t12_2.e, t12_2.ctid, t12_3.ctid, t12_3.tableoid
- -> Seq Scan on public.t12 t12_2
- Output: t12_2.ctid, t12_2.a, t12_2.b, t12_2.c, t12_2.e
- Filter: ((t12_2.a > 5) AND (t12_2.a = 3) AND leakproof(t12_2.a))
- -> Append
- -> Seq Scan on public.t12 t12_3
- Output: t12_3.ctid, t12_3.tableoid, t12_3.a
- Filter: (t12_3.a = 3)
- -> Seq Scan on public.t111 t111_2
- Output: t111_2.ctid, t111_2.tableoid, t111_2.a
- Filter: (t111_2.a = 3)
- -> Subquery Scan on t1_3
- Output: 100, t1_3.b, t1_3.c, t1_3.d, t1_3.e, t1_3.ctid
- Filter: snoop(t1_3.a)
- -> LockRows
- Output: t111_3.ctid, t111_3.a, t111_3.b, t111_3.c, t111_3.d, t111_3.e, t111_3.ctid, t12_4.ctid, t12_4.tableoid
- -> Nested Loop Semi Join
- Output: t111_3.ctid, t111_3.a, t111_3.b, t111_3.c, t111_3.d, t111_3.e, t111_3.ctid, t12_4.ctid, t12_4.tableoid
- -> Seq Scan on public.t111 t111_3
- Output: t111_3.ctid, t111_3.a, t111_3.b, t111_3.c, t111_3.d, t111_3.e
- Filter: ((t111_3.a > 5) AND (t111_3.a = 3) AND leakproof(t111_3.a))
- -> Append
- -> Seq Scan on public.t12 t12_4
- Output: t12_4.ctid, t12_4.tableoid, t12_4.a
- Filter: (t12_4.a = 3)
- -> Seq Scan on public.t111 t111_4
- Output: t111_4.ctid, t111_4.tableoid, t111_4.a
- Filter: (t111_4.a = 3)
-(73 rows)
-
-UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a = 3;
+ Index Cond: ((t1.a > 5) AND (t1.a < 7))
+ Filter: ((t1.a <> 6) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t1.a) AND leakproof(t1.a))
+ SubPlan 1
+ -> Append
+ -> Seq Scan on public.t12 t12_1
+ Filter: (t12_1.a = t1.a)
+ -> Seq Scan on public.t111 t111_1
+ Filter: (t111_1.a = t1.a)
+ SubPlan 2
+ -> Append
+ -> Seq Scan on public.t12 t12_2
+ Output: t12_2.a
+ -> Seq Scan on public.t111 t111_2
+ Output: t111_2.a
+ -> Index Scan using t11_a_idx on public.t11
+ Output: 100, t11.b, t11.c, t11.d, t11.ctid
+ Index Cond: ((t11.a > 5) AND (t11.a < 7))
+ Filter: ((t11.a <> 6) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t11.a) AND leakproof(t11.a))
+ -> Index Scan using t12_a_idx on public.t12
+ Output: 100, t12.b, t12.c, t12.e, t12.ctid
+ Index Cond: ((t12.a > 5) AND (t12.a < 7))
+ Filter: ((t12.a <> 6) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t12.a) AND leakproof(t12.a))
+ -> Index Scan using t111_a_idx on public.t111
+ Output: 100, t111.b, t111.c, t111.d, t111.e, t111.ctid
+ Index Cond: ((t111.a > 5) AND (t111.a < 7))
+ Filter: ((t111.a <> 6) AND (alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t111.a) AND leakproof(t111.a))
+(33 rows)
+
+UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6;
SELECT * FROM v1 WHERE a=100; -- Nothing should have been changed to 100
a | b | c | d
---+---+---+---
@@ -2205,82 +2147,42 @@ SELECT * FROM t1 WHERE a=100; -- Nothing should have been changed to 100
EXPLAIN (VERBOSE, COSTS OFF)
UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8;
- QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------
- Update on public.t1 t1_4
- Update on public.t1 t1_4
- Update on public.t11 t1
- Update on public.t12 t1
- Update on public.t111 t1
- -> Subquery Scan on t1
+ QUERY PLAN
+---------------------------------------------------------------------------------------------------------
+ Update on public.t1
+ Update on public.t1
+ Update on public.t11
+ Update on public.t12
+ Update on public.t111
+ -> Index Scan using t1_a_idx on public.t1
Output: (t1.a + 1), t1.b, t1.c, t1.ctid
- Filter: snoop(t1.a)
- -> LockRows
- Output: t1_5.a, t1_5.ctid, t1_5.b, t1_5.c, t1_5.ctid, t12.ctid, t12.tableoid
- -> Nested Loop Semi Join
- Output: t1_5.a, t1_5.ctid, t1_5.b, t1_5.c, t1_5.ctid, t12.ctid, t12.tableoid
- -> Seq Scan on public.t1 t1_5
- Output: t1_5.a, t1_5.ctid, t1_5.b, t1_5.c
- Filter: ((t1_5.a > 5) AND (t1_5.a = 8) AND leakproof(t1_5.a))
- -> Append
- -> Seq Scan on public.t12
- Output: t12.ctid, t12.tableoid, t12.a
- Filter: (t12.a = 8)
- -> Seq Scan on public.t111
- Output: t111.ctid, t111.tableoid, t111.a
- Filter: (t111.a = 8)
- -> Subquery Scan on t1_1
- Output: (t1_1.a + 1), t1_1.b, t1_1.c, t1_1.d, t1_1.ctid
- Filter: snoop(t1_1.a)
- -> LockRows
- Output: t11.a, t11.ctid, t11.b, t11.c, t11.d, t11.ctid, t12_1.ctid, t12_1.tableoid
- -> Nested Loop Semi Join
- Output: t11.a, t11.ctid, t11.b, t11.c, t11.d, t11.ctid, t12_1.ctid, t12_1.tableoid
- -> Seq Scan on public.t11
- Output: t11.a, t11.ctid, t11.b, t11.c, t11.d
- Filter: ((t11.a > 5) AND (t11.a = 8) AND leakproof(t11.a))
- -> Append
- -> Seq Scan on public.t12 t12_1
- Output: t12_1.ctid, t12_1.tableoid, t12_1.a
- Filter: (t12_1.a = 8)
- -> Seq Scan on public.t111 t111_1
- Output: t111_1.ctid, t111_1.tableoid, t111_1.a
- Filter: (t111_1.a = 8)
- -> Subquery Scan on t1_2
- Output: (t1_2.a + 1), t1_2.b, t1_2.c, t1_2.e, t1_2.ctid
- Filter: snoop(t1_2.a)
- -> LockRows
- Output: t12_2.a, t12_2.ctid, t12_2.b, t12_2.c, t12_2.e, t12_2.ctid, t12_3.ctid, t12_3.tableoid
- -> Nested Loop Semi Join
- Output: t12_2.a, t12_2.ctid, t12_2.b, t12_2.c, t12_2.e, t12_2.ctid, t12_3.ctid, t12_3.tableoid
- -> Seq Scan on public.t12 t12_2
- Output: t12_2.a, t12_2.ctid, t12_2.b, t12_2.c, t12_2.e
- Filter: ((t12_2.a > 5) AND (t12_2.a = 8) AND leakproof(t12_2.a))
- -> Append
- -> Seq Scan on public.t12 t12_3
- Output: t12_3.ctid, t12_3.tableoid, t12_3.a
- Filter: (t12_3.a = 8)
- -> Seq Scan on public.t111 t111_2
- Output: t111_2.ctid, t111_2.tableoid, t111_2.a
- Filter: (t111_2.a = 8)
- -> Subquery Scan on t1_3
- Output: (t1_3.a + 1), t1_3.b, t1_3.c, t1_3.d, t1_3.e, t1_3.ctid
- Filter: snoop(t1_3.a)
- -> LockRows
- Output: t111_3.a, t111_3.ctid, t111_3.b, t111_3.c, t111_3.d, t111_3.e, t111_3.ctid, t12_4.ctid, t12_4.tableoid
- -> Nested Loop Semi Join
- Output: t111_3.a, t111_3.ctid, t111_3.b, t111_3.c, t111_3.d, t111_3.e, t111_3.ctid, t12_4.ctid, t12_4.tableoid
- -> Seq Scan on public.t111 t111_3
- Output: t111_3.a, t111_3.ctid, t111_3.b, t111_3.c, t111_3.d, t111_3.e
- Filter: ((t111_3.a > 5) AND (t111_3.a = 8) AND leakproof(t111_3.a))
- -> Append
- -> Seq Scan on public.t12 t12_4
- Output: t12_4.ctid, t12_4.tableoid, t12_4.a
- Filter: (t12_4.a = 8)
- -> Seq Scan on public.t111 t111_4
- Output: t111_4.ctid, t111_4.tableoid, t111_4.a
- Filter: (t111_4.a = 8)
-(73 rows)
+ Index Cond: ((t1.a > 5) AND (t1.a = 8))
+ Filter: ((alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t1.a) AND leakproof(t1.a))
+ SubPlan 1
+ -> Append
+ -> Seq Scan on public.t12 t12_1
+ Filter: (t12_1.a = t1.a)
+ -> Seq Scan on public.t111 t111_1
+ Filter: (t111_1.a = t1.a)
+ SubPlan 2
+ -> Append
+ -> Seq Scan on public.t12 t12_2
+ Output: t12_2.a
+ -> Seq Scan on public.t111 t111_2
+ Output: t111_2.a
+ -> Index Scan using t11_a_idx on public.t11
+ Output: (t11.a + 1), t11.b, t11.c, t11.d, t11.ctid
+ Index Cond: ((t11.a > 5) AND (t11.a = 8))
+ Filter: ((alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t11.a) AND leakproof(t11.a))
+ -> Index Scan using t12_a_idx on public.t12
+ Output: (t12.a + 1), t12.b, t12.c, t12.e, t12.ctid
+ Index Cond: ((t12.a > 5) AND (t12.a = 8))
+ Filter: ((alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t12.a) AND leakproof(t12.a))
+ -> Index Scan using t111_a_idx on public.t111
+ Output: (t111.a + 1), t111.b, t111.c, t111.d, t111.e, t111.ctid
+ Index Cond: ((t111.a > 5) AND (t111.a = 8))
+ Filter: ((alternatives: SubPlan 1 or hashed SubPlan 2) AND snoop(t111.a) AND leakproof(t111.a))
+(33 rows)
UPDATE v1 SET a=a+1 WHERE snoop(a) AND leakproof(a) AND a = 8;
NOTICE: snooped value: 8
diff --git a/src/test/regress/sql/equivclass.sql b/src/test/regress/sql/equivclass.sql
index 17fad673e92..0e4aa0cd2c5 100644
--- a/src/test/regress/sql/equivclass.sql
+++ b/src/test/regress/sql/equivclass.sql
@@ -222,3 +222,35 @@ explain (costs off)
union all
select ff + 4 as x from ec1) as ss1
where ss1.x = ec1.f1 and ec1.ff = 42::int8;
+
+-- check effects of row-level security
+set enable_nestloop = on;
+set enable_mergejoin = off;
+
+alter table ec1 enable row level security;
+create policy p1 on ec1 using (f1 < '5'::int8alias1);
+
+create user regress_user_ectest;
+grant select on ec0 to regress_user_ectest;
+grant select on ec1 to regress_user_ectest;
+
+-- without any RLS, we'll treat {a.ff, b.ff, 43} as an EquivalenceClass
+explain (costs off)
+ select * from ec0 a, ec1 b
+ where a.ff = b.ff and a.ff = 43::bigint::int8alias1;
+
+set session authorization regress_user_ectest;
+
+-- with RLS active, the non-leakproof a.ff = 43 clause is not treated
+-- as a suitable source for an EquivalenceClass; currently, this is true
+-- even though the RLS clause has nothing to do directly with the EC
+explain (costs off)
+ select * from ec0 a, ec1 b
+ where a.ff = b.ff and a.ff = 43::bigint::int8alias1;
+
+reset session authorization;
+
+revoke select on ec0 from regress_user_ectest;
+revoke select on ec1 from regress_user_ectest;
+
+drop user regress_user_ectest;
diff --git a/src/test/regress/sql/updatable_views.sql b/src/test/regress/sql/updatable_views.sql
index bb9a3a61746..ffc64d2de9a 100644
--- a/src/test/regress/sql/updatable_views.sql
+++ b/src/test/regress/sql/updatable_views.sql
@@ -1001,8 +1001,8 @@ SELECT * FROM v1 WHERE a=3; -- should not see anything
SELECT * FROM v1 WHERE a=8;
EXPLAIN (VERBOSE, COSTS OFF)
-UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a = 3;
-UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a = 3;
+UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6;
+UPDATE v1 SET a=100 WHERE snoop(a) AND leakproof(a) AND a < 7 AND a != 6;
SELECT * FROM v1 WHERE a=100; -- Nothing should have been changed to 100
SELECT * FROM t1 WHERE a=100; -- Nothing should have been changed to 100