From 383f11f674479e78b1e39487dc764704bafa4732 Mon Sep 17 00:00:00 2001
From: Andreas Lind <andreaslindpetersen@gmail.com>
Date: Fri, 18 Apr 2025 15:23:20 +0200
Subject: [PATCH v1 4/4] Add bypassleakproof test

---
 src/test/regress/expected/bypassleakproof.out | 55 +++++++++++++++++++
 src/test/regress/parallel_schedule            |  2 +-
 src/test/regress/sql/bypassleakproof.sql      | 52 ++++++++++++++++++
 3 files changed, 108 insertions(+), 1 deletion(-)
 create mode 100644 src/test/regress/expected/bypassleakproof.out
 create mode 100644 src/test/regress/sql/bypassleakproof.sql

diff --git a/src/test/regress/expected/bypassleakproof.out b/src/test/regress/expected/bypassleakproof.out
new file mode 100644
index 00000000000..93defc04636
--- /dev/null
+++ b/src/test/regress/expected/bypassleakproof.out
@@ -0,0 +1,55 @@
+-- BYPASSLEAKPROOF flag
+CREATE TYPE foo_or_bar_enum AS ENUM('foo', 'bar');
+CREATE TABLE base_tbl (tenant_id int, foo_or_bar foo_or_bar_enum);
+ALTER TABLE base_tbl ENABLE ROW LEVEL SECURITY;
+INSERT INTO base_tbl(tenant_id, foo_or_bar)
+SELECT 1, 'foo' FROM generate_series(1, 1000) AS n;
+INSERT INTO base_tbl(tenant_id, foo_or_bar)
+SELECT 2, 'foo' FROM generate_series(1, 1000) AS n;
+INSERT INTO base_tbl(tenant_id, foo_or_bar)
+VALUES(2, 'bar');
+CREATE FUNCTION is_bar(val foo_or_bar_enum) RETURNS boolean AS $$ SELECT val = 'bar'; $$ LANGUAGE SQL IMMUTABLE;
+CREATE INDEX ON base_tbl(tenant_id, (is_bar(foo_or_bar)));
+ANALYZE base_tbl;
+CREATE USER regress_bypassleakproof_nobypassleakproof_user NOBYPASSLEAKPROOF;
+CREATE USER regress_bypassleakproof_bypassleakproof_user BYPASSLEAKPROOF;
+GRANT SELECT ON base_tbl TO regress_bypassleakproof_nobypassleakproof_user;
+GRANT SELECT ON base_tbl TO regress_bypassleakproof_bypassleakproof_user;
+-- Check that the flag gets set correctly:
+SELECT rolname, rolbypassleakproof FROM pg_catalog.pg_roles
+WHERE rolname LIKE 'regress_bypassleakproof_%'
+ORDER BY rolname;
+                    rolname                     | rolbypassleakproof 
+------------------------------------------------+--------------------
+ regress_bypassleakproof_bypassleakproof_user   | t
+ regress_bypassleakproof_nobypassleakproof_user | f
+(2 rows)
+
+CREATE POLICY only_tenant_2 ON base_tbl FOR ALL
+TO regress_bypassleakproof_nobypassleakproof_user, regress_bypassleakproof_bypassleakproof_user
+USING (tenant_id = 2);
+SET SESSION AUTHORIZATION regress_bypassleakproof_nobypassleakproof_user;
+EXPLAIN (verbose, costs off) SELECT * FROM base_tbl WHERE is_bar(foo_or_bar);
+                                       QUERY PLAN                                        
+-----------------------------------------------------------------------------------------
+ Seq Scan on public.base_tbl
+   Output: tenant_id, foo_or_bar
+   Filter: ((base_tbl.tenant_id = 2) AND (base_tbl.foo_or_bar = 'bar'::foo_or_bar_enum))
+(3 rows)
+
+RESET SESSION AUTHORIZATION;
+SET SESSION AUTHORIZATION regress_bypassleakproof_bypassleakproof_user;
+EXPLAIN (verbose, costs off) SELECT * FROM base_tbl WHERE is_bar(foo_or_bar);
+                                              QUERY PLAN                                              
+------------------------------------------------------------------------------------------------------
+ Index Scan using base_tbl_tenant_id_is_bar_idx on public.base_tbl
+   Output: tenant_id, foo_or_bar
+   Index Cond: ((base_tbl.tenant_id = 2) AND ((base_tbl.foo_or_bar = 'bar'::foo_or_bar_enum) = true))
+(3 rows)
+
+RESET SESSION AUTHORIZATION;
+DROP TABLE base_tbl CASCADE;
+DROP USER regress_bypassleakproof_nobypassleakproof_user;
+DROP USER regress_bypassleakproof_bypassleakproof_user;
+DROP FUNCTION is_bar;
+DROP TYPE foo_or_bar_enum;
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 0f38caa0d24..12431a92096 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -43,7 +43,7 @@ test: copy copyselect copydml copyencoding insert insert_conflict
 # Note: many of the tests in later groups depend on create_index
 # ----------
 test: create_function_c create_misc create_operator create_procedure create_table create_type create_schema
-test: create_index create_index_spgist create_view index_including index_including_gist
+test: create_index create_index_spgist create_view index_including index_including_gist bypassleakproof
 
 # ----------
 # Another group of parallel tests
diff --git a/src/test/regress/sql/bypassleakproof.sql b/src/test/regress/sql/bypassleakproof.sql
new file mode 100644
index 00000000000..2ee42311e91
--- /dev/null
+++ b/src/test/regress/sql/bypassleakproof.sql
@@ -0,0 +1,52 @@
+-- BYPASSLEAKPROOF flag
+
+CREATE TYPE foo_or_bar_enum AS ENUM('foo', 'bar');
+
+CREATE TABLE base_tbl (tenant_id int, foo_or_bar foo_or_bar_enum);
+ALTER TABLE base_tbl ENABLE ROW LEVEL SECURITY;
+
+INSERT INTO base_tbl(tenant_id, foo_or_bar)
+SELECT 1, 'foo' FROM generate_series(1, 1000) AS n;
+INSERT INTO base_tbl(tenant_id, foo_or_bar)
+SELECT 2, 'foo' FROM generate_series(1, 1000) AS n;
+INSERT INTO base_tbl(tenant_id, foo_or_bar)
+VALUES(2, 'bar');
+
+CREATE FUNCTION is_bar(val foo_or_bar_enum) RETURNS boolean AS $$ SELECT val = 'bar'; $$ LANGUAGE SQL IMMUTABLE;
+
+CREATE INDEX ON base_tbl(tenant_id, (is_bar(foo_or_bar)));
+
+ANALYZE base_tbl;
+
+CREATE USER regress_bypassleakproof_nobypassleakproof_user NOBYPASSLEAKPROOF;
+CREATE USER regress_bypassleakproof_bypassleakproof_user BYPASSLEAKPROOF;
+GRANT SELECT ON base_tbl TO regress_bypassleakproof_nobypassleakproof_user;
+GRANT SELECT ON base_tbl TO regress_bypassleakproof_bypassleakproof_user;
+
+-- Check that the flag gets set correctly:
+SELECT rolname, rolbypassleakproof FROM pg_catalog.pg_roles
+WHERE rolname LIKE 'regress_bypassleakproof_%'
+ORDER BY rolname;
+
+CREATE POLICY only_tenant_2 ON base_tbl FOR ALL
+TO regress_bypassleakproof_nobypassleakproof_user, regress_bypassleakproof_bypassleakproof_user
+USING (tenant_id = 2);
+
+SET SESSION AUTHORIZATION regress_bypassleakproof_nobypassleakproof_user;
+
+EXPLAIN (verbose, costs off) SELECT * FROM base_tbl WHERE is_bar(foo_or_bar);
+
+RESET SESSION AUTHORIZATION;
+
+SET SESSION AUTHORIZATION regress_bypassleakproof_bypassleakproof_user;
+
+EXPLAIN (verbose, costs off) SELECT * FROM base_tbl WHERE is_bar(foo_or_bar);
+
+RESET SESSION AUTHORIZATION;
+
+DROP TABLE base_tbl CASCADE;
+
+DROP USER regress_bypassleakproof_nobypassleakproof_user;
+DROP USER regress_bypassleakproof_bypassleakproof_user;
+DROP FUNCTION is_bar;
+DROP TYPE foo_or_bar_enum;
-- 
2.39.2

