PG17 compatibility: account for MAINTAIN privilege in regress tests (#7774)

This PR addresses regress tests impacted by the introduction of [the
MAINTAIN privilege in
PG17](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=ecb0fd337).
The impacted tests include `generated_identity`,
`create_single_shard_table`, `grant_on_sequence_propagation`,
`grant_on_foreign_server_propagation`, `single_node_enterprise`,
`multi_multiuser_master_protocol`,
`multi_alter_table_row_level_security`, `shard_move_constraints` which
show the following error:
```
SELECT start_metadata_sync_to_node('localhost', :worker_2_port);
- start_metadata_sync_to_node
----------------------------------------------------------------------
-
-(1 row)
-
+ERROR:  unrecognized aclright: 16384
```

and `multi_multiuser_master_protocol`, where the `pg_class.relacl`
column has 'm' for MAINTAIN if applicable:
```
        relname       |   rolname   |                           relacl                           
 ---------------------+-------------+------------------------------------------------------------
  trivial_full_access | full_access | 
- trivial_postgres    | postgres    | {postgres=arwdDxt/postgres,full_access=arwdDxt/postgres}
+ trivial_postgres    | postgres    | {postgres=arwdDxtm/postgres,full_access=arwdDxtm/postgres}
```

The PR updates function `convert_aclright_to_string()` in
citus_ruleutils.c to include a case for `ACL_MAINTAIN`. Per the comment
on `convert_aclright_to_string()` in citus_ruleutils.c, it is a copy of
`convert_aclright_to_string()` in Postgres (where it is in
`src/backend/utils/adt/acl.c`), so requires updating to be consistent
with Postgres. With this change Citus can recognize the MAINTAIN
privilege, and will not emit the `unrecognized aclright` error. The PR
also adds an alternative goldfile for `multi_multiuser_master_protocol`.

Note that `convert_aclright_to_string()` in Postgres includes access
types SET and ALTER SYSTEM on system parameters (aka GUCs), added by
[this PG16
commit](https://github.com/postgres/postgres/commit/a0ffa885e). If Citus
were to have a requirement to support granting SET and ALTER SYSTEM we
would need to update `convert_aclright_to_string()` in citus_ruleutils.c
with SET and ALTER SYSTEM.
pull/7922/head
Colm 2024-12-06 13:03:51 +00:00 committed by naisila
parent beb222ea8d
commit 592416250c
7 changed files with 696 additions and 43 deletions

View File

@ -1359,6 +1359,10 @@ convert_aclright_to_string(int aclright)
return "TEMPORARY"; return "TEMPORARY";
case ACL_CONNECT: case ACL_CONNECT:
return "CONNECT"; return "CONNECT";
#if PG_VERSION_NUM >= PG_VERSION_17
case ACL_MAINTAIN:
return "MAINTAIN";
#endif
default: default:
elog(ERROR, "unrecognized aclright: %d", aclright); elog(ERROR, "unrecognized aclright: %d", aclright);
return NULL; return NULL;

View File

@ -1,6 +1,11 @@
-- --
-- MULTI_MULTIUSER_MASTER_PROTOCOL -- MULTI_MULTIUSER_MASTER_PROTOCOL
-- --
-- Test multi_multiuser_master_protocol has an alternative output file because
-- PG17's support for the MAINTAIN privilege:
-- https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=ecb0fd337
-- means that calls of master_get_table_ddl_events() can show MAINTAIN and the
-- pg_class.relacl column may have 'm' for MAINTAIN
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 109079; ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 109079;
-- Tests that check the metadata returned by the master node. At the -- Tests that check the metadata returned by the master node. At the
-- same time ensure that any user, not just a superuser, can call -- same time ensure that any user, not just a superuser, can call
@ -19,6 +24,8 @@ SELECT * FROM master_get_table_ddl_events('lineitem') order by 1;
GRANT DELETE ON public.lineitem TO postgres GRANT DELETE ON public.lineitem TO postgres
GRANT INSERT ON public.lineitem TO full_access GRANT INSERT ON public.lineitem TO full_access
GRANT INSERT ON public.lineitem TO postgres GRANT INSERT ON public.lineitem TO postgres
GRANT MAINTAIN ON public.lineitem TO full_access
GRANT MAINTAIN ON public.lineitem TO postgres
GRANT REFERENCES ON public.lineitem TO full_access GRANT REFERENCES ON public.lineitem TO full_access
GRANT REFERENCES ON public.lineitem TO postgres GRANT REFERENCES ON public.lineitem TO postgres
GRANT SELECT ON public.lineitem TO full_access GRANT SELECT ON public.lineitem TO full_access
@ -31,7 +38,7 @@ SELECT * FROM master_get_table_ddl_events('lineitem') order by 1;
GRANT UPDATE ON public.lineitem TO full_access GRANT UPDATE ON public.lineitem TO full_access
GRANT UPDATE ON public.lineitem TO postgres GRANT UPDATE ON public.lineitem TO postgres
REVOKE ALL ON public.lineitem FROM PUBLIC REVOKE ALL ON public.lineitem FROM PUBLIC
(20 rows) (22 rows)
SELECT * FROM master_get_new_shardid(); SELECT * FROM master_get_new_shardid();
master_get_new_shardid master_get_new_shardid
@ -75,8 +82,9 @@ SELECT * FROM master_get_table_ddl_events('checkperm');
GRANT TRUNCATE ON public.checkperm TO postgres GRANT TRUNCATE ON public.checkperm TO postgres
GRANT REFERENCES ON public.checkperm TO postgres GRANT REFERENCES ON public.checkperm TO postgres
GRANT TRIGGER ON public.checkperm TO postgres GRANT TRIGGER ON public.checkperm TO postgres
GRANT MAINTAIN ON public.checkperm TO postgres
ALTER TABLE public.checkperm OWNER TO postgres ALTER TABLE public.checkperm OWNER TO postgres
(10 rows) (11 rows)
GRANT SELECT ON checkperm TO read_access; GRANT SELECT ON checkperm TO read_access;
GRANT ALL ON checkperm TO full_access; GRANT ALL ON checkperm TO full_access;
@ -92,6 +100,7 @@ SELECT * FROM master_get_table_ddl_events('checkperm');
GRANT TRUNCATE ON public.checkperm TO postgres GRANT TRUNCATE ON public.checkperm TO postgres
GRANT REFERENCES ON public.checkperm TO postgres GRANT REFERENCES ON public.checkperm TO postgres
GRANT TRIGGER ON public.checkperm TO postgres GRANT TRIGGER ON public.checkperm TO postgres
GRANT MAINTAIN ON public.checkperm TO postgres
GRANT SELECT ON public.checkperm TO read_access GRANT SELECT ON public.checkperm TO read_access
GRANT INSERT ON public.checkperm TO full_access GRANT INSERT ON public.checkperm TO full_access
GRANT SELECT ON public.checkperm TO full_access GRANT SELECT ON public.checkperm TO full_access
@ -100,8 +109,9 @@ SELECT * FROM master_get_table_ddl_events('checkperm');
GRANT TRUNCATE ON public.checkperm TO full_access GRANT TRUNCATE ON public.checkperm TO full_access
GRANT REFERENCES ON public.checkperm TO full_access GRANT REFERENCES ON public.checkperm TO full_access
GRANT TRIGGER ON public.checkperm TO full_access GRANT TRIGGER ON public.checkperm TO full_access
GRANT MAINTAIN ON public.checkperm TO full_access
ALTER TABLE public.checkperm OWNER TO postgres ALTER TABLE public.checkperm OWNER TO postgres
(18 rows) (20 rows)
REVOKE ALL ON checkperm FROM read_access; REVOKE ALL ON checkperm FROM read_access;
GRANT SELECT ON checkperm TO PUBLIC; GRANT SELECT ON checkperm TO PUBLIC;
@ -117,6 +127,7 @@ SELECT * FROM master_get_table_ddl_events('checkperm');
GRANT TRUNCATE ON public.checkperm TO postgres GRANT TRUNCATE ON public.checkperm TO postgres
GRANT REFERENCES ON public.checkperm TO postgres GRANT REFERENCES ON public.checkperm TO postgres
GRANT TRIGGER ON public.checkperm TO postgres GRANT TRIGGER ON public.checkperm TO postgres
GRANT MAINTAIN ON public.checkperm TO postgres
GRANT INSERT ON public.checkperm TO full_access GRANT INSERT ON public.checkperm TO full_access
GRANT SELECT ON public.checkperm TO full_access GRANT SELECT ON public.checkperm TO full_access
GRANT UPDATE ON public.checkperm TO full_access GRANT UPDATE ON public.checkperm TO full_access
@ -124,9 +135,10 @@ SELECT * FROM master_get_table_ddl_events('checkperm');
GRANT TRUNCATE ON public.checkperm TO full_access GRANT TRUNCATE ON public.checkperm TO full_access
GRANT REFERENCES ON public.checkperm TO full_access GRANT REFERENCES ON public.checkperm TO full_access
GRANT TRIGGER ON public.checkperm TO full_access GRANT TRIGGER ON public.checkperm TO full_access
GRANT MAINTAIN ON public.checkperm TO full_access
GRANT SELECT ON public.checkperm TO PUBLIC GRANT SELECT ON public.checkperm TO PUBLIC
ALTER TABLE public.checkperm OWNER TO postgres ALTER TABLE public.checkperm OWNER TO postgres
(18 rows) (20 rows)
GRANT ALL ON checkperm TO full_access WITH GRANT OPTION; GRANT ALL ON checkperm TO full_access WITH GRANT OPTION;
SELECT * FROM master_get_table_ddl_events('checkperm'); SELECT * FROM master_get_table_ddl_events('checkperm');
@ -141,6 +153,7 @@ SELECT * FROM master_get_table_ddl_events('checkperm');
GRANT TRUNCATE ON public.checkperm TO postgres GRANT TRUNCATE ON public.checkperm TO postgres
GRANT REFERENCES ON public.checkperm TO postgres GRANT REFERENCES ON public.checkperm TO postgres
GRANT TRIGGER ON public.checkperm TO postgres GRANT TRIGGER ON public.checkperm TO postgres
GRANT MAINTAIN ON public.checkperm TO postgres
GRANT INSERT ON public.checkperm TO full_access WITH GRANT OPTION GRANT INSERT ON public.checkperm TO full_access WITH GRANT OPTION
GRANT SELECT ON public.checkperm TO full_access WITH GRANT OPTION GRANT SELECT ON public.checkperm TO full_access WITH GRANT OPTION
GRANT UPDATE ON public.checkperm TO full_access WITH GRANT OPTION GRANT UPDATE ON public.checkperm TO full_access WITH GRANT OPTION
@ -148,9 +161,10 @@ SELECT * FROM master_get_table_ddl_events('checkperm');
GRANT TRUNCATE ON public.checkperm TO full_access WITH GRANT OPTION GRANT TRUNCATE ON public.checkperm TO full_access WITH GRANT OPTION
GRANT REFERENCES ON public.checkperm TO full_access WITH GRANT OPTION GRANT REFERENCES ON public.checkperm TO full_access WITH GRANT OPTION
GRANT TRIGGER ON public.checkperm TO full_access WITH GRANT OPTION GRANT TRIGGER ON public.checkperm TO full_access WITH GRANT OPTION
GRANT MAINTAIN ON public.checkperm TO full_access WITH GRANT OPTION
GRANT SELECT ON public.checkperm TO PUBLIC GRANT SELECT ON public.checkperm TO PUBLIC
ALTER TABLE public.checkperm OWNER TO postgres ALTER TABLE public.checkperm OWNER TO postgres
(18 rows) (20 rows)
-- create table as superuser/postgres -- create table as superuser/postgres
CREATE TABLE trivial_postgres (id int); CREATE TABLE trivial_postgres (id int);
@ -172,10 +186,10 @@ SELECT create_distributed_table('trivial_full_access', 'id', 'append');
RESET ROLE; RESET ROLE;
SELECT relname, rolname, relacl FROM pg_class JOIN pg_roles ON (pg_roles.oid = pg_class.relowner) WHERE relname LIKE 'trivial%' ORDER BY relname; SELECT relname, rolname, relacl FROM pg_class JOIN pg_roles ON (pg_roles.oid = pg_class.relowner) WHERE relname LIKE 'trivial%' ORDER BY relname;
relname | rolname | relacl relname | rolname | relacl
--------------------------------------------------------------------- ---------------------------------------------------------------------
trivial_full_access | full_access | trivial_full_access | full_access |
trivial_postgres | postgres | {postgres=arwdDxt/postgres,full_access=arwdDxt/postgres} trivial_postgres | postgres | {postgres=arwdDxtm/postgres,full_access=arwdDxtm/postgres}
(2 rows) (2 rows)
SET citus.shard_replication_factor = 2; -- on all workers... SET citus.shard_replication_factor = 2; -- on all workers...
@ -222,26 +236,26 @@ SELECT master_create_empty_shard('trivial_full_access');
RESET ROLE; RESET ROLE;
\c - - - :worker_1_port \c - - - :worker_1_port
SELECT relname, rolname, relacl FROM pg_class JOIN pg_roles ON (pg_roles.oid = pg_class.relowner) WHERE relname LIKE 'trivial%' ORDER BY relname; SELECT relname, rolname, relacl FROM pg_class JOIN pg_roles ON (pg_roles.oid = pg_class.relowner) WHERE relname LIKE 'trivial%' ORDER BY relname;
relname | rolname | relacl relname | rolname | relacl
--------------------------------------------------------------------- ---------------------------------------------------------------------
trivial_full_access_109081 | full_access | trivial_full_access_109081 | full_access |
trivial_full_access_109083 | full_access | trivial_full_access_109083 | full_access |
trivial_full_access_109085 | full_access | trivial_full_access_109085 | full_access |
trivial_postgres_109080 | postgres | {postgres=arwdDxt/postgres,full_access=arwdDxt/postgres} trivial_postgres_109080 | postgres | {postgres=arwdDxtm/postgres,full_access=arwdDxtm/postgres}
trivial_postgres_109082 | postgres | {postgres=arwdDxt/postgres,full_access=arwdDxt/postgres} trivial_postgres_109082 | postgres | {postgres=arwdDxtm/postgres,full_access=arwdDxtm/postgres}
trivial_postgres_109084 | postgres | {postgres=arwdDxt/postgres,full_access=arwdDxt/postgres} trivial_postgres_109084 | postgres | {postgres=arwdDxtm/postgres,full_access=arwdDxtm/postgres}
(6 rows) (6 rows)
\c - - - :worker_2_port \c - - - :worker_2_port
SELECT relname, rolname, relacl FROM pg_class JOIN pg_roles ON (pg_roles.oid = pg_class.relowner) WHERE relname LIKE 'trivial%' ORDER BY relname; SELECT relname, rolname, relacl FROM pg_class JOIN pg_roles ON (pg_roles.oid = pg_class.relowner) WHERE relname LIKE 'trivial%' ORDER BY relname;
relname | rolname | relacl relname | rolname | relacl
--------------------------------------------------------------------- ---------------------------------------------------------------------
trivial_full_access_109081 | full_access | trivial_full_access_109081 | full_access |
trivial_full_access_109083 | full_access | trivial_full_access_109083 | full_access |
trivial_full_access_109085 | full_access | trivial_full_access_109085 | full_access |
trivial_postgres_109080 | postgres | {postgres=arwdDxt/postgres,full_access=arwdDxt/postgres} trivial_postgres_109080 | postgres | {postgres=arwdDxtm/postgres,full_access=arwdDxtm/postgres}
trivial_postgres_109082 | postgres | {postgres=arwdDxt/postgres,full_access=arwdDxt/postgres} trivial_postgres_109082 | postgres | {postgres=arwdDxtm/postgres,full_access=arwdDxtm/postgres}
trivial_postgres_109084 | postgres | {postgres=arwdDxt/postgres,full_access=arwdDxt/postgres} trivial_postgres_109084 | postgres | {postgres=arwdDxtm/postgres,full_access=arwdDxtm/postgres}
(6 rows) (6 rows)
\c - - - :master_port \c - - - :master_port

View File

@ -0,0 +1,498 @@
--
-- MULTI_MULTIUSER_MASTER_PROTOCOL
--
-- Test multi_multiuser_master_protocol has an alternative output file because
-- PG17's support for the MAINTAIN privilege:
-- https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=ecb0fd337
-- means that calls of master_get_table_ddl_events() can show MAINTAIN and the
-- pg_class.relacl column may have 'm' for MAINTAIN
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 109079;
-- Tests that check the metadata returned by the master node. At the
-- same time ensure that any user, not just a superuser, can call
-- these. Note that, for now at least, any user can call these. That's
-- OK-ish, since the schema is visible from the catalogs anyway, and
-- exhausting shardids doesn't seem like a super viable attack path.
SET ROLE no_access;
SELECT * FROM master_get_table_ddl_events('lineitem') order by 1;
master_get_table_ddl_events
---------------------------------------------------------------------
ALTER TABLE public.lineitem ADD CONSTRAINT lineitem_pkey PRIMARY KEY (l_orderkey, l_linenumber)
ALTER TABLE public.lineitem OWNER TO postgres
CREATE INDEX lineitem_time_index ON public.lineitem USING btree (l_shipdate)
CREATE TABLE public.lineitem (l_orderkey bigint NOT NULL, l_partkey integer NOT NULL, l_suppkey integer NOT NULL, l_linenumber integer NOT NULL, l_quantity numeric(15,2) NOT NULL, l_extendedprice numeric(15,2) NOT NULL, l_discount numeric(15,2) NOT NULL, l_tax numeric(15,2) NOT NULL, l_returnflag character(1) NOT NULL, l_linestatus character(1) NOT NULL, l_shipdate date NOT NULL, l_commitdate date NOT NULL, l_receiptdate date NOT NULL, l_shipinstruct character(25) NOT NULL, l_shipmode character(10) NOT NULL, l_comment character varying(44) NOT NULL) USING heap
GRANT DELETE ON public.lineitem TO full_access
GRANT DELETE ON public.lineitem TO postgres
GRANT INSERT ON public.lineitem TO full_access
GRANT INSERT ON public.lineitem TO postgres
GRANT REFERENCES ON public.lineitem TO full_access
GRANT REFERENCES ON public.lineitem TO postgres
GRANT SELECT ON public.lineitem TO full_access
GRANT SELECT ON public.lineitem TO postgres
GRANT SELECT ON public.lineitem TO read_access
GRANT TRIGGER ON public.lineitem TO full_access
GRANT TRIGGER ON public.lineitem TO postgres
GRANT TRUNCATE ON public.lineitem TO full_access
GRANT TRUNCATE ON public.lineitem TO postgres
GRANT UPDATE ON public.lineitem TO full_access
GRANT UPDATE ON public.lineitem TO postgres
REVOKE ALL ON public.lineitem FROM PUBLIC
(20 rows)
SELECT * FROM master_get_new_shardid();
master_get_new_shardid
---------------------------------------------------------------------
109079
(1 row)
SELECT * FROM master_get_active_worker_nodes();
node_name | node_port
---------------------------------------------------------------------
localhost | 57638
localhost | 57637
(2 rows)
RESET ROLE;
-- ensure GRANT/REVOKE's do something sane for creating shards of
CREATE TABLE checkperm(key int);
SELECT create_distributed_table('checkperm', 'key', 'append');
create_distributed_table
---------------------------------------------------------------------
(1 row)
SELECT * FROM master_get_table_ddl_events('checkperm');
master_get_table_ddl_events
---------------------------------------------------------------------
CREATE TABLE public.checkperm (key integer) USING heap
ALTER TABLE public.checkperm OWNER TO postgres
(2 rows)
REVOKE ALL ON checkperm FROM PUBLIC;
SELECT * FROM master_get_table_ddl_events('checkperm');
master_get_table_ddl_events
---------------------------------------------------------------------
CREATE TABLE public.checkperm (key integer) USING heap
REVOKE ALL ON public.checkperm FROM PUBLIC
GRANT INSERT ON public.checkperm TO postgres
GRANT SELECT ON public.checkperm TO postgres
GRANT UPDATE ON public.checkperm TO postgres
GRANT DELETE ON public.checkperm TO postgres
GRANT TRUNCATE ON public.checkperm TO postgres
GRANT REFERENCES ON public.checkperm TO postgres
GRANT TRIGGER ON public.checkperm TO postgres
ALTER TABLE public.checkperm OWNER TO postgres
(10 rows)
GRANT SELECT ON checkperm TO read_access;
GRANT ALL ON checkperm TO full_access;
SELECT * FROM master_get_table_ddl_events('checkperm');
master_get_table_ddl_events
---------------------------------------------------------------------
CREATE TABLE public.checkperm (key integer) USING heap
REVOKE ALL ON public.checkperm FROM PUBLIC
GRANT INSERT ON public.checkperm TO postgres
GRANT SELECT ON public.checkperm TO postgres
GRANT UPDATE ON public.checkperm TO postgres
GRANT DELETE ON public.checkperm TO postgres
GRANT TRUNCATE ON public.checkperm TO postgres
GRANT REFERENCES ON public.checkperm TO postgres
GRANT TRIGGER ON public.checkperm TO postgres
GRANT SELECT ON public.checkperm TO read_access
GRANT INSERT ON public.checkperm TO full_access
GRANT SELECT ON public.checkperm TO full_access
GRANT UPDATE ON public.checkperm TO full_access
GRANT DELETE ON public.checkperm TO full_access
GRANT TRUNCATE ON public.checkperm TO full_access
GRANT REFERENCES ON public.checkperm TO full_access
GRANT TRIGGER ON public.checkperm TO full_access
ALTER TABLE public.checkperm OWNER TO postgres
(18 rows)
REVOKE ALL ON checkperm FROM read_access;
GRANT SELECT ON checkperm TO PUBLIC;
SELECT * FROM master_get_table_ddl_events('checkperm');
master_get_table_ddl_events
---------------------------------------------------------------------
CREATE TABLE public.checkperm (key integer) USING heap
REVOKE ALL ON public.checkperm FROM PUBLIC
GRANT INSERT ON public.checkperm TO postgres
GRANT SELECT ON public.checkperm TO postgres
GRANT UPDATE ON public.checkperm TO postgres
GRANT DELETE ON public.checkperm TO postgres
GRANT TRUNCATE ON public.checkperm TO postgres
GRANT REFERENCES ON public.checkperm TO postgres
GRANT TRIGGER ON public.checkperm TO postgres
GRANT INSERT ON public.checkperm TO full_access
GRANT SELECT ON public.checkperm TO full_access
GRANT UPDATE ON public.checkperm TO full_access
GRANT DELETE ON public.checkperm TO full_access
GRANT TRUNCATE ON public.checkperm TO full_access
GRANT REFERENCES ON public.checkperm TO full_access
GRANT TRIGGER ON public.checkperm TO full_access
GRANT SELECT ON public.checkperm TO PUBLIC
ALTER TABLE public.checkperm OWNER TO postgres
(18 rows)
GRANT ALL ON checkperm TO full_access WITH GRANT OPTION;
SELECT * FROM master_get_table_ddl_events('checkperm');
master_get_table_ddl_events
---------------------------------------------------------------------
CREATE TABLE public.checkperm (key integer) USING heap
REVOKE ALL ON public.checkperm FROM PUBLIC
GRANT INSERT ON public.checkperm TO postgres
GRANT SELECT ON public.checkperm TO postgres
GRANT UPDATE ON public.checkperm TO postgres
GRANT DELETE ON public.checkperm TO postgres
GRANT TRUNCATE ON public.checkperm TO postgres
GRANT REFERENCES ON public.checkperm TO postgres
GRANT TRIGGER ON public.checkperm TO postgres
GRANT INSERT ON public.checkperm TO full_access WITH GRANT OPTION
GRANT SELECT ON public.checkperm TO full_access WITH GRANT OPTION
GRANT UPDATE ON public.checkperm TO full_access WITH GRANT OPTION
GRANT DELETE ON public.checkperm TO full_access WITH GRANT OPTION
GRANT TRUNCATE ON public.checkperm TO full_access WITH GRANT OPTION
GRANT REFERENCES ON public.checkperm TO full_access WITH GRANT OPTION
GRANT TRIGGER ON public.checkperm TO full_access WITH GRANT OPTION
GRANT SELECT ON public.checkperm TO PUBLIC
ALTER TABLE public.checkperm OWNER TO postgres
(18 rows)
-- create table as superuser/postgres
CREATE TABLE trivial_postgres (id int);
SELECT create_distributed_table('trivial_postgres', 'id', 'append');
create_distributed_table
---------------------------------------------------------------------
(1 row)
GRANT ALL ON trivial_postgres TO full_access;
GRANT CREATE ON SCHEMA public TO full_access;
SET ROLE full_access;
CREATE TABLE trivial_full_access (id int);
SELECT create_distributed_table('trivial_full_access', 'id', 'append');
create_distributed_table
---------------------------------------------------------------------
(1 row)
RESET ROLE;
SELECT relname, rolname, relacl FROM pg_class JOIN pg_roles ON (pg_roles.oid = pg_class.relowner) WHERE relname LIKE 'trivial%' ORDER BY relname;
relname | rolname | relacl
---------------------------------------------------------------------
trivial_full_access | full_access |
trivial_postgres | postgres | {postgres=arwdDxt/postgres,full_access=arwdDxt/postgres}
(2 rows)
SET citus.shard_replication_factor = 2; -- on all workers...
-- create shards as each user, verify ownership
SELECT master_create_empty_shard('trivial_postgres');
master_create_empty_shard
---------------------------------------------------------------------
109080
(1 row)
SELECT master_create_empty_shard('trivial_full_access');
master_create_empty_shard
---------------------------------------------------------------------
109081
(1 row)
SET ROLE full_access;
SELECT master_create_empty_shard('trivial_postgres');
master_create_empty_shard
---------------------------------------------------------------------
109082
(1 row)
SELECT master_create_empty_shard('trivial_full_access');
master_create_empty_shard
---------------------------------------------------------------------
109083
(1 row)
RESET ROLE;
SET ROLE full_access;
SELECT master_create_empty_shard('trivial_postgres');
master_create_empty_shard
---------------------------------------------------------------------
109084
(1 row)
SELECT master_create_empty_shard('trivial_full_access');
master_create_empty_shard
---------------------------------------------------------------------
109085
(1 row)
RESET ROLE;
\c - - - :worker_1_port
SELECT relname, rolname, relacl FROM pg_class JOIN pg_roles ON (pg_roles.oid = pg_class.relowner) WHERE relname LIKE 'trivial%' ORDER BY relname;
relname | rolname | relacl
---------------------------------------------------------------------
trivial_full_access_109081 | full_access |
trivial_full_access_109083 | full_access |
trivial_full_access_109085 | full_access |
trivial_postgres_109080 | postgres | {postgres=arwdDxt/postgres,full_access=arwdDxt/postgres}
trivial_postgres_109082 | postgres | {postgres=arwdDxt/postgres,full_access=arwdDxt/postgres}
trivial_postgres_109084 | postgres | {postgres=arwdDxt/postgres,full_access=arwdDxt/postgres}
(6 rows)
\c - - - :worker_2_port
SELECT relname, rolname, relacl FROM pg_class JOIN pg_roles ON (pg_roles.oid = pg_class.relowner) WHERE relname LIKE 'trivial%' ORDER BY relname;
relname | rolname | relacl
---------------------------------------------------------------------
trivial_full_access_109081 | full_access |
trivial_full_access_109083 | full_access |
trivial_full_access_109085 | full_access |
trivial_postgres_109080 | postgres | {postgres=arwdDxt/postgres,full_access=arwdDxt/postgres}
trivial_postgres_109082 | postgres | {postgres=arwdDxt/postgres,full_access=arwdDxt/postgres}
trivial_postgres_109084 | postgres | {postgres=arwdDxt/postgres,full_access=arwdDxt/postgres}
(6 rows)
\c - - - :master_port
-- ensure COPY into append tables works
CREATE TABLE stage_postgres(id) AS SELECT 2;
GRANT ALL ON stage_postgres TO full_access;
SET ROLE full_access;
CREATE TABLE stage_full_access(id) AS SELECT 1;
RESET ROLE;
SELECT master_create_empty_shard('trivial_postgres') AS shardid \gset
COPY trivial_postgres FROM STDIN WITH (append_to_shard :shardid);
SELECT master_create_empty_shard('trivial_full_access') AS shardid \gset
COPY trivial_full_access FROM STDIN WITH (append_to_shard :shardid);
SET ROLE full_access;
SELECT master_create_empty_shard('trivial_postgres') AS shardid \gset
COPY trivial_postgres FROM STDIN WITH (append_to_shard :shardid);
SELECT master_create_empty_shard('trivial_full_access') AS shardid \gset
COPY trivial_full_access FROM STDIN WITH (append_to_shard :shardid);
RESET ROLE;
SELECT * FROM trivial_postgres ORDER BY id;
id
---------------------------------------------------------------------
1
1
2
2
(4 rows)
SELECT * FROM trivial_full_access ORDER BY id;
id
---------------------------------------------------------------------
1
1
2
2
(4 rows)
SET ROLE full_access;
SELECT * FROM trivial_postgres ORDER BY id;
id
---------------------------------------------------------------------
1
1
2
2
(4 rows)
SELECT * FROM trivial_full_access ORDER BY id;
id
---------------------------------------------------------------------
1
1
2
2
(4 rows)
RESET ROLE;
-- verify column level grants are not supported
GRANT UPDATE (id) ON trivial_postgres TO read_access;
ERROR: grant/revoke on column list is currently unsupported
DROP TABLE trivial_full_access;
DROP TABLE trivial_postgres;
DROP TABLE stage_full_access;
DROP TABLE stage_postgres;
-- test GRANT/REVOKE on all tables in schema
CREATE SCHEMA multiuser_schema;
CREATE TABLE multiuser_schema.hash_table(a int, b int);
CREATE TABLE multiuser_schema.reference_table(a int, b int);
SET citus.shard_replication_factor TO 1;
SELECT create_distributed_table('multiuser_schema.hash_table', 'a', colocate_with => 'none');
create_distributed_table
---------------------------------------------------------------------
(1 row)
-- usage right must be granted to user
GRANT USAGE ON SCHEMA multiuser_schema TO read_access;
-- verify test user (read_access) does not have select privilege on both tables
SELECT * FROM run_command_on_placements('multiuser_schema.hash_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
ORDER BY nodename, nodeport, shardid;
nodename | nodeport | shardid | success | result
---------------------------------------------------------------------
localhost | 57637 | 109090 | t | f
localhost | 57637 | 109092 | t | f
localhost | 57638 | 109091 | t | f
localhost | 57638 | 109093 | t | f
(4 rows)
-- grant select
GRANT SELECT ON ALL TABLES IN SCHEMA multiuser_schema TO read_access;
-- verify select is granted
SELECT * FROM run_command_on_placements('multiuser_schema.hash_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
ORDER BY nodename, nodeport, shardid;
nodename | nodeport | shardid | success | result
---------------------------------------------------------------------
localhost | 57637 | 109090 | t | t
localhost | 57637 | 109092 | t | t
localhost | 57638 | 109091 | t | t
localhost | 57638 | 109093 | t | t
(4 rows)
-- distribute the second table
SELECT create_reference_table('multiuser_schema.reference_table');
create_reference_table
---------------------------------------------------------------------
(1 row)
-- verify select is also granted
SELECT * FROM run_command_on_placements('multiuser_schema.reference_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
ORDER BY nodename, nodeport, shardid;
nodename | nodeport | shardid | success | result
---------------------------------------------------------------------
localhost | 57636 | 109094 | t | t
localhost | 57637 | 109094 | t | t
localhost | 57638 | 109094 | t | t
(3 rows)
-- create another table in the schema, verify select is not granted
CREATE TABLE multiuser_schema.another_table(a int, b int);
SELECT create_distributed_table('multiuser_schema.another_table', 'a', colocate_with => 'none');
create_distributed_table
---------------------------------------------------------------------
(1 row)
SELECT * FROM run_command_on_placements('multiuser_schema.another_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
ORDER BY nodename, nodeport, shardid;
nodename | nodeport | shardid | success | result
---------------------------------------------------------------------
localhost | 57637 | 109095 | t | f
localhost | 57637 | 109097 | t | f
localhost | 57638 | 109096 | t | f
localhost | 57638 | 109098 | t | f
(4 rows)
-- grant select again, verify it is granted
GRANT SELECT ON ALL TABLES IN SCHEMA multiuser_schema TO read_access;
SELECT * FROM run_command_on_placements('multiuser_schema.another_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
ORDER BY nodename, nodeport, shardid;
nodename | nodeport | shardid | success | result
---------------------------------------------------------------------
localhost | 57637 | 109095 | t | t
localhost | 57637 | 109097 | t | t
localhost | 57638 | 109096 | t | t
localhost | 57638 | 109098 | t | t
(4 rows)
-- verify isolate tenant carries grants
SELECT isolate_tenant_to_new_shard('multiuser_schema.hash_table', 5, shard_transfer_mode => 'block_writes');
isolate_tenant_to_new_shard
---------------------------------------------------------------------
109100
(1 row)
SELECT * FROM run_command_on_placements('multiuser_schema.hash_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
ORDER BY nodename, nodeport, shardid;
nodename | nodeport | shardid | success | result
---------------------------------------------------------------------
localhost | 57637 | 109092 | t | t
localhost | 57637 | 109099 | t | t
localhost | 57637 | 109100 | t | t
localhost | 57637 | 109101 | t | t
localhost | 57638 | 109091 | t | t
localhost | 57638 | 109093 | t | t
(6 rows)
-- revoke select
REVOKE SELECT ON ALL TABLES IN SCHEMA multiuser_schema FROM read_access;
SELECT * FROM run_command_on_placements('multiuser_schema.hash_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
ORDER BY nodename, nodeport, shardid;
nodename | nodeport | shardid | success | result
---------------------------------------------------------------------
localhost | 57637 | 109092 | t | f
localhost | 57637 | 109099 | t | f
localhost | 57637 | 109100 | t | f
localhost | 57637 | 109101 | t | f
localhost | 57638 | 109091 | t | f
localhost | 57638 | 109093 | t | f
(6 rows)
-- test multi-schema grants
CREATE SCHEMA multiuser_second_schema;
CREATE TABLE multiuser_second_schema.hash_table(a int, b int);
SELECT create_distributed_table('multiuser_second_schema.hash_table', 'a');
create_distributed_table
---------------------------------------------------------------------
(1 row)
GRANT ALL ON ALL TABLES IN SCHEMA multiuser_schema, multiuser_second_schema TO read_access;
SELECT * FROM run_command_on_placements('multiuser_schema.hash_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
ORDER BY nodename, nodeport, shardid;
nodename | nodeport | shardid | success | result
---------------------------------------------------------------------
localhost | 57637 | 109092 | t | t
localhost | 57637 | 109099 | t | t
localhost | 57637 | 109100 | t | t
localhost | 57637 | 109101 | t | t
localhost | 57638 | 109091 | t | t
localhost | 57638 | 109093 | t | t
(6 rows)
SELECT * FROM run_command_on_placements('multiuser_second_schema.hash_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
ORDER BY nodename, nodeport, shardid;
nodename | nodeport | shardid | success | result
---------------------------------------------------------------------
localhost | 57637 | 109102 | t | t
localhost | 57637 | 109103 | t | t
localhost | 57637 | 109104 | t | t
localhost | 57637 | 109106 | t | t
localhost | 57638 | 109105 | t | t
localhost | 57638 | 109107 | t | t
(6 rows)
-- revoke from multiple schemas, verify result
REVOKE SELECT ON ALL TABLES IN SCHEMA multiuser_schema, multiuser_second_schema FROM read_access;
SELECT * FROM run_command_on_placements('multiuser_schema.hash_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
ORDER BY nodename, nodeport, shardid;
nodename | nodeport | shardid | success | result
---------------------------------------------------------------------
localhost | 57637 | 109092 | t | f
localhost | 57637 | 109099 | t | f
localhost | 57637 | 109100 | t | f
localhost | 57637 | 109101 | t | f
localhost | 57638 | 109091 | t | f
localhost | 57638 | 109093 | t | f
(6 rows)
SELECT * FROM run_command_on_placements('multiuser_second_schema.hash_table', $$ select has_table_privilege('read_access', '%s', 'select') $$)
ORDER BY nodename, nodeport, shardid;
nodename | nodeport | shardid | success | result
---------------------------------------------------------------------
localhost | 57637 | 109102 | t | f
localhost | 57637 | 109103 | t | f
localhost | 57637 | 109104 | t | f
localhost | 57637 | 109106 | t | f
localhost | 57638 | 109105 | t | f
localhost | 57638 | 109107 | t | f
(6 rows)
DROP SCHEMA multiuser_schema CASCADE;
NOTICE: drop cascades to 4 other objects
DETAIL: drop cascades to table multiuser_schema.hash_table
drop cascades to table multiuser_schema.reference_table
drop cascades to table multiuser_schema.reference_table_109094
drop cascades to table multiuser_schema.another_table
DROP SCHEMA multiuser_second_schema CASCADE;
NOTICE: drop cascades to table multiuser_second_schema.hash_table

View File

@ -338,9 +338,6 @@ DEBUG: Router planner cannot handle multi-shard select queries
RESET client_min_messages; RESET client_min_messages;
RESET search_path; RESET search_path;
RESET citus.next_shard_id;
RESET citus.shard_count;
RESET citus.shard_replication_factor;
DROP SCHEMA pg17_corr_subq_folding CASCADE; DROP SCHEMA pg17_corr_subq_folding CASCADE;
NOTICE: drop cascades to 3 other objects NOTICE: drop cascades to 3 other objects
DETAIL: drop cascades to table pg17_corr_subq_folding.test DETAIL: drop cascades to table pg17_corr_subq_folding.test
@ -353,19 +350,19 @@ drop cascades to table pg17_corr_subq_folding.events
-- PG17-specific tests go here. -- PG17-specific tests go here.
-- --
CREATE SCHEMA pg17; CREATE SCHEMA pg17;
SET search_path TO pg17; SET search_path to pg17;
-- Test specifying access method on partitioned tables. PG17 feature, added by: -- Test specifying access method on partitioned tables. PG17 feature, added by:
-- https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=374c7a229 -- https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=374c7a229
-- The following tests were failing tests in tableam but will pass on PG >= 17. -- The following tests were failing tests in tableam but will pass on PG >= 17.
-- There is some set-up duplication of tableam, and this test can be returned -- There is some set-up duplication of tableam, and this test can be returned
-- to tableam when 17 is the minimum supported PG version. -- to tableam when 17 is the minimum supported PG version.
SELECT public.run_command_on_coordinator_and_workers($Q$ SELECT public.run_command_on_coordinator_and_workers($Q$
SET citus.enable_ddl_propagation TO off; SET citus.enable_ddl_propagation TO off;
CREATE FUNCTION fake_am_handler(internal) CREATE FUNCTION fake_am_handler(internal)
RETURNS table_am_handler RETURNS table_am_handler
AS 'citus' AS 'citus'
LANGUAGE C; LANGUAGE C;
CREATE ACCESS METHOD fake_am TYPE TABLE HANDLER fake_am_handler; CREATE ACCESS METHOD fake_am TYPE TABLE HANDLER fake_am_handler;
$Q$); $Q$);
run_command_on_coordinator_and_workers run_command_on_coordinator_and_workers
--------------------------------------------------------------------- ---------------------------------------------------------------------
@ -379,9 +376,9 @@ CREATE TABLE test_partitioned(id int, p int, val int)
PARTITION BY RANGE (p) USING fake_am; PARTITION BY RANGE (p) USING fake_am;
-- Test that children inherit access method from parent -- Test that children inherit access method from parent
CREATE TABLE test_partitioned_p1 PARTITION OF test_partitioned CREATE TABLE test_partitioned_p1 PARTITION OF test_partitioned
FOR VALUES FROM (1) TO (10); FOR VALUES FROM (1) TO (10);
CREATE TABLE test_partitioned_p2 PARTITION OF test_partitioned CREATE TABLE test_partitioned_p2 PARTITION OF test_partitioned
FOR VALUES FROM (11) TO (20); FOR VALUES FROM (11) TO (20);
INSERT INTO test_partitioned VALUES (1, 5, -1), (2, 15, -2); INSERT INTO test_partitioned VALUES (1, 5, -1), (2, 15, -2);
WARNING: fake_tuple_insert WARNING: fake_tuple_insert
WARNING: fake_tuple_insert WARNING: fake_tuple_insert
@ -416,10 +413,93 @@ ORDER BY c.relname;
test_partitioned_p2 | fake_am test_partitioned_p2 | fake_am
(2 rows) (2 rows)
-- Clean up
DROP TABLE test_partitioned; DROP TABLE test_partitioned;
ALTER EXTENSION citus DROP ACCESS METHOD fake_am; ALTER EXTENSION citus DROP ACCESS METHOD fake_am;
SELECT public.run_command_on_coordinator_and_workers($Q$
RESET citus.enable_ddl_propagation;
$Q$);
run_command_on_coordinator_and_workers
---------------------------------------------------------------------
(1 row)
-- End of testing specifying access method on partitioned tables. -- End of testing specifying access method on partitioned tables.
-- MAINTAIN privilege tests
CREATE ROLE regress_maintain;
CREATE ROLE regress_no_maintain;
ALTER ROLE regress_maintain WITH login;
GRANT USAGE ON SCHEMA pg17 TO regress_maintain;
ALTER ROLE regress_no_maintain WITH login;
GRANT USAGE ON SCHEMA pg17 TO regress_no_maintain;
SET citus.shard_count TO 1; -- For consistent remote command logging
CREATE TABLE dist_test(a int, b int);
SELECT create_distributed_table('dist_test', 'a');
create_distributed_table
---------------------------------------------------------------------
(1 row)
INSERT INTO dist_test SELECT i % 10, i FROM generate_series(1, 100) t(i);
SET citus.log_remote_commands TO on;
SET citus.grep_remote_commands = '%maintain%';
GRANT MAINTAIN ON dist_test TO regress_maintain;
NOTICE: issuing GRANT maintain ON dist_test TO regress_maintain
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing GRANT maintain ON dist_test TO regress_maintain
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_apply_shard_ddl_command (20240023, 'pg17', 'GRANT maintain ON dist_test TO regress_maintain')
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
RESET citus.grep_remote_commands;
SET ROLE regress_no_maintain;
-- Current role does not have MAINTAIN privileges on dist_test
ANALYZE dist_test;
WARNING: permission denied to analyze "dist_test", skipping it
NOTICE: issuing ANALYZE pg17.dist_test_20240023
DETAIL: on server regress_no_maintain@localhost:xxxxx connectionId: xxxxxxx
VACUUM dist_test;
WARNING: permission denied to vacuum "dist_test", skipping it
NOTICE: issuing VACUUM pg17.dist_test_20240023
DETAIL: on server regress_no_maintain@localhost:xxxxx connectionId: xxxxxxx
SET ROLE regress_maintain;
-- Current role has MAINTAIN privileges on dist_test
ANALYZE dist_test;
NOTICE: issuing ANALYZE pg17.dist_test_20240023
DETAIL: on server regress_maintain@localhost:xxxxx connectionId: xxxxxxx
VACUUM dist_test;
NOTICE: issuing VACUUM pg17.dist_test_20240023
DETAIL: on server regress_maintain@localhost:xxxxx connectionId: xxxxxxx
-- Take away regress_maintain's MAINTAIN privileges on dist_test
RESET ROLE;
SET citus.grep_remote_commands = '%maintain%';
REVOKE MAINTAIN ON dist_test FROM regress_maintain;
NOTICE: issuing REVOKE maintain ON dist_test FROM regress_maintain
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing REVOKE maintain ON dist_test FROM regress_maintain
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_apply_shard_ddl_command (20240023, 'pg17', 'REVOKE maintain ON dist_test FROM regress_maintain')
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
RESET citus.grep_remote_commands;
SET ROLE regress_maintain;
-- Current role does not have MAINTAIN privileges on dist_test
ANALYZE dist_test;
WARNING: permission denied to analyze "dist_test", skipping it
NOTICE: issuing ANALYZE pg17.dist_test_20240023
DETAIL: on server regress_maintain@localhost:xxxxx connectionId: xxxxxxx
VACUUM dist_test;
WARNING: permission denied to vacuum "dist_test", skipping it
NOTICE: issuing VACUUM pg17.dist_test_20240023
DETAIL: on server regress_maintain@localhost:xxxxx connectionId: xxxxxxx
RESET ROLE;
-- End of MAINTAIN privilege tests
RESET citus.log_remote_commands;
RESET citus.next_shard_id;
RESET citus.shard_count;
RESET citus.shard_replication_factor;
DROP SCHEMA pg17 CASCADE; DROP SCHEMA pg17 CASCADE;
NOTICE: drop cascades to 2 other objects NOTICE: drop cascades to 3 other objects
DETAIL: drop cascades to function fake_am_handler(internal) DETAIL: drop cascades to function fake_am_handler(internal)
drop cascades to access method fake_am drop cascades to access method fake_am
drop cascades to table dist_test
DROP ROLE regress_maintain;
DROP ROLE regress_no_maintain;

View File

@ -282,9 +282,6 @@ DEBUG: Router planner cannot handle multi-shard select queries
RESET client_min_messages; RESET client_min_messages;
RESET search_path; RESET search_path;
RESET citus.next_shard_id;
RESET citus.shard_count;
RESET citus.shard_replication_factor;
DROP SCHEMA pg17_corr_subq_folding CASCADE; DROP SCHEMA pg17_corr_subq_folding CASCADE;
NOTICE: drop cascades to 3 other objects NOTICE: drop cascades to 3 other objects
DETAIL: drop cascades to table pg17_corr_subq_folding.test DETAIL: drop cascades to table pg17_corr_subq_folding.test

View File

@ -2,6 +2,12 @@
-- MULTI_MULTIUSER_MASTER_PROTOCOL -- MULTI_MULTIUSER_MASTER_PROTOCOL
-- --
-- Test multi_multiuser_master_protocol has an alternative output file because
-- PG17's support for the MAINTAIN privilege:
-- https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=ecb0fd337
-- means that calls of master_get_table_ddl_events() can show MAINTAIN and the
-- pg_class.relacl column may have 'm' for MAINTAIN
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 109079; ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 109079;
-- Tests that check the metadata returned by the master node. At the -- Tests that check the metadata returned by the master node. At the

View File

@ -168,9 +168,6 @@ GROUP BY dept;
RESET client_min_messages; RESET client_min_messages;
RESET search_path; RESET search_path;
RESET citus.next_shard_id;
RESET citus.shard_count;
RESET citus.shard_replication_factor;
DROP SCHEMA pg17_corr_subq_folding CASCADE; DROP SCHEMA pg17_corr_subq_folding CASCADE;
\if :server_version_ge_17 \if :server_version_ge_17
@ -181,7 +178,7 @@ DROP SCHEMA pg17_corr_subq_folding CASCADE;
-- PG17-specific tests go here. -- PG17-specific tests go here.
-- --
CREATE SCHEMA pg17; CREATE SCHEMA pg17;
SET search_path TO pg17; SET search_path to pg17;
-- Test specifying access method on partitioned tables. PG17 feature, added by: -- Test specifying access method on partitioned tables. PG17 feature, added by:
-- https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=374c7a229 -- https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=374c7a229
@ -190,12 +187,12 @@ SET search_path TO pg17;
-- to tableam when 17 is the minimum supported PG version. -- to tableam when 17 is the minimum supported PG version.
SELECT public.run_command_on_coordinator_and_workers($Q$ SELECT public.run_command_on_coordinator_and_workers($Q$
SET citus.enable_ddl_propagation TO off; SET citus.enable_ddl_propagation TO off;
CREATE FUNCTION fake_am_handler(internal) CREATE FUNCTION fake_am_handler(internal)
RETURNS table_am_handler RETURNS table_am_handler
AS 'citus' AS 'citus'
LANGUAGE C; LANGUAGE C;
CREATE ACCESS METHOD fake_am TYPE TABLE HANDLER fake_am_handler; CREATE ACCESS METHOD fake_am TYPE TABLE HANDLER fake_am_handler;
$Q$); $Q$);
-- Since Citus assumes access methods are part of the extension, make fake_am -- Since Citus assumes access methods are part of the extension, make fake_am
@ -207,9 +204,9 @@ PARTITION BY RANGE (p) USING fake_am;
-- Test that children inherit access method from parent -- Test that children inherit access method from parent
CREATE TABLE test_partitioned_p1 PARTITION OF test_partitioned CREATE TABLE test_partitioned_p1 PARTITION OF test_partitioned
FOR VALUES FROM (1) TO (10); FOR VALUES FROM (1) TO (10);
CREATE TABLE test_partitioned_p2 PARTITION OF test_partitioned CREATE TABLE test_partitioned_p2 PARTITION OF test_partitioned
FOR VALUES FROM (11) TO (20); FOR VALUES FROM (11) TO (20);
INSERT INTO test_partitioned VALUES (1, 5, -1), (2, 15, -2); INSERT INTO test_partitioned VALUES (1, 5, -1), (2, 15, -2);
INSERT INTO test_partitioned VALUES (3, 6, -6), (4, 16, -4); INSERT INTO test_partitioned VALUES (3, 6, -6), (4, 16, -4);
@ -222,9 +219,66 @@ SELECT c.relname, am.amname FROM pg_class c, pg_am am
WHERE c.relam = am.oid AND c.oid IN ('test_partitioned_p1'::regclass, 'test_partitioned_p2'::regclass) WHERE c.relam = am.oid AND c.oid IN ('test_partitioned_p1'::regclass, 'test_partitioned_p2'::regclass)
ORDER BY c.relname; ORDER BY c.relname;
-- Clean up
DROP TABLE test_partitioned; DROP TABLE test_partitioned;
ALTER EXTENSION citus DROP ACCESS METHOD fake_am; ALTER EXTENSION citus DROP ACCESS METHOD fake_am;
SELECT public.run_command_on_coordinator_and_workers($Q$
RESET citus.enable_ddl_propagation;
$Q$);
-- End of testing specifying access method on partitioned tables. -- End of testing specifying access method on partitioned tables.
-- MAINTAIN privilege tests
CREATE ROLE regress_maintain;
CREATE ROLE regress_no_maintain;
ALTER ROLE regress_maintain WITH login;
GRANT USAGE ON SCHEMA pg17 TO regress_maintain;
ALTER ROLE regress_no_maintain WITH login;
GRANT USAGE ON SCHEMA pg17 TO regress_no_maintain;
SET citus.shard_count TO 1; -- For consistent remote command logging
CREATE TABLE dist_test(a int, b int);
SELECT create_distributed_table('dist_test', 'a');
INSERT INTO dist_test SELECT i % 10, i FROM generate_series(1, 100) t(i);
SET citus.log_remote_commands TO on;
SET citus.grep_remote_commands = '%maintain%';
GRANT MAINTAIN ON dist_test TO regress_maintain;
RESET citus.grep_remote_commands;
SET ROLE regress_no_maintain;
-- Current role does not have MAINTAIN privileges on dist_test
ANALYZE dist_test;
VACUUM dist_test;
SET ROLE regress_maintain;
-- Current role has MAINTAIN privileges on dist_test
ANALYZE dist_test;
VACUUM dist_test;
-- Take away regress_maintain's MAINTAIN privileges on dist_test
RESET ROLE;
SET citus.grep_remote_commands = '%maintain%';
REVOKE MAINTAIN ON dist_test FROM regress_maintain;
RESET citus.grep_remote_commands;
SET ROLE regress_maintain;
-- Current role does not have MAINTAIN privileges on dist_test
ANALYZE dist_test;
VACUUM dist_test;
RESET ROLE;
-- End of MAINTAIN privilege tests
RESET citus.log_remote_commands;
RESET citus.next_shard_id;
RESET citus.shard_count;
RESET citus.shard_replication_factor;
DROP SCHEMA pg17 CASCADE; DROP SCHEMA pg17 CASCADE;
DROP ROLE regress_maintain;
DROP ROLE regress_no_maintain;