-- Regression test for this issue:
-- https://github.com/citusdata/citus/issues/3867
SET citus.shard_count = 4;
SET citus.next_shard_id TO 1959300;
CREATE SCHEMA set_role_in_transaction;
SET search_path TO set_role_in_transaction;
CREATE TABLE t(a int);
SELECT create_distributed_table('t', 'a');
 create_distributed_table
---------------------------------------------------------------------

(1 row)

-- hide messages only visible in Citus Opensource
SET client_min_messages TO WARNING;
CREATE USER user1;
CREATE USER user2;
-- Not needed on Citus Enterprise, so using count(*) for same output
SELECT count(*) FROM run_command_on_workers('CREATE USER user1');
 count
---------------------------------------------------------------------
     2
(1 row)

SELECT count(*) FROM run_command_on_workers('CREATE USER user2');
 count
---------------------------------------------------------------------
     2
(1 row)

GRANT ALL ON SCHEMA set_role_in_transaction TO user1;
GRANT ALL ON SCHEMA set_role_in_transaction TO user2;
GRANT ALL ON ALL TABLES IN SCHEMA set_role_in_transaction TO user1;
GRANT ALL ON ALL TABLES IN SCHEMA set_role_in_transaction TO user2;
-- Not needed on Citus Enterprise, so using count(*) for same output
SELECT count(*) FROM run_command_on_workers('GRANT ALL ON ALL TABLES IN SCHEMA set_role_in_transaction TO user1');
 count
---------------------------------------------------------------------
     2
(1 row)

SELECT count(*) FROM run_command_on_workers('GRANT ALL ON ALL TABLES IN SCHEMA set_role_in_transaction TO user2');
 count
---------------------------------------------------------------------
     2
(1 row)

RESET client_min_messages;
-- Visibility bugs
SET ROLE user1;
SET search_path TO set_role_in_transaction;
BEGIN;
INSERT INTO t values (1);
SELECT * FROM t; -- 1 is visible as expected
 a
---------------------------------------------------------------------
 1
(1 row)

SET ROLE user2;
SET search_path TO set_role_in_transaction;
SELECT * FROM t; -- 1 is not visible
ERROR:  cannot perform query on placements that were modified in this transaction by a different user
INSERT INTO t values (1); -- assert failure
ERROR:  current transaction is aborted, commands ignored until end of transaction block
SELECT * from t;
ERROR:  current transaction is aborted, commands ignored until end of transaction block
ROLLBACK;
-- Self deadlock
SET ROLE user1;
SET search_path TO set_role_in_transaction;
BEGIN;
TRUNCATE t;
SET ROLE user2;
SET search_path TO set_role_in_transaction;
-- assert failure or self deadlock (it is detected by deadlock detector)
INSERT INTO t values (2);
ERROR:  cannot perform query on placements that were modified in this transaction by a different user
ROLLBACK;
-- we cannot change role in between COPY commands as well
SET ROLE user1;
SET search_path TO set_role_in_transaction;
BEGIN;
    COPY t FROM STDIN;
    SET ROLE user2;
    SET search_path TO set_role_in_transaction;
    COPY t FROM STDIN;
ERROR:  cannot perform query on placements that were modified in this transaction by a different user
CONTEXT:  COPY t, line 1: "1"
ROLLBACK;
RESET ROLE;
REVOKE ALL ON SCHEMA set_role_in_transaction FROM user1;
REVOKE ALL ON SCHEMA set_role_in_transaction FROM user2;
REVOKE ALL ON ALL TABLES IN SCHEMA set_role_in_transaction FROM user1;
REVOKE ALL ON ALL TABLES IN SCHEMA set_role_in_transaction FROM user2;
-- Not needed on Citus Enterprise, so using count(*) for same output
SELECT count(*) FROM run_command_on_workers('REVOKE ALL ON ALL TABLES IN SCHEMA set_role_in_transaction FROM user1');
 count
---------------------------------------------------------------------
     2
(1 row)

SELECT count(*) FROM run_command_on_workers('REVOKE ALL ON ALL TABLES IN SCHEMA set_role_in_transaction FROM user2');
 count
---------------------------------------------------------------------
     2
(1 row)

DROP USER user1;
DROP USER user2;
-- Not needed on Citus Enterprise, so using count(*) for same output
SELECT count(*) FROM run_command_on_workers('DROP USER user1');
 count
---------------------------------------------------------------------
     2
(1 row)

SELECT count(*) FROM run_command_on_workers('DROP USER user2');
 count
---------------------------------------------------------------------
     2
(1 row)

DROP SCHEMA set_role_in_transaction CASCADE;
NOTICE:  drop cascades to table t
