Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 403bbcb

Browse files
authored
Merge pull request #261 from postgrespro/PGPRO-7622
Fixes related to new changes in PostgreSQL 16: December 6, 2022 - December 27, 2022
2 parents 15a3816 + 2d49e88 commit 403bbcb

9 files changed

+422
-16
lines changed

expected/pathman_permissions_1.out

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
\set VERBOSITY terse
2+
SET search_path = 'public';
3+
CREATE EXTENSION pg_pathman;
4+
CREATE SCHEMA permissions;
5+
CREATE ROLE user1 LOGIN;
6+
CREATE ROLE user2 LOGIN;
7+
GRANT USAGE, CREATE ON SCHEMA permissions TO user1;
8+
GRANT USAGE, CREATE ON SCHEMA permissions TO user2;
9+
/* Switch to #1 */
10+
SET ROLE user1;
11+
CREATE TABLE permissions.user1_table(id serial, a int);
12+
INSERT INTO permissions.user1_table SELECT g, g FROM generate_series(1, 20) as g;
13+
/* Should fail (can't SELECT) */
14+
SET ROLE user2;
15+
DO $$
16+
BEGIN
17+
SELECT create_range_partitions('permissions.user1_table', 'id', 1, 10, 2);
18+
EXCEPTION
19+
WHEN insufficient_privilege THEN
20+
RAISE NOTICE 'Insufficient priviliges';
21+
END$$;
22+
NOTICE: Insufficient priviliges
23+
/* Grant SELECT to user2 */
24+
SET ROLE user1;
25+
GRANT SELECT ON permissions.user1_table TO user2;
26+
/* Should fail (don't own parent) */
27+
SET ROLE user2;
28+
DO $$
29+
BEGIN
30+
SELECT create_range_partitions('permissions.user1_table', 'id', 1, 10, 2);
31+
EXCEPTION
32+
WHEN insufficient_privilege THEN
33+
RAISE NOTICE 'Insufficient priviliges';
34+
END$$;
35+
NOTICE: Insufficient priviliges
36+
/* Should be ok */
37+
SET ROLE user1;
38+
SELECT create_range_partitions('permissions.user1_table', 'id', 1, 10, 2);
39+
create_range_partitions
40+
-------------------------
41+
2
42+
(1 row)
43+
44+
/* Should be able to see */
45+
SET ROLE user2;
46+
SELECT * FROM pathman_config;
47+
partrel | expr | parttype | range_interval
48+
-------------------------+------+----------+----------------
49+
permissions.user1_table | id | 2 | 10
50+
(1 row)
51+
52+
SELECT * FROM pathman_config_params;
53+
partrel | enable_parent | auto | init_callback | spawn_using_bgw
54+
-------------------------+---------------+------+---------------+-----------------
55+
permissions.user1_table | f | t | | f
56+
(1 row)
57+
58+
/* Should fail */
59+
SET ROLE user2;
60+
SELECT set_enable_parent('permissions.user1_table', true);
61+
WARNING: only the owner or superuser can change partitioning configuration of table "user1_table"
62+
ERROR: new row violates row-level security policy for table "pathman_config_params"
63+
SELECT set_auto('permissions.user1_table', false);
64+
WARNING: only the owner or superuser can change partitioning configuration of table "user1_table"
65+
ERROR: new row violates row-level security policy for table "pathman_config_params"
66+
/* Should fail */
67+
SET ROLE user2;
68+
DELETE FROM pathman_config
69+
WHERE partrel = 'permissions.user1_table'::regclass;
70+
WARNING: only the owner or superuser can change partitioning configuration of table "user1_table"
71+
/* No rights to insert, should fail */
72+
SET ROLE user2;
73+
DO $$
74+
BEGIN
75+
INSERT INTO permissions.user1_table (id, a) VALUES (35, 0);
76+
EXCEPTION
77+
WHEN insufficient_privilege THEN
78+
RAISE NOTICE 'Insufficient priviliges';
79+
END$$;
80+
NOTICE: Insufficient priviliges
81+
/* No rights to create partitions (need INSERT privilege) */
82+
SET ROLE user2;
83+
SELECT prepend_range_partition('permissions.user1_table');
84+
ERROR: permission denied for parent relation "user1_table"
85+
/* Allow user2 to create partitions */
86+
SET ROLE user1;
87+
GRANT INSERT ON permissions.user1_table TO user2;
88+
GRANT UPDATE(a) ON permissions.user1_table TO user2; /* per-column ACL */
89+
/* Should be able to prepend a partition */
90+
SET ROLE user2;
91+
SELECT prepend_range_partition('permissions.user1_table');
92+
prepend_range_partition
93+
---------------------------
94+
permissions.user1_table_4
95+
(1 row)
96+
97+
SELECT attname, attacl FROM pg_attribute
98+
WHERE attrelid = (SELECT "partition" FROM pathman_partition_list
99+
WHERE parent = 'permissions.user1_table'::REGCLASS
100+
ORDER BY range_min::int ASC /* prepend */
101+
LIMIT 1)
102+
ORDER BY attname; /* check ACL for each column */
103+
attname | attacl
104+
----------+-----------------
105+
a | {user2=w/user1}
106+
cmax |
107+
cmin |
108+
ctid |
109+
id |
110+
tableoid |
111+
xmax |
112+
xmin |
113+
(8 rows)
114+
115+
/* Have rights, should be ok (parent's ACL is shared by new children) */
116+
SET ROLE user2;
117+
INSERT INTO permissions.user1_table (id, a) VALUES (35, 0) RETURNING *;
118+
id | a
119+
----+---
120+
35 | 0
121+
(1 row)
122+
123+
SELECT relname, relacl FROM pg_class
124+
WHERE oid = ANY (SELECT "partition" FROM pathman_partition_list
125+
WHERE parent = 'permissions.user1_table'::REGCLASS
126+
ORDER BY range_max::int DESC /* append */
127+
LIMIT 3)
128+
ORDER BY relname; /* we also check ACL for "user1_table_2" */
129+
relname | relacl
130+
---------------+---------------------------------------
131+
user1_table_2 | {user1=arwdDxtm/user1,user2=r/user1}
132+
user1_table_5 | {user1=arwdDxtm/user1,user2=ar/user1}
133+
user1_table_6 | {user1=arwdDxtm/user1,user2=ar/user1}
134+
(3 rows)
135+
136+
/* Try to drop partition, should fail */
137+
DO $$
138+
BEGIN
139+
SELECT drop_range_partition('permissions.user1_table_4');
140+
EXCEPTION
141+
WHEN insufficient_privilege THEN
142+
RAISE NOTICE 'Insufficient priviliges';
143+
END$$;
144+
NOTICE: Insufficient priviliges
145+
/* Disable automatic partition creation */
146+
SET ROLE user1;
147+
SELECT set_auto('permissions.user1_table', false);
148+
set_auto
149+
----------
150+
151+
(1 row)
152+
153+
/* Partition creation, should fail */
154+
SET ROLE user2;
155+
INSERT INTO permissions.user1_table (id, a) VALUES (55, 0) RETURNING *;
156+
ERROR: no suitable partition for key '55'
157+
/* Finally drop partitions */
158+
SET ROLE user1;
159+
SELECT drop_partitions('permissions.user1_table');
160+
NOTICE: 10 rows copied from permissions.user1_table_1
161+
NOTICE: 10 rows copied from permissions.user1_table_2
162+
NOTICE: 0 rows copied from permissions.user1_table_4
163+
NOTICE: 0 rows copied from permissions.user1_table_5
164+
NOTICE: 1 rows copied from permissions.user1_table_6
165+
drop_partitions
166+
-----------------
167+
5
168+
(1 row)
169+
170+
/* Switch to #2 */
171+
SET ROLE user2;
172+
/* Test ddl event trigger */
173+
CREATE TABLE permissions.user2_table(id serial);
174+
SELECT create_hash_partitions('permissions.user2_table', 'id', 3);
175+
create_hash_partitions
176+
------------------------
177+
3
178+
(1 row)
179+
180+
INSERT INTO permissions.user2_table SELECT generate_series(1, 30);
181+
SELECT drop_partitions('permissions.user2_table');
182+
NOTICE: 9 rows copied from permissions.user2_table_0
183+
NOTICE: 11 rows copied from permissions.user2_table_1
184+
NOTICE: 10 rows copied from permissions.user2_table_2
185+
drop_partitions
186+
-----------------
187+
3
188+
(1 row)
189+
190+
/* Switch to #1 */
191+
SET ROLE user1;
192+
CREATE TABLE permissions.dropped_column(a int, val int not null, b int, c int);
193+
INSERT INTO permissions.dropped_column SELECT i,i,i,i FROM generate_series(1, 30) i;
194+
GRANT SELECT(val), INSERT(val) ON permissions.dropped_column TO user2;
195+
SELECT create_range_partitions('permissions.dropped_column', 'val', 1, 10);
196+
create_range_partitions
197+
-------------------------
198+
3
199+
(1 row)
200+
201+
SELECT attrelid::regclass, attname, attacl FROM pg_attribute
202+
WHERE attrelid = ANY (SELECT "partition" FROM pathman_partition_list
203+
WHERE parent = 'permissions.dropped_column'::REGCLASS)
204+
AND attacl IS NOT NULL
205+
ORDER BY attrelid::regclass::text; /* check ACL for each column */
206+
attrelid | attname | attacl
207+
------------------------------+---------+------------------
208+
permissions.dropped_column_1 | val | {user2=ar/user1}
209+
permissions.dropped_column_2 | val | {user2=ar/user1}
210+
permissions.dropped_column_3 | val | {user2=ar/user1}
211+
(3 rows)
212+
213+
ALTER TABLE permissions.dropped_column DROP COLUMN a; /* DROP "a" */
214+
SELECT append_range_partition('permissions.dropped_column');
215+
append_range_partition
216+
------------------------------
217+
permissions.dropped_column_4
218+
(1 row)
219+
220+
SELECT attrelid::regclass, attname, attacl FROM pg_attribute
221+
WHERE attrelid = ANY (SELECT "partition" FROM pathman_partition_list
222+
WHERE parent = 'permissions.dropped_column'::REGCLASS)
223+
AND attacl IS NOT NULL
224+
ORDER BY attrelid::regclass::text; /* check ACL for each column (+1 partition) */
225+
attrelid | attname | attacl
226+
------------------------------+---------+------------------
227+
permissions.dropped_column_1 | val | {user2=ar/user1}
228+
permissions.dropped_column_2 | val | {user2=ar/user1}
229+
permissions.dropped_column_3 | val | {user2=ar/user1}
230+
permissions.dropped_column_4 | val | {user2=ar/user1}
231+
(4 rows)
232+
233+
ALTER TABLE permissions.dropped_column DROP COLUMN b; /* DROP "b" */
234+
SELECT append_range_partition('permissions.dropped_column');
235+
append_range_partition
236+
------------------------------
237+
permissions.dropped_column_5
238+
(1 row)
239+
240+
SELECT attrelid::regclass, attname, attacl FROM pg_attribute
241+
WHERE attrelid = ANY (SELECT "partition" FROM pathman_partition_list
242+
WHERE parent = 'permissions.dropped_column'::REGCLASS)
243+
AND attacl IS NOT NULL
244+
ORDER BY attrelid::regclass::text; /* check ACL for each column (+1 partition) */
245+
attrelid | attname | attacl
246+
------------------------------+---------+------------------
247+
permissions.dropped_column_1 | val | {user2=ar/user1}
248+
permissions.dropped_column_2 | val | {user2=ar/user1}
249+
permissions.dropped_column_3 | val | {user2=ar/user1}
250+
permissions.dropped_column_4 | val | {user2=ar/user1}
251+
permissions.dropped_column_5 | val | {user2=ar/user1}
252+
(5 rows)
253+
254+
DROP TABLE permissions.dropped_column CASCADE;
255+
NOTICE: drop cascades to 6 other objects
256+
/* Finally reset user */
257+
RESET ROLE;
258+
DROP OWNED BY user1;
259+
DROP OWNED BY user2;
260+
DROP USER user1;
261+
DROP USER user2;
262+
DROP SCHEMA permissions;
263+
DROP EXTENSION pg_pathman;

src/include/compat/pg_compat.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,17 @@ extern AttrNumber *convert_tuples_by_name_map(TupleDesc indesc,
10841084
expression_tree_mutator((node), (mutator), (context))
10851085
#endif
10861086

1087+
/*
1088+
* stringToQualifiedNameList
1089+
*/
1090+
#if PG_VERSION_NUM >= 160000
1091+
#define stringToQualifiedNameListCompat(string) \
1092+
stringToQualifiedNameList((string), NULL)
1093+
#else
1094+
#define stringToQualifiedNameListCompat(string) \
1095+
stringToQualifiedNameList((string))
1096+
#endif
1097+
10871098
/*
10881099
* -------------
10891100
* Common code

src/include/partition_filter.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ struct ResultPartsStorage
101101
PartRelationInfo *prel;
102102
ExprState *prel_expr_state;
103103
ExprContext *prel_econtext;
104+
#if PG_VERSION_NUM >= 160000 /* for commit a61b1f74823c */
105+
ResultRelInfo *init_rri; /* first initialized ResultRelInfo */
106+
#endif
104107
};
105108

106109
typedef struct
@@ -167,7 +170,7 @@ void init_result_parts_storage(ResultPartsStorage *parts_storage,
167170
void fini_result_parts_storage(ResultPartsStorage *parts_storage);
168171

169172
/* Find ResultRelInfo holder in storage */
170-
ResultRelInfoHolder * scan_result_parts_storage(ResultPartsStorage *storage, Oid partid);
173+
ResultRelInfoHolder * scan_result_parts_storage(EState *estate, ResultPartsStorage *storage, Oid partid);
171174

172175
/* Refresh PartRelationInfo in storage */
173176
PartRelationInfo * refresh_result_parts_storage(ResultPartsStorage *parts_storage, Oid partid);
@@ -186,7 +189,8 @@ Oid * find_partitions_for_value(Datum value, Oid value_type,
186189
const PartRelationInfo *prel,
187190
int *nparts);
188191

189-
ResultRelInfoHolder *select_partition_for_insert(ResultPartsStorage *parts_storage,
192+
ResultRelInfoHolder *select_partition_for_insert(EState *estate,
193+
ResultPartsStorage *parts_storage,
190194
TupleTableSlot *slot);
191195

192196
Plan * make_partition_filter(Plan *subplan,

0 commit comments

Comments
 (0)