summaryrefslogtreecommitdiff
path: root/src/test/regress/expected
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/regress/expected')
-rw-r--r--src/test/regress/expected/foreign_key.out51
-rw-r--r--src/test/regress/expected/rowsecurity.out259
2 files changed, 310 insertions, 0 deletions
diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.out
index dc541d61adf..7f9e0ebb82d 100644
--- a/src/test/regress/expected/foreign_key.out
+++ b/src/test/regress/expected/foreign_key.out
@@ -3406,3 +3406,54 @@ SET client_min_messages TO warning;
DROP SCHEMA fkpart12 CASCADE;
RESET client_min_messages;
RESET search_path;
+-- Exercise the column mapping code with foreign keys. In this test we'll
+-- create a partitioned table which has a partition with a dropped column and
+-- check to ensure that an UPDATE cascades the changes correctly to the
+-- partitioned table.
+CREATE SCHEMA fkpart13;
+SET search_path TO fkpart13;
+CREATE TABLE fkpart13_t1 (a int PRIMARY KEY);
+CREATE TABLE fkpart13_t2 (
+ part_id int PRIMARY KEY,
+ column_to_drop int,
+ FOREIGN KEY (part_id) REFERENCES fkpart13_t1 ON UPDATE CASCADE ON DELETE CASCADE
+) PARTITION BY LIST (part_id);
+CREATE TABLE fkpart13_t2_p1 PARTITION OF fkpart13_t2 FOR VALUES IN (1);
+-- drop the column
+ALTER TABLE fkpart13_t2 DROP COLUMN column_to_drop;
+-- create a new partition without the dropped column
+CREATE TABLE fkpart13_t2_p2 PARTITION OF fkpart13_t2 FOR VALUES IN (2);
+CREATE TABLE fkpart13_t3 (
+ a int NOT NULL,
+ FOREIGN KEY (a)
+ REFERENCES fkpart13_t2
+ ON UPDATE CASCADE ON DELETE CASCADE
+);
+INSERT INTO fkpart13_t1 (a) VALUES (1);
+INSERT INTO fkpart13_t2 (part_id) VALUES (1);
+INSERT INTO fkpart13_t3 (a) VALUES (1);
+-- Test a cascading update works correctly with with the dropped column
+UPDATE fkpart13_t1 SET a = 2 WHERE a = 1;
+SELECT tableoid::regclass,* FROM fkpart13_t2;
+ tableoid | part_id
+----------------+---------
+ fkpart13_t2_p2 | 2
+(1 row)
+
+SELECT tableoid::regclass,* FROM fkpart13_t3;
+ tableoid | a
+-------------+---
+ fkpart13_t3 | 2
+(1 row)
+
+-- Exercise code in ExecGetTriggerResultRel() as there's been previous issues
+-- with ResultRelInfos being returned with the incorrect ri_RootResultRelInfo
+WITH cte AS (
+ UPDATE fkpart13_t2_p1 SET part_id = part_id
+) UPDATE fkpart13_t1 SET a = 2 WHERE a = 1;
+DROP SCHEMA fkpart13 CASCADE;
+NOTICE: drop cascades to 3 other objects
+DETAIL: drop cascades to table fkpart13_t1
+drop cascades to table fkpart13_t2
+drop cascades to table fkpart13_t3
+RESET search_path;
diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out
index 42b78a24603..c958ef4d70a 100644
--- a/src/test/regress/expected/rowsecurity.out
+++ b/src/test/regress/expected/rowsecurity.out
@@ -31,6 +31,265 @@ CREATE OR REPLACE FUNCTION f_leak(text) RETURNS bool
COST 0.0000001 LANGUAGE plpgsql
AS 'BEGIN RAISE NOTICE ''f_leak => %'', $1; RETURN true; END';
GRANT EXECUTE ON FUNCTION f_leak(text) TO public;
+--
+-- Test policies applied by command type
+--
+SET SESSION AUTHORIZATION regress_rls_alice;
+-- setup source table (for MERGE operations)
+CREATE TABLE rls_test_src (a int PRIMARY KEY, b text);
+ALTER TABLE rls_test_src ENABLE ROW LEVEL SECURITY;
+GRANT SELECT, UPDATE ON rls_test_src TO public;
+INSERT INTO rls_test_src VALUES (1, 'src a');
+-- setup target table with a column set by a BEFORE ROW trigger
+-- (policies should always see values set by the trigger)
+CREATE TABLE rls_test_tgt (a int PRIMARY KEY, b text, c text);
+ALTER TABLE rls_test_tgt ENABLE ROW LEVEL SECURITY;
+GRANT SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON rls_test_tgt TO public;
+CREATE FUNCTION rls_test_tgt_set_c() RETURNS trigger AS
+ $$ BEGIN new.c = upper(new.b); RETURN new; END; $$
+ LANGUAGE plpgsql;
+CREATE TRIGGER rls_test_tgt_set_c BEFORE INSERT OR UPDATE ON rls_test_tgt
+ FOR EACH ROW EXECUTE FUNCTION rls_test_tgt_set_c();
+-- setup a complete set of policies that emit NOTICE messages when applied
+CREATE FUNCTION rls_test_policy_fn(text, record) RETURNS bool AS
+ $$ BEGIN RAISE NOTICE '%.%', $1, $2; RETURN true; END; $$
+ LANGUAGE plpgsql;
+CREATE POLICY sel_pol ON rls_test_src FOR SELECT
+ USING (rls_test_policy_fn('SELECT USING on rls_test_src', rls_test_src));
+CREATE POLICY upd_pol ON rls_test_src FOR UPDATE
+ USING (rls_test_policy_fn('UPDATE USING on rls_test_src', rls_test_src))
+ WITH CHECK (rls_test_policy_fn('UPDATE CHECK on rls_test_src', rls_test_src));
+CREATE POLICY sel_pol ON rls_test_tgt FOR SELECT
+ USING (rls_test_policy_fn('SELECT USING on rls_test_tgt', rls_test_tgt));
+CREATE POLICY ins_pol ON rls_test_tgt FOR INSERT
+ WITH CHECK (rls_test_policy_fn('INSERT CHECK on rls_test_tgt', rls_test_tgt));
+CREATE POLICY upd_pol ON rls_test_tgt FOR UPDATE
+ USING (rls_test_policy_fn('UPDATE USING on rls_test_tgt', rls_test_tgt))
+ WITH CHECK (rls_test_policy_fn('UPDATE CHECK on rls_test_tgt', rls_test_tgt));
+CREATE POLICY del_pol ON rls_test_tgt FOR DELETE
+ USING (rls_test_policy_fn('DELETE USING on rls_test_tgt', rls_test_tgt));
+-- test policies applied to regress_rls_bob
+SET SESSION AUTHORIZATION regress_rls_bob;
+-- SELECT, COPY ... TO, and TABLE should only apply SELECT USING policy clause
+SELECT * FROM rls_test_src;
+NOTICE: SELECT USING on rls_test_src.(1,"src a")
+ a | b
+---+-------
+ 1 | src a
+(1 row)
+
+COPY rls_test_src TO stdout;
+NOTICE: SELECT USING on rls_test_src.(1,"src a")
+1 src a
+TABLE rls_test_src;
+NOTICE: SELECT USING on rls_test_src.(1,"src a")
+ a | b
+---+-------
+ 1 | src a
+(1 row)
+
+-- SELECT ... FOR UPDATE/SHARE should also apply UPDATE USING policy clause
+SELECT * FROM rls_test_src FOR UPDATE;
+NOTICE: UPDATE USING on rls_test_src.(1,"src a")
+NOTICE: SELECT USING on rls_test_src.(1,"src a")
+ a | b
+---+-------
+ 1 | src a
+(1 row)
+
+SELECT * FROM rls_test_src FOR NO KEY UPDATE;
+NOTICE: UPDATE USING on rls_test_src.(1,"src a")
+NOTICE: SELECT USING on rls_test_src.(1,"src a")
+ a | b
+---+-------
+ 1 | src a
+(1 row)
+
+SELECT * FROM rls_test_src FOR SHARE;
+NOTICE: UPDATE USING on rls_test_src.(1,"src a")
+NOTICE: SELECT USING on rls_test_src.(1,"src a")
+ a | b
+---+-------
+ 1 | src a
+(1 row)
+
+SELECT * FROM rls_test_src FOR KEY SHARE;
+NOTICE: UPDATE USING on rls_test_src.(1,"src a")
+NOTICE: SELECT USING on rls_test_src.(1,"src a")
+ a | b
+---+-------
+ 1 | src a
+(1 row)
+
+-- plain INSERT should apply INSERT CHECK policy clause
+INSERT INTO rls_test_tgt VALUES (1, 'tgt a');
+NOTICE: INSERT CHECK on rls_test_tgt.(1,"tgt a","TGT A")
+-- INSERT ... RETURNING should also apply SELECT USING policy clause
+TRUNCATE rls_test_tgt;
+INSERT INTO rls_test_tgt VALUES (1, 'tgt a') RETURNING *;
+NOTICE: INSERT CHECK on rls_test_tgt.(1,"tgt a","TGT A")
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt a","TGT A")
+ a | b | c
+---+-------+-------
+ 1 | tgt a | TGT A
+(1 row)
+
+-- UPDATE without WHERE or RETURNING should only apply UPDATE policy clauses
+UPDATE rls_test_tgt SET b = 'tgt b';
+NOTICE: UPDATE USING on rls_test_tgt.(1,"tgt a","TGT A")
+NOTICE: UPDATE CHECK on rls_test_tgt.(1,"tgt b","TGT B")
+-- UPDATE with WHERE or RETURNING should also apply SELECT USING policy clause
+-- (to both old and new values)
+UPDATE rls_test_tgt SET b = 'tgt c' WHERE a = 1;
+NOTICE: UPDATE USING on rls_test_tgt.(1,"tgt b","TGT B")
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt b","TGT B")
+NOTICE: UPDATE CHECK on rls_test_tgt.(1,"tgt c","TGT C")
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt c","TGT C")
+UPDATE rls_test_tgt SET b = 'tgt d' RETURNING *;
+NOTICE: UPDATE USING on rls_test_tgt.(1,"tgt c","TGT C")
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt c","TGT C")
+NOTICE: UPDATE CHECK on rls_test_tgt.(1,"tgt d","TGT D")
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt d","TGT D")
+ a | b | c
+---+-------+-------
+ 1 | tgt d | TGT D
+(1 row)
+
+-- DELETE without WHERE or RETURNING should only apply DELETE USING policy clause
+BEGIN; DELETE FROM rls_test_tgt; ROLLBACK;
+NOTICE: DELETE USING on rls_test_tgt.(1,"tgt d","TGT D")
+-- DELETE with WHERE or RETURNING should also apply SELECT USING policy clause
+BEGIN; DELETE FROM rls_test_tgt WHERE a = 1; ROLLBACK;
+NOTICE: DELETE USING on rls_test_tgt.(1,"tgt d","TGT D")
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt d","TGT D")
+DELETE FROM rls_test_tgt RETURNING *;
+NOTICE: DELETE USING on rls_test_tgt.(1,"tgt d","TGT D")
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt d","TGT D")
+ a | b | c
+---+-------+-------
+ 1 | tgt d | TGT D
+(1 row)
+
+-- INSERT ... ON CONFLICT DO NOTHING should apply INSERT CHECK and SELECT USING
+-- policy clauses (to new value, whether it conflicts or not)
+INSERT INTO rls_test_tgt VALUES (1, 'tgt a') ON CONFLICT (a) DO NOTHING;
+NOTICE: INSERT CHECK on rls_test_tgt.(1,"tgt a","TGT A")
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt a","TGT A")
+INSERT INTO rls_test_tgt VALUES (1, 'tgt b') ON CONFLICT (a) DO NOTHING;
+NOTICE: INSERT CHECK on rls_test_tgt.(1,"tgt b","TGT B")
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt b","TGT B")
+-- INSERT ... ON CONFLICT DO NOTHING without an arbiter clause only applies
+-- INSERT CHECK policy clause
+INSERT INTO rls_test_tgt VALUES (1, 'tgt b') ON CONFLICT DO NOTHING;
+NOTICE: INSERT CHECK on rls_test_tgt.(1,"tgt b","TGT B")
+-- INSERT ... ON CONFLICT DO UPDATE should apply INSERT CHECK and SELECT USING
+-- policy clauses to values proposed for insert. In the event of a conflict it
+-- should also apply UPDATE and SELECT policies to old and new values, like
+-- UPDATE ... WHERE.
+BEGIN;
+INSERT INTO rls_test_tgt VALUES (2, 'tgt a') ON CONFLICT (a) DO UPDATE SET b = 'tgt b';
+NOTICE: INSERT CHECK on rls_test_tgt.(2,"tgt a","TGT A")
+NOTICE: SELECT USING on rls_test_tgt.(2,"tgt a","TGT A")
+INSERT INTO rls_test_tgt VALUES (2, 'tgt c') ON CONFLICT (a) DO UPDATE SET b = 'tgt d';
+NOTICE: INSERT CHECK on rls_test_tgt.(2,"tgt c","TGT C")
+NOTICE: SELECT USING on rls_test_tgt.(2,"tgt c","TGT C")
+NOTICE: UPDATE USING on rls_test_tgt.(2,"tgt a","TGT A")
+NOTICE: SELECT USING on rls_test_tgt.(2,"tgt a","TGT A")
+NOTICE: UPDATE CHECK on rls_test_tgt.(2,"tgt d","TGT D")
+NOTICE: SELECT USING on rls_test_tgt.(2,"tgt d","TGT D")
+INSERT INTO rls_test_tgt VALUES (3, 'tgt a') ON CONFLICT (a) DO UPDATE SET b = 'tgt b' RETURNING *;
+NOTICE: INSERT CHECK on rls_test_tgt.(3,"tgt a","TGT A")
+NOTICE: SELECT USING on rls_test_tgt.(3,"tgt a","TGT A")
+ a | b | c
+---+-------+-------
+ 3 | tgt a | TGT A
+(1 row)
+
+INSERT INTO rls_test_tgt VALUES (3, 'tgt c') ON CONFLICT (a) DO UPDATE SET b = 'tgt d' RETURNING *;
+NOTICE: INSERT CHECK on rls_test_tgt.(3,"tgt c","TGT C")
+NOTICE: SELECT USING on rls_test_tgt.(3,"tgt c","TGT C")
+NOTICE: UPDATE USING on rls_test_tgt.(3,"tgt a","TGT A")
+NOTICE: SELECT USING on rls_test_tgt.(3,"tgt a","TGT A")
+NOTICE: UPDATE CHECK on rls_test_tgt.(3,"tgt d","TGT D")
+NOTICE: SELECT USING on rls_test_tgt.(3,"tgt d","TGT D")
+ a | b | c
+---+-------+-------
+ 3 | tgt d | TGT D
+(1 row)
+
+ROLLBACK;
+-- MERGE should always apply SELECT USING policy clauses to both source and
+-- target rows
+MERGE INTO rls_test_tgt t USING rls_test_src s ON t.a = s.a
+ WHEN NOT MATCHED THEN DO NOTHING;
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt a","TGT A")
+NOTICE: SELECT USING on rls_test_src.(1,"src a")
+-- MERGE ... INSERT should behave like INSERT on target table
+-- (SELECT policy applied to target, if RETURNING is specified)
+TRUNCATE rls_test_tgt;
+MERGE INTO rls_test_tgt t USING rls_test_src s ON t.a = s.a
+ WHEN NOT MATCHED THEN INSERT VALUES (1, 'tgt a');
+NOTICE: SELECT USING on rls_test_src.(1,"src a")
+NOTICE: INSERT CHECK on rls_test_tgt.(1,"tgt a","TGT A")
+TRUNCATE rls_test_tgt;
+MERGE INTO rls_test_tgt t USING rls_test_src s ON t.a = s.a
+ WHEN NOT MATCHED THEN INSERT VALUES (1, 'tgt a')
+ RETURNING *;
+NOTICE: SELECT USING on rls_test_src.(1,"src a")
+NOTICE: INSERT CHECK on rls_test_tgt.(1,"tgt a","TGT A")
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt a","TGT A")
+ a | b | a | b | c
+---+-------+---+-------+-------
+ 1 | src a | 1 | tgt a | TGT A
+(1 row)
+
+-- MERGE ... UPDATE should behave like UPDATE ... WHERE on target table
+-- (join clause is like WHERE, so SELECT policies are always applied)
+MERGE INTO rls_test_tgt t USING rls_test_src s ON t.a = s.a
+ WHEN MATCHED THEN UPDATE SET b = 'tgt b';
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt a","TGT A")
+NOTICE: SELECT USING on rls_test_src.(1,"src a")
+NOTICE: UPDATE USING on rls_test_tgt.(1,"tgt a","TGT A")
+NOTICE: UPDATE CHECK on rls_test_tgt.(1,"tgt b","TGT B")
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt b","TGT B")
+MERGE INTO rls_test_tgt t USING rls_test_src s ON t.a = s.a
+ WHEN MATCHED THEN UPDATE SET b = 'tgt c'
+ RETURNING *;
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt b","TGT B")
+NOTICE: SELECT USING on rls_test_src.(1,"src a")
+NOTICE: UPDATE USING on rls_test_tgt.(1,"tgt b","TGT B")
+NOTICE: UPDATE CHECK on rls_test_tgt.(1,"tgt c","TGT C")
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt c","TGT C")
+ a | b | a | b | c
+---+-------+---+-------+-------
+ 1 | src a | 1 | tgt c | TGT C
+(1 row)
+
+-- MERGE ... DELETE should behave like DELETE ... WHERE on target table
+-- (join clause is like WHERE, so SELECT policies are always applied)
+BEGIN;
+MERGE INTO rls_test_tgt t USING rls_test_src s ON t.a = s.a
+ WHEN MATCHED THEN DELETE;
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt c","TGT C")
+NOTICE: SELECT USING on rls_test_src.(1,"src a")
+NOTICE: DELETE USING on rls_test_tgt.(1,"tgt c","TGT C")
+ROLLBACK;
+MERGE INTO rls_test_tgt t USING rls_test_src s ON t.a = s.a
+ WHEN MATCHED THEN DELETE
+ RETURNING *;
+NOTICE: SELECT USING on rls_test_tgt.(1,"tgt c","TGT C")
+NOTICE: SELECT USING on rls_test_src.(1,"src a")
+NOTICE: DELETE USING on rls_test_tgt.(1,"tgt c","TGT C")
+ a | b | a | b | c
+---+-------+---+-------+-------
+ 1 | src a | 1 | tgt c | TGT C
+(1 row)
+
+-- Tidy up
+RESET SESSION AUTHORIZATION;
+DROP TABLE rls_test_src, rls_test_tgt;
+DROP FUNCTION rls_test_tgt_set_c;
+DROP FUNCTION rls_test_policy_fn;
-- BASIC Row-Level Security Scenario
SET SESSION AUTHORIZATION regress_rls_alice;
CREATE TABLE uaccount (