Skip to content

Commit 063c111

Browse files
committed
Merge branch 'master' into rel_1_3_beta
2 parents 4586e55 + 5f455c1 commit 063c111

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+4701
-373
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ regression.out
88
*.pyc
99
*.gcda
1010
*.gcno
11-
pg_pathman--1.1.sql
11+
pg_pathman--1.2.sql

Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@ OBJS = src/init.o src/relation_info.o src/utils.o src/partition_filter.o \
99
src/partition_creation.o $(WIN32RES)
1010

1111
EXTENSION = pg_pathman
12-
EXTVERSION = 1.1
12+
EXTVERSION = 1.2
1313
DATA_built = pg_pathman--$(EXTVERSION).sql
14-
DATA = pg_pathman--1.0.sql pg_pathman--1.0--1.1.sql
14+
DATA = pg_pathman--1.0.sql \
15+
pg_pathman--1.0--1.1.sql \
16+
pg_pathman--1.1.sql \
17+
pg_pathman--1.1--1.2.sql
1518
PGFILEDESC = "pg_pathman - partitioning tool"
1619

1720
REGRESS = pathman_basic \

README.md

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,9 @@ Done! Now it's time to setup your partitioning schemes.
8484
create_hash_partitions(relation REGCLASS,
8585
attribute TEXT,
8686
partitions_count INTEGER,
87-
partition_name TEXT DEFAULT NULL,
8887
partition_data BOOLEAN DEFAULT TRUE)
8988
```
90-
Performs HASH partitioning for `relation` by integer key `attribute`. The `partitions_count` parameter specifies the number of partitions to create; it cannot be changed afterwards. If `partition_data` is `true` then all the data will be automatically copied from the parent table to partitions. Note that data migration may took a while to finish and the table will be locked until transaction commits. See `partition_table_concurrently()` for a lock-free way to migrate data. Partition creation callback is invoked for each partition if set beforehand (see `set_part_init_callback()`).
89+
Performs HASH partitioning for `relation` by integer key `attribute`. The `partitions_count` parameter specifies the number of partitions to create; it cannot be changed afterwards. If `partition_data` is `true` then all the data will be automatically copied from the parent table to partitions. Note that data migration may took a while to finish and the table will be locked until transaction commits. See `partition_table_concurrently()` for a lock-free way to migrate data. Partition creation callback is invoked for each partition if set beforehand (see `set_init_callback()`).
9190

9291
```plpgsql
9392
create_range_partitions(relation REGCLASS,
@@ -148,6 +147,14 @@ create_range_update_trigger(parent REGCLASS)
148147
Same as above, but for a RANGE-partitioned table.
149148

150149
### Post-creation partition management
150+
```plpgsql
151+
replace_hash_partition(old_partition REGCLASS,
152+
new_partition REGCLASS,
153+
lock_parent BOOL DEFAULT TRUE)
154+
```
155+
Replaces specified partition of HASH-partitioned table with another table. The `lock_parent` parameter will prevent any INSERT/UPDATE/ALTER TABLE queries to parent table.
156+
157+
151158
```plpgsql
152159
split_range_partition(partition REGCLASS,
153160
split_value ANYELEMENT,
@@ -247,6 +254,11 @@ Set partition creation callback to be invoked for each attached or created parti
247254
}
248255
```
249256

257+
```plpgsql
258+
set_set_spawn_using_bgw(relation REGCLASS, value BOOLEAN)
259+
```
260+
When INSERTing new data beyond the partitioning range, use SpawnPartitionsWorker to create new partitions in a separate transaction.
261+
250262
## Views and tables
251263

252264
#### `pathman_config` --- main config storage
@@ -255,19 +267,18 @@ CREATE TABLE IF NOT EXISTS pathman_config (
255267
partrel REGCLASS NOT NULL PRIMARY KEY,
256268
attname TEXT NOT NULL,
257269
parttype INTEGER NOT NULL,
258-
range_interval TEXT,
259-
260-
CHECK (parttype IN (1, 2)) /* check for allowed part types */ );
270+
range_interval TEXT);
261271
```
262272
This table stores a list of partitioned tables.
263273

264274
#### `pathman_config_params` --- optional parameters
265275
```plpgsql
266276
CREATE TABLE IF NOT EXISTS pathman_config_params (
267-
partrel REGCLASS NOT NULL PRIMARY KEY,
268-
enable_parent BOOLEAN NOT NULL DEFAULT TRUE,
269-
auto BOOLEAN NOT NULL DEFAULT TRUE,
270-
init_callback REGPROCEDURE NOT NULL DEFAULT 0);
277+
partrel REGCLASS NOT NULL PRIMARY KEY,
278+
enable_parent BOOLEAN NOT NULL DEFAULT TRUE,
279+
auto BOOLEAN NOT NULL DEFAULT TRUE,
280+
init_callback REGPROCEDURE NOT NULL DEFAULT 0,
281+
spawn_using_bgw BOOLEAN NOT NULL DEFAULT FALSE);
271282
```
272283
This table stores optional parameters which override standard behavior.
273284

expected/pathman_basic.out

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,7 +1728,8 @@ NOTICE: drop cascades to 9 other objects
17281728
/* Test automatic partition creation */
17291729
CREATE TABLE test.range_rel (
17301730
id SERIAL PRIMARY KEY,
1731-
dt TIMESTAMP NOT NULL);
1731+
dt TIMESTAMP NOT NULL,
1732+
data TEXT);
17321733
SELECT pathman.create_range_partitions('test.range_rel', 'dt', '2015-01-01'::DATE, '10 days'::INTERVAL, 1);
17331734
create_range_partitions
17341735
-------------------------
@@ -1748,9 +1749,9 @@ EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE dt = '2014-12-15';
17481749
(3 rows)
17491750

17501751
SELECT * FROM test.range_rel WHERE dt = '2014-12-15';
1751-
id | dt
1752-
-----+--------------------------
1753-
137 | Mon Dec 15 00:00:00 2014
1752+
id | dt | data
1753+
-----+--------------------------+------
1754+
137 | Mon Dec 15 00:00:00 2014 |
17541755
(1 row)
17551756

17561757
EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE dt = '2015-03-15';
@@ -1762,9 +1763,9 @@ EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE dt = '2015-03-15';
17621763
(3 rows)
17631764

17641765
SELECT * FROM test.range_rel WHERE dt = '2015-03-15';
1765-
id | dt
1766-
----+--------------------------
1767-
74 | Sun Mar 15 00:00:00 2015
1766+
id | dt | data
1767+
----+--------------------------+------
1768+
74 | Sun Mar 15 00:00:00 2015 |
17681769
(1 row)
17691770

17701771
SELECT pathman.set_auto('test.range_rel', false);
@@ -1782,6 +1783,17 @@ SELECT pathman.set_auto('test.range_rel', true);
17821783
(1 row)
17831784

17841785
INSERT INTO test.range_rel (dt) VALUES ('2015-06-01');
1786+
/*
1787+
* Test auto removing record from config on table DROP (but not on column drop
1788+
* as it used to be before version 1.2)
1789+
*/
1790+
ALTER TABLE test.range_rel DROP COLUMN data;
1791+
SELECT * FROM pathman.pathman_config;
1792+
partrel | attname | parttype | range_interval
1793+
----------------+---------+----------+----------------
1794+
test.range_rel | dt | 2 | @ 10 days
1795+
(1 row)
1796+
17851797
DROP TABLE test.range_rel CASCADE;
17861798
NOTICE: drop cascades to 20 other objects
17871799
SELECT * FROM pathman.pathman_config;

expected/pathman_calamity.out

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,50 @@ SELECT debug_capture();
1212
set client_min_messages = NOTICE;
1313
/* create table to be partitioned */
1414
CREATE TABLE calamity.part_test(val serial);
15+
/* check function build_hash_condition() */
16+
SELECT build_hash_condition('int4', 'val', 10, 1);
17+
build_hash_condition
18+
-------------------------------------------------
19+
public.get_hash_part_idx(hashint4(val), 10) = 1
20+
(1 row)
21+
22+
SELECT build_hash_condition('text', 'val', 10, 1);
23+
build_hash_condition
24+
-------------------------------------------------
25+
public.get_hash_part_idx(hashtext(val), 10) = 1
26+
(1 row)
27+
28+
SELECT build_hash_condition('int4', 'val', 1, 1);
29+
ERROR: 'partition_index' must be lower than 'partitions_count'
30+
SELECT build_hash_condition('int4', 'val', 10, 20);
31+
ERROR: 'partition_index' must be lower than 'partitions_count'
32+
SELECT build_hash_condition('text', 'val', 10, NULL) IS NULL;
33+
?column?
34+
----------
35+
t
36+
(1 row)
37+
38+
SELECT build_hash_condition('calamity.part_test', 'val', 10, 1);
39+
ERROR: no hash function for type calamity.part_test
40+
/* check function build_range_condition() */
41+
SELECT build_range_condition('calamity.part_test', 'val', 10, 20);
42+
build_range_condition
43+
------------------------------
44+
((val >= 10) AND (val < 20))
45+
(1 row)
46+
47+
SELECT build_range_condition('calamity.part_test', 'val', 10, NULL);
48+
build_range_condition
49+
-----------------------
50+
((val >= 10))
51+
(1 row)
52+
53+
SELECT build_range_condition('calamity.part_test', 'val', NULL, 10);
54+
build_range_condition
55+
-----------------------
56+
((val < 10))
57+
(1 row)
58+
1559
/* check function validate_relname() */
1660
SELECT validate_relname('calamity.part_test');
1761
validate_relname

expected/pathman_callbacks.out

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,39 +26,66 @@ SELECT set_init_callback('callbacks.abc',
2626
(1 row)
2727

2828
INSERT INTO callbacks.abc VALUES (123, 1);
29-
INSERT INTO callbacks.abc VALUES (223, 1);
29+
INSERT INTO callbacks.abc VALUES (223, 1); /* show warning */
30+
WARNING: callback arg: {"parent": "abc", "parttype": "2", "partition": "abc_3", "range_max": "301", "range_min": "201"}
31+
SELECT set_spawn_using_bgw('callbacks.abc', true);
32+
set_spawn_using_bgw
33+
---------------------
34+
35+
(1 row)
36+
37+
SELECT get_number_of_partitions('callbacks.abc');
38+
get_number_of_partitions
39+
--------------------------
40+
3
41+
(1 row)
42+
43+
INSERT INTO callbacks.abc VALUES (323, 1);
44+
SELECT get_number_of_partitions('callbacks.abc'); /* +1 partition (created by BGW) */
45+
get_number_of_partitions
46+
--------------------------
47+
4
48+
(1 row)
49+
50+
SELECT set_spawn_using_bgw('callbacks.abc', false);
51+
set_spawn_using_bgw
52+
---------------------
53+
54+
(1 row)
55+
3056
SELECT append_range_partition('callbacks.abc');
31-
WARNING: callback arg: {"parent": "abc", "parttype": "2", "partition": "abc_4", "range_max": "401", "range_min": "301"}
57+
WARNING: callback arg: {"parent": "abc", "parttype": "2", "partition": "abc_5", "range_max": "501", "range_min": "401"}
3258
append_range_partition
3359
------------------------
34-
callbacks.abc_4
60+
callbacks.abc_5
3561
(1 row)
3662

3763
SELECT prepend_range_partition('callbacks.abc');
38-
WARNING: callback arg: {"parent": "abc", "parttype": "2", "partition": "abc_5", "range_max": "1", "range_min": "-99"}
64+
WARNING: callback arg: {"parent": "abc", "parttype": "2", "partition": "abc_6", "range_max": "1", "range_min": "-99"}
3965
prepend_range_partition
4066
-------------------------
41-
callbacks.abc_5
67+
callbacks.abc_6
4268
(1 row)
4369

44-
SELECT add_range_partition('callbacks.abc', 401, 502);
45-
WARNING: callback arg: {"parent": "abc", "parttype": "2", "partition": "abc_6", "range_max": "502", "range_min": "401"}
70+
SELECT add_range_partition('callbacks.abc', 501, 602);
71+
WARNING: callback arg: {"parent": "abc", "parttype": "2", "partition": "abc_7", "range_max": "602", "range_min": "501"}
4672
add_range_partition
4773
---------------------
48-
callbacks.abc_6
74+
callbacks.abc_7
4975
(1 row)
5076

5177
SELECT drop_partitions('callbacks.abc');
5278
NOTICE: function callbacks.abc_upd_trig_func() does not exist, skipping
5379
NOTICE: 0 rows copied from callbacks.abc_1
5480
NOTICE: 1 rows copied from callbacks.abc_2
5581
NOTICE: 1 rows copied from callbacks.abc_3
56-
NOTICE: 0 rows copied from callbacks.abc_4
82+
NOTICE: 1 rows copied from callbacks.abc_4
5783
NOTICE: 0 rows copied from callbacks.abc_5
5884
NOTICE: 0 rows copied from callbacks.abc_6
85+
NOTICE: 0 rows copied from callbacks.abc_7
5986
drop_partitions
6087
-----------------
61-
6
88+
7
6289
(1 row)
6390

6491
/* set callback to be called on HASH partitions */

expected/pathman_permissions.out

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,20 @@ CREATE ROLE user1 LOGIN;
55
CREATE ROLE user2 LOGIN;
66
GRANT USAGE, CREATE ON SCHEMA permissions TO user1;
77
GRANT USAGE, CREATE ON SCHEMA permissions TO user2;
8-
ALTER DEFAULT PRIVILEGES FOR ROLE user1
9-
IN SCHEMA permissions
10-
GRANT SELECT, INSERT ON TABLES
11-
TO user2;
128
/* Switch to #1 */
139
SET ROLE user1;
1410
CREATE TABLE permissions.user1_table(id serial, a int);
1511
INSERT INTO permissions.user1_table SELECT g, g FROM generate_series(1, 20) as g;
16-
/* Should fail */
12+
/* Should fail (can't SELECT) */
13+
SET ROLE user2;
14+
SELECT create_range_partitions('permissions.user1_table', 'id', 1, 10, 2);
15+
ERROR: permission denied for relation user1_table
16+
/* Grant SELECT to user2 */
17+
SET ROLE user1;
18+
GRANT SELECT ON permissions.user1_table TO user2;
19+
/* Should fail (don't own parent) */
1720
SET ROLE user2;
1821
SELECT create_range_partitions('permissions.user1_table', 'id', 1, 10, 2);
19-
NOTICE: sequence "user1_table_seq" does not exist, skipping
2022
WARNING: only the owner or superuser can change partitioning configuration of table "user1_table"
2123
ERROR: new row violates row-level security policy for table "pathman_config"
2224
/* Should be ok */
@@ -37,9 +39,9 @@ SELECT * FROM pathman_config;
3739
(1 row)
3840

3941
SELECT * FROM pathman_config_params;
40-
partrel | enable_parent | auto | init_callback
41-
-------------------------+---------------+------+---------------
42-
permissions.user1_table | f | t | -
42+
partrel | enable_parent | auto | init_callback | spawn_using_bgw
43+
-------------------------+---------------+------+---------------+-----------------
44+
permissions.user1_table | f | t | - | f
4345
(1 row)
4446

4547
/* Should fail */
@@ -58,21 +60,61 @@ WARNING: only the owner or superuser can change partitioning configuration of t
5860
/* No rights to insert, should fail */
5961
SET ROLE user2;
6062
INSERT INTO permissions.user1_table (id, a) VALUES (35, 0);
61-
/* Have rights, should be ok (bgw connects as user1) */
63+
ERROR: permission denied for relation user1_table
64+
/* No rights to create partitions (need INSERT privilege) */
65+
SET ROLE user2;
66+
SELECT prepend_range_partition('permissions.user1_table');
67+
ERROR: permission denied for parent relation "user1_table"
68+
/* Allow user2 to create partitions */
6269
SET ROLE user1;
6370
GRANT INSERT ON permissions.user1_table TO user2;
71+
GRANT UPDATE(a) ON permissions.user1_table TO user2; /* per-column ACL */
72+
/* Should be able to prepend a partition */
73+
SET ROLE user2;
74+
SELECT prepend_range_partition('permissions.user1_table');
75+
prepend_range_partition
76+
---------------------------
77+
permissions.user1_table_4
78+
(1 row)
79+
80+
SELECT attname, attacl from pg_attribute
81+
WHERE attrelid = (SELECT partition FROM pathman_partition_list
82+
WHERE parent = 'permissions.user1_table'::REGCLASS
83+
ORDER BY range_min::int ASC /* prepend */
84+
LIMIT 1)
85+
ORDER BY attname; /* check ACL for each column */
86+
attname | attacl
87+
----------+-----------------
88+
a | {user2=w/user1}
89+
cmax |
90+
cmin |
91+
ctid |
92+
id |
93+
tableoid |
94+
xmax |
95+
xmin |
96+
(8 rows)
97+
98+
/* Have rights, should be ok (parent's ACL is shared by new children) */
6499
SET ROLE user2;
65100
INSERT INTO permissions.user1_table (id, a) VALUES (35, 0) RETURNING *;
66101
id | a
67102
----+---
68103
35 | 0
69104
(1 row)
70105

71-
SELECT relacl FROM pg_class WHERE oid = 'permissions.user1_table_4'::regclass;
72-
relacl
73-
--------------------------------------
74-
{user1=arwdDxt/user1,user2=ar/user1}
75-
(1 row)
106+
SELECT relname, relacl FROM pg_class
107+
WHERE oid = ANY (SELECT partition FROM pathman_partition_list
108+
WHERE parent = 'permissions.user1_table'::REGCLASS
109+
ORDER BY range_max::int DESC /* append */
110+
LIMIT 3)
111+
ORDER BY relname; /* we also check ACL for "user1_table_2" */
112+
relname | relacl
113+
---------------+--------------------------------------
114+
user1_table_2 | {user1=arwdDxt/user1,user2=r/user1}
115+
user1_table_5 | {user1=arwdDxt/user1,user2=ar/user1}
116+
user1_table_6 | {user1=arwdDxt/user1,user2=ar/user1}
117+
(3 rows)
76118

77119
/* Try to drop partition, should fail */
78120
SELECT drop_range_partition('permissions.user1_table_4');
@@ -95,11 +137,12 @@ SELECT drop_partitions('permissions.user1_table');
95137
NOTICE: function permissions.user1_table_upd_trig_func() does not exist, skipping
96138
NOTICE: 10 rows copied from permissions.user1_table_1
97139
NOTICE: 10 rows copied from permissions.user1_table_2
98-
NOTICE: 0 rows copied from permissions.user1_table_3
99-
NOTICE: 2 rows copied from permissions.user1_table_4
140+
NOTICE: 0 rows copied from permissions.user1_table_4
141+
NOTICE: 0 rows copied from permissions.user1_table_5
142+
NOTICE: 1 rows copied from permissions.user1_table_6
100143
drop_partitions
101144
-----------------
102-
4
145+
5
103146
(1 row)
104147

105148
/* Switch to #2 */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy