summaryrefslogtreecommitdiff
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.out12
-rw-r--r--src/test/regress/expected/rowsecurity.out106
-rw-r--r--src/test/regress/expected/select_views.out46
-rw-r--r--src/test/regress/expected/select_views_1.out46
-rw-r--r--src/test/regress/sql/rowsecurity.sql20
-rw-r--r--src/test/regress/sql/select_views.sql14
6 files changed, 237 insertions, 7 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 9427a6fae80..3a7a4c329f3 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
@@ -85,13 +85,11 @@ SET ROLE s1;
-- restrictive hook's policy is current_user = superuser
-- combined with AND, results in nothing being allowed
EXPLAIN (costs off) SELECT * FROM rls_test_both;
- QUERY PLAN
--------------------------------------------------------
- Subquery Scan on rls_test_both
- Filter: ("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: ((supervisor = "current_user"()) AND (username = "current_user"()))
+(2 rows)
SELECT * FROM rls_test_both;
username | supervisor | data
diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out
index 1ea65a7d8a1..ad936321749 100644
--- a/src/test/regress/expected/rowsecurity.out
+++ b/src/test/regress/expected/rowsecurity.out
@@ -1914,6 +1914,112 @@ EXPLAIN (COSTS OFF) SELECT * FROM y2 WHERE f_leak(b);
(4 rows)
--
+-- Qual push-down of leaky functions, when not referring to table
+--
+SELECT * FROM y2 WHERE f_leak('abc');
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+NOTICE: f_leak => abc
+ a | b
+----+----------------------------------
+ 0 | cfcd208495d565ef66e7dff9f98764da
+ 2 | c81e728d9d4c2f636f067f89cc14862c
+ 3 | eccbc87e4b5ce2fe28308fd9f2a7baf3
+ 4 | a87ff679a2f3e71d9181a67b7542122c
+ 6 | 1679091c5a880faf6fb5e6087eb1b2dc
+ 8 | c9f0f895fb98ab9159f51fd0297e236d
+ 9 | 45c48cce2e2d7fbdea1afc51c7c6ad26
+ 10 | d3d9446802a44259755d38e6d163e820
+ 12 | c20ad4d76fe97759aa27a0c99bff6710
+ 14 | aab3238922bcc25a6f606eb525ffdc56
+ 15 | 9bf31c7ff062936a96d3c8bd1f8f2ff3
+ 16 | c74d97b01eae257e44aa9d5bade97baf
+ 18 | 6f4922f45568161a8cdf4ad2299f6d23
+ 20 | 98f13708210194c475687be6106a3b84
+(14 rows)
+
+EXPLAIN (COSTS OFF) SELECT * FROM y2 WHERE f_leak('abc');
+ QUERY PLAN
+---------------------------------------------------------------------------------------
+ Seq Scan on y2
+ Filter: (f_leak('abc'::text) AND (((a % 4) = 0) OR ((a % 3) = 0) OR ((a % 2) = 0)))
+(2 rows)
+
+CREATE TABLE test_qual_pushdown (
+ abc text
+);
+INSERT INTO test_qual_pushdown VALUES ('abc'),('def');
+SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(abc);
+NOTICE: f_leak => abc
+NOTICE: f_leak => def
+ a | b | abc
+---+---+-----
+(0 rows)
+
+EXPLAIN (COSTS OFF) SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(abc);
+ QUERY PLAN
+-------------------------------------------------------------------------
+ Hash Join
+ Hash Cond: (test_qual_pushdown.abc = y2.b)
+ -> Seq Scan on test_qual_pushdown
+ Filter: f_leak(abc)
+ -> Hash
+ -> Seq Scan on y2
+ Filter: (((a % 4) = 0) OR ((a % 3) = 0) OR ((a % 2) = 0))
+(7 rows)
+
+SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(b);
+NOTICE: f_leak => cfcd208495d565ef66e7dff9f98764da
+NOTICE: f_leak => c81e728d9d4c2f636f067f89cc14862c
+NOTICE: f_leak => eccbc87e4b5ce2fe28308fd9f2a7baf3
+NOTICE: f_leak => a87ff679a2f3e71d9181a67b7542122c
+NOTICE: f_leak => 1679091c5a880faf6fb5e6087eb1b2dc
+NOTICE: f_leak => c9f0f895fb98ab9159f51fd0297e236d
+NOTICE: f_leak => 45c48cce2e2d7fbdea1afc51c7c6ad26
+NOTICE: f_leak => d3d9446802a44259755d38e6d163e820
+NOTICE: f_leak => c20ad4d76fe97759aa27a0c99bff6710
+NOTICE: f_leak => aab3238922bcc25a6f606eb525ffdc56
+NOTICE: f_leak => 9bf31c7ff062936a96d3c8bd1f8f2ff3
+NOTICE: f_leak => c74d97b01eae257e44aa9d5bade97baf
+NOTICE: f_leak => 6f4922f45568161a8cdf4ad2299f6d23
+NOTICE: f_leak => 98f13708210194c475687be6106a3b84
+ a | b | abc
+---+---+-----
+(0 rows)
+
+EXPLAIN (COSTS OFF) SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(b);
+ 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)
+
+DROP TABLE test_qual_pushdown;
+--
-- Plancache invalidate on user change.
--
RESET SESSION AUTHORIZATION;
diff --git a/src/test/regress/expected/select_views.out b/src/test/regress/expected/select_views.out
index 82d510de806..7f575266c1b 100644
--- a/src/test/regress/expected/select_views.out
+++ b/src/test/regress/expected/select_views.out
@@ -1349,6 +1349,52 @@ EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure WHERE f_leak(passwd);
(4 rows)
--
+-- scenario: qualifiers can be pushed down if they contain leaky functions,
+-- provided they aren't passed data from inside the view.
+--
+SELECT * FROM my_property_normal v
+ WHERE f_leak('passwd') AND f_leak(passwd);
+NOTICE: f_leak => passwd
+NOTICE: f_leak => passwd123
+NOTICE: f_leak => passwd
+NOTICE: f_leak => beafsteak
+NOTICE: f_leak => passwd
+NOTICE: f_leak => hamburger
+ cid | name | tel | passwd
+-----+---------------+------------------+-----------
+ 101 | regress_alice | +81-12-3456-7890 | passwd123
+(1 row)
+
+EXPLAIN (COSTS OFF) SELECT * FROM my_property_normal v
+ WHERE f_leak('passwd') AND f_leak(passwd);
+ QUERY PLAN
+---------------------------------------------------------------------------------------------
+ Seq Scan on customer
+ Filter: (f_leak('passwd'::text) AND f_leak(passwd) AND (name = ("current_user"())::text))
+(2 rows)
+
+SELECT * FROM my_property_secure v
+ WHERE f_leak('passwd') AND f_leak(passwd);
+NOTICE: f_leak => passwd
+NOTICE: f_leak => passwd123
+NOTICE: f_leak => passwd
+NOTICE: f_leak => passwd
+ cid | name | tel | passwd
+-----+---------------+------------------+-----------
+ 101 | regress_alice | +81-12-3456-7890 | passwd123
+(1 row)
+
+EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure v
+ WHERE f_leak('passwd') AND f_leak(passwd);
+ QUERY PLAN
+--------------------------------------------------------------------------------
+ Subquery Scan on v
+ Filter: f_leak(v.passwd)
+ -> Seq Scan on customer
+ Filter: (f_leak('passwd'::text) AND (name = ("current_user"())::text))
+(4 rows)
+
+--
-- scenario: if a qualifier references only one-side of a particular join-
-- tree, it shall be distributed to the most deep scan plan as
-- possible as we can.
diff --git a/src/test/regress/expected/select_views_1.out b/src/test/regress/expected/select_views_1.out
index ce22bfabeca..5275ef0b2de 100644
--- a/src/test/regress/expected/select_views_1.out
+++ b/src/test/regress/expected/select_views_1.out
@@ -1349,6 +1349,52 @@ EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure WHERE f_leak(passwd);
(4 rows)
--
+-- scenario: qualifiers can be pushed down if they contain leaky functions,
+-- provided they aren't passed data from inside the view.
+--
+SELECT * FROM my_property_normal v
+ WHERE f_leak('passwd') AND f_leak(passwd);
+NOTICE: f_leak => passwd
+NOTICE: f_leak => passwd123
+NOTICE: f_leak => passwd
+NOTICE: f_leak => beafsteak
+NOTICE: f_leak => passwd
+NOTICE: f_leak => hamburger
+ cid | name | tel | passwd
+-----+---------------+------------------+-----------
+ 101 | regress_alice | +81-12-3456-7890 | passwd123
+(1 row)
+
+EXPLAIN (COSTS OFF) SELECT * FROM my_property_normal v
+ WHERE f_leak('passwd') AND f_leak(passwd);
+ QUERY PLAN
+---------------------------------------------------------------------------------------------
+ Seq Scan on customer
+ Filter: (f_leak('passwd'::text) AND f_leak(passwd) AND (name = ("current_user"())::text))
+(2 rows)
+
+SELECT * FROM my_property_secure v
+ WHERE f_leak('passwd') AND f_leak(passwd);
+NOTICE: f_leak => passwd
+NOTICE: f_leak => passwd123
+NOTICE: f_leak => passwd
+NOTICE: f_leak => passwd
+ cid | name | tel | passwd
+-----+---------------+------------------+-----------
+ 101 | regress_alice | +81-12-3456-7890 | passwd123
+(1 row)
+
+EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure v
+ WHERE f_leak('passwd') AND f_leak(passwd);
+ QUERY PLAN
+--------------------------------------------------------------------------------
+ Subquery Scan on v
+ Filter: f_leak(v.passwd)
+ -> Seq Scan on customer
+ Filter: (f_leak('passwd'::text) AND (name = ("current_user"())::text))
+(4 rows)
+
+--
-- scenario: if a qualifier references only one-side of a particular join-
-- tree, it shall be distributed to the most deep scan plan as
-- possible as we can.
diff --git a/src/test/regress/sql/rowsecurity.sql b/src/test/regress/sql/rowsecurity.sql
index f38b4438fdf..7d12dd00a2f 100644
--- a/src/test/regress/sql/rowsecurity.sql
+++ b/src/test/regress/sql/rowsecurity.sql
@@ -680,6 +680,26 @@ SELECT * FROM y2 WHERE f_leak(b);
EXPLAIN (COSTS OFF) SELECT * FROM y2 WHERE f_leak(b);
--
+-- Qual push-down of leaky functions, when not referring to table
+--
+SELECT * FROM y2 WHERE f_leak('abc');
+EXPLAIN (COSTS OFF) SELECT * FROM y2 WHERE f_leak('abc');
+
+CREATE TABLE test_qual_pushdown (
+ abc text
+);
+
+INSERT INTO test_qual_pushdown VALUES ('abc'),('def');
+
+SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(abc);
+EXPLAIN (COSTS OFF) SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(abc);
+
+SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(b);
+EXPLAIN (COSTS OFF) SELECT * FROM y2 JOIN test_qual_pushdown ON (b = abc) WHERE f_leak(b);
+
+DROP TABLE test_qual_pushdown;
+
+--
-- Plancache invalidate on user change.
--
RESET SESSION AUTHORIZATION;
diff --git a/src/test/regress/sql/select_views.sql b/src/test/regress/sql/select_views.sql
index da356237eba..3b74ab9d80f 100644
--- a/src/test/regress/sql/select_views.sql
+++ b/src/test/regress/sql/select_views.sql
@@ -96,6 +96,20 @@ SELECT * FROM my_property_secure WHERE f_leak(passwd);
EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure WHERE f_leak(passwd);
--
+-- scenario: qualifiers can be pushed down if they contain leaky functions,
+-- provided they aren't passed data from inside the view.
+--
+SELECT * FROM my_property_normal v
+ WHERE f_leak('passwd') AND f_leak(passwd);
+EXPLAIN (COSTS OFF) SELECT * FROM my_property_normal v
+ WHERE f_leak('passwd') AND f_leak(passwd);
+
+SELECT * FROM my_property_secure v
+ WHERE f_leak('passwd') AND f_leak(passwd);
+EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure v
+ WHERE f_leak('passwd') AND f_leak(passwd);
+
+--
-- scenario: if a qualifier references only one-side of a particular join-
-- tree, it shall be distributed to the most deep scan plan as
-- possible as we can.