@@ -5728,3 +5728,206 @@ statement ok
57285728SET allow_view_with_security_invoker_clause = off
57295729
57305730subtest end
5731+
5732+ subtest row_security_off
5733+
5734+ statement ok
5735+ CREATE USER alice;
5736+
5737+ statement ok
5738+ CREATE TABLE accounts (
5739+ id INT PRIMARY KEY,
5740+ owner TEXT,
5741+ balance INT
5742+ );
5743+
5744+ statement ok
5745+ INSERT INTO accounts VALUES
5746+ (1, 'alice', 100),
5747+ (2, 'bob', 200);
5748+
5749+ statement ok
5750+ ALTER TABLE accounts ENABLE ROW LEVEL SECURITY;
5751+
5752+ statement ok
5753+ GRANT ALL ON accounts TO alice;
5754+
5755+ statement ok
5756+ SET ROLE alice;
5757+
5758+ # RLS enabled but no policies (deny all) - row_security='off' should fail.
5759+ query ITI
5760+ SELECT * FROM accounts;
5761+ ----
5762+
5763+ statement ok
5764+ SET SESSION row_security = 'off';
5765+
5766+ statement error pgcode 42501 pq: query would be affected by row-level security policy for table "accounts"
5767+ SELECT * FROM accounts;
5768+
5769+ statement ok
5770+ RESET row_security;
5771+
5772+ statement ok
5773+ SET ROLE root;
5774+
5775+ # Add policy and test with alice as non-owner.
5776+ statement ok
5777+ CREATE POLICY user_is_owner ON accounts
5778+ USING (owner = current_user());
5779+
5780+ statement ok
5781+ SET ROLE alice;
5782+
5783+ query ITI
5784+ SELECT * FROM accounts;
5785+ ----
5786+ 1 alice 100
5787+
5788+ statement ok
5789+ SET SESSION row_security = 'off';
5790+
5791+ statement error pgcode 42501 pq: query would be affected by row-level security policy for table "accounts"
5792+ SELECT * FROM accounts;
5793+
5794+ statement ok
5795+ RESET row_security;
5796+
5797+ # Test INSERT and UPDATE.
5798+ statement ok
5799+ INSERT INTO accounts VALUES (3, 'alice', 300);
5800+
5801+ statement ok
5802+ UPDATE accounts SET balance = balance + 50 WHERE id = 3;
5803+
5804+ statement ok
5805+ SET SESSION row_security = 'off';
5806+
5807+ statement error pgcode 42501 pq: query would be affected by row-level security policy for table "accounts"
5808+ INSERT INTO accounts VALUES (5, 'alice', 500);
5809+
5810+ statement error pgcode 42501 pq: query would be affected by row-level security policy for table "accounts"
5811+ UPDATE accounts SET balance = balance + 50 WHERE id = 3;
5812+
5813+ statement ok
5814+ RESET row_security;
5815+
5816+ # Test DELETE and UPSERT.
5817+ statement ok
5818+ DELETE FROM accounts WHERE id = 1;
5819+
5820+ statement ok
5821+ UPSERT INTO accounts VALUES (3, 'alice', 400);
5822+
5823+ statement ok
5824+ SET SESSION row_security = 'off';
5825+
5826+ statement error pgcode 42501 pq: query would be affected by row-level security policy for table "accounts"
5827+ DELETE FROM accounts WHERE id = 3;
5828+
5829+ statement error pgcode 42501 pq: query would be affected by row-level security policy for table "accounts"
5830+ UPSERT INTO accounts VALUES (6, 'alice', 600);
5831+
5832+ statement ok
5833+ RESET row_security;
5834+
5835+ statement ok
5836+ SET ROLE root;
5837+
5838+ # Table owner bypasses RLS without FORCE.
5839+ statement ok
5840+ ALTER TABLE accounts OWNER TO alice;
5841+
5842+ statement ok
5843+ SET ROLE alice;
5844+
5845+ statement ok
5846+ DROP POLICY user_is_owner ON accounts;
5847+
5848+ statement ok
5849+ CREATE POLICY deny_all ON accounts USING (false);
5850+
5851+ query ITI rowsort
5852+ SELECT * FROM accounts;
5853+ ----
5854+ 2 bob 200
5855+ 3 alice 400
5856+
5857+ statement ok
5858+ SET SESSION row_security = 'off';
5859+
5860+ query ITI rowsort
5861+ SELECT * FROM accounts;
5862+ ----
5863+ 2 bob 200
5864+ 3 alice 400
5865+
5866+ statement ok
5867+ RESET row_security;
5868+
5869+ # With FORCE, table owner is restricted.
5870+ statement ok
5871+ ALTER TABLE accounts FORCE ROW LEVEL SECURITY;
5872+
5873+ query ITI
5874+ SELECT * FROM accounts;
5875+ ----
5876+
5877+ statement ok
5878+ SET SESSION row_security = 'off';
5879+
5880+ statement error pgcode 42501 pq: query would be affected by row-level security policy for table "accounts"
5881+ SELECT * FROM accounts;
5882+
5883+ statement ok
5884+ RESET row_security;
5885+
5886+ statement ok
5887+ SET ROLE root;
5888+
5889+ # Verify setting doesn't apply to admin.
5890+ statement ok
5891+ SET SESSION row_security = 'off';
5892+
5893+ query ITI rowsort
5894+ SELECT * FROM accounts;
5895+ ----
5896+ 2 bob 200
5897+ 3 alice 400
5898+
5899+ statement ok
5900+ RESET row_security;
5901+
5902+ # Non-RLS table allows row_security='off'.
5903+ statement ok
5904+ CREATE TABLE non_rls (id INT PRIMARY KEY);
5905+
5906+ statement ok
5907+ INSERT INTO non_rls VALUES (1), (2);
5908+
5909+ statement ok
5910+ GRANT ALL ON non_rls TO alice;
5911+
5912+ statement ok
5913+ SET ROLE alice;
5914+
5915+ statement ok
5916+ SET SESSION row_security = 'off';
5917+
5918+ query I rowsort
5919+ SELECT * FROM non_rls;
5920+ ----
5921+ 1
5922+ 2
5923+
5924+ statement ok
5925+ SET ROLE root;
5926+
5927+ statement ok
5928+ DROP TABLE accounts, non_rls;
5929+
5930+ statement ok
5931+ DROP USER alice;
5932+
5933+ subtest end
0 commit comments