@@ -2729,6 +2729,113 @@ COPY copy_t FROM STDIN; --fail - permission denied.
2729
2729
ERROR: permission denied for relation copy_t
2730
2730
RESET SESSION AUTHORIZATION;
2731
2731
DROP TABLE copy_t;
2732
+ -- Check WHERE CURRENT OF
2733
+ SET SESSION AUTHORIZATION rls_regress_user0;
2734
+ CREATE TABLE current_check (currentid int, payload text, rlsuser text);
2735
+ GRANT ALL ON current_check TO PUBLIC;
2736
+ INSERT INTO current_check VALUES
2737
+ (1, 'abc', 'rls_regress_user1'),
2738
+ (2, 'bcd', 'rls_regress_user1'),
2739
+ (3, 'cde', 'rls_regress_user1'),
2740
+ (4, 'def', 'rls_regress_user1');
2741
+ CREATE POLICY p1 ON current_check FOR SELECT USING (currentid % 2 = 0);
2742
+ CREATE POLICY p2 ON current_check FOR DELETE USING (currentid = 4 AND rlsuser = current_user);
2743
+ CREATE POLICY p3 ON current_check FOR UPDATE USING (currentid = 4) WITH CHECK (rlsuser = current_user);
2744
+ ALTER TABLE current_check ENABLE ROW LEVEL SECURITY;
2745
+ SET SESSION AUTHORIZATION rls_regress_user1;
2746
+ -- Can SELECT even rows
2747
+ SELECT * FROM current_check;
2748
+ currentid | payload | rlsuser
2749
+ -----------+---------+-------------------
2750
+ 2 | bcd | rls_regress_user1
2751
+ 4 | def | rls_regress_user1
2752
+ (2 rows)
2753
+
2754
+ -- Cannot UPDATE row 2
2755
+ UPDATE current_check SET payload = payload || '_new' WHERE currentid = 2 RETURNING *;
2756
+ currentid | payload | rlsuser
2757
+ -----------+---------+---------
2758
+ (0 rows)
2759
+
2760
+ BEGIN;
2761
+ DECLARE current_check_cursor SCROLL CURSOR FOR SELECT * FROM current_check;
2762
+ -- Returns rows that can be seen according to SELECT policy, like plain SELECT
2763
+ -- above (even rows)
2764
+ FETCH ABSOLUTE 1 FROM current_check_cursor;
2765
+ currentid | payload | rlsuser
2766
+ -----------+---------+-------------------
2767
+ 2 | bcd | rls_regress_user1
2768
+ (1 row)
2769
+
2770
+ -- Still cannot UPDATE row 2 through cursor
2771
+ UPDATE current_check SET payload = payload || '_new' WHERE CURRENT OF current_check_cursor RETURNING *;
2772
+ currentid | payload | rlsuser
2773
+ -----------+---------+---------
2774
+ (0 rows)
2775
+
2776
+ -- Can update row 4 through cursor, which is the next visible row
2777
+ FETCH RELATIVE 1 FROM current_check_cursor;
2778
+ currentid | payload | rlsuser
2779
+ -----------+---------+-------------------
2780
+ 4 | def | rls_regress_user1
2781
+ (1 row)
2782
+
2783
+ UPDATE current_check SET payload = payload || '_new' WHERE CURRENT OF current_check_cursor RETURNING *;
2784
+ currentid | payload | rlsuser
2785
+ -----------+---------+-------------------
2786
+ 4 | def_new | rls_regress_user1
2787
+ (1 row)
2788
+
2789
+ SELECT * FROM current_check;
2790
+ currentid | payload | rlsuser
2791
+ -----------+---------+-------------------
2792
+ 2 | bcd | rls_regress_user1
2793
+ 4 | def_new | rls_regress_user1
2794
+ (2 rows)
2795
+
2796
+ -- Plan should be a subquery TID scan
2797
+ EXPLAIN (COSTS OFF) UPDATE current_check SET payload = payload WHERE CURRENT OF current_check_cursor;
2798
+ QUERY PLAN
2799
+ ---------------------------------------------------------------
2800
+ Update on current_check current_check_1
2801
+ -> Subquery Scan on current_check
2802
+ -> LockRows
2803
+ -> Tid Scan on current_check current_check_2
2804
+ TID Cond: CURRENT OF current_check_cursor
2805
+ Filter: (currentid = 4)
2806
+ (6 rows)
2807
+
2808
+ -- Similarly can only delete row 4
2809
+ FETCH ABSOLUTE 1 FROM current_check_cursor;
2810
+ currentid | payload | rlsuser
2811
+ -----------+---------+-------------------
2812
+ 2 | bcd | rls_regress_user1
2813
+ (1 row)
2814
+
2815
+ DELETE FROM current_check WHERE CURRENT OF current_check_cursor RETURNING *;
2816
+ currentid | payload | rlsuser
2817
+ -----------+---------+---------
2818
+ (0 rows)
2819
+
2820
+ FETCH RELATIVE 1 FROM current_check_cursor;
2821
+ currentid | payload | rlsuser
2822
+ -----------+---------+-------------------
2823
+ 4 | def | rls_regress_user1
2824
+ (1 row)
2825
+
2826
+ DELETE FROM current_check WHERE CURRENT OF current_check_cursor RETURNING *;
2827
+ currentid | payload | rlsuser
2828
+ -----------+---------+-------------------
2829
+ 4 | def_new | rls_regress_user1
2830
+ (1 row)
2831
+
2832
+ SELECT * FROM current_check;
2833
+ currentid | payload | rlsuser
2834
+ -----------+---------+-------------------
2835
+ 2 | bcd | rls_regress_user1
2836
+ (1 row)
2837
+
2838
+ COMMIT;
2732
2839
--
2733
2840
-- Collation support
2734
2841
--
0 commit comments