Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4bd715c

Browse files
committed
Merge branch 'rel_1_2_beta' ofhttps://github.com/postgrespro/pg_pathman into rel_1_2_beta
2 parents9575107 +2a31969 commit4bd715c

10 files changed

+490
-165
lines changed

‎expected/pathman_calamity.out

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,44 @@ 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('val', 10, 20);
42+
build_range_condition
43+
----------------------------
44+
val >= '10' AND val < '20'
45+
(1 row)
46+
47+
SELECT build_range_condition('val', 10, NULL) IS NULL;
48+
?column?
49+
----------
50+
t
51+
(1 row)
52+
1553
/* check function validate_relname() */
1654
SELECT validate_relname('calamity.part_test');
1755
validate_relname

‎expected/pathman_permissions.out

Lines changed: 58 additions & 15 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 */
@@ -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 */

‎hash.sql

Lines changed: 63 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,6 @@ CREATE OR REPLACE FUNCTION @extschema@.create_hash_partitions(
1818
partition_dataBOOLEAN DEFAULT TRUE)
1919
RETURNSINTEGERAS
2020
$$
21-
DECLARE
22-
v_child_relnameTEXT;
23-
v_plain_schemaTEXT;
24-
v_plain_relnameTEXT;
25-
-- v_atttypeREGTYPE;
26-
-- v_hashfuncREGPROC;
27-
v_init_callbackREGPROCEDURE;
28-
2921
BEGIN
3022
PERFORM @extschema@.validate_relname(parent_relid);
3123

@@ -40,13 +32,6 @@ BEGIN
4032
attribute :=lower(attribute);
4133
PERFORM @extschema@.common_relation_checks(parent_relid, attribute);
4234

43-
/* Fetch atttype and its hash function*/
44-
-- v_atttype := @extschema@.get_attribute_type(parent_relid, attribute);
45-
-- v_hashfunc := @extschema@.get_type_hash_func(v_atttype);
46-
47-
SELECT* INTO v_plain_schema, v_plain_relname
48-
FROM @extschema@.get_plain_schema_and_relname(parent_relid);
49-
5035
/* Insert new entry to pathman config*/
5136
INSERT INTO @extschema@.pathman_config (partrel, attname, parttype)
5237
VALUES (parent_relid, attribute,1);
@@ -74,29 +59,42 @@ SET client_min_messages = WARNING;
7459

7560
/*
7661
* Replace hash partition with another one. It could be useful in case when
77-
* someone wants to attach foreign table as a partition
62+
* someone wants to attach foreign table as a partition.
63+
*
64+
* lock_parent - should we take an exclusive lock?
7865
*/
7966
CREATEOR REPLACE FUNCTION @extschema@.replace_hash_partition(
8067
old_partitionREGCLASS,
81-
new_partitionREGCLASS)
68+
new_partitionREGCLASS,
69+
lock_parentBOOL DEFAULT TRUE)
8270
RETURNS REGCLASSAS
8371
$$
8472
DECLARE
85-
v_attnameTEXT;
73+
parent_relidREGCLASS;
74+
part_attnameTEXT;/* partitioned column*/
75+
old_constr_nameTEXT;/* name of old_partition's constraint*/
76+
old_constr_defTEXT;/* definition of old_partition's constraint*/
8677
rel_persistenceCHAR;
87-
v_init_callbackREGPROCEDURE;
88-
v_parent_relidREGCLASS;
89-
v_part_countINT;
90-
v_part_numINT;
78+
p_init_callbackREGPROCEDURE;
79+
9180
BEGIN
9281
PERFORM @extschema@.validate_relname(old_partition);
9382
PERFORM @extschema@.validate_relname(new_partition);
9483

9584
/* Parent relation*/
96-
v_parent_relid := @extschema@.get_parent_of_partition(old_partition);
85+
parent_relid := @extschema@.get_parent_of_partition(old_partition);
86+
87+
IF lock_parent THEN
88+
/* Acquire data modification lock (prevent further modifications)*/
89+
PERFORM @extschema@.prevent_relation_modification(parent_relid);
90+
ELSE
91+
/* Acquire lock on parent*/
92+
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
93+
END IF;
9794

98-
/* Acquire lock on parent*/
99-
PERFORM @extschema@.lock_partitioned_relation(v_parent_relid);
95+
/* Acquire data modification lock (prevent further modifications)*/
96+
PERFORM @extschema@.prevent_relation_modification(old_partition);
97+
PERFORM @extschema@.prevent_relation_modification(new_partition);
10098

10199
/* Ignore temporary tables*/
102100
SELECT relpersistenceFROMpg_catalog.pg_class
@@ -108,52 +106,54 @@ BEGIN
108106
END IF;
109107

110108
/* Check that new partition has an equal structure as parent does*/
111-
IF NOT @extschema@.validate_relations_equality(v_parent_relid, new_partition) THEN
109+
IF NOT @extschema@.validate_relations_equality(parent_relid, new_partition) THEN
112110
RAISE EXCEPTION'partition must have the exact same structure as parent';
113111
END IF;
114112

115113
/* Get partitioning key*/
116-
v_attname := attnameFROM @extschema@.pathman_configWHERE partrel=v_parent_relid;
117-
IFv_attname ISNULL THEN
118-
RAISE EXCEPTION'table "%" is not partitioned',v_parent_relid::TEXT;
114+
part_attname := attnameFROM @extschema@.pathman_configWHERE partrel=parent_relid;
115+
IFpart_attname ISNULL THEN
116+
RAISE EXCEPTION'table "%" is not partitioned',parent_relid::TEXT;
119117
END IF;
120118

121-
/* Calculate partitions count and old partition's number*/
122-
v_part_count :=count(*)FROM @extschema@.pathman_partition_listWHERE parent= v_parent_relid;
123-
v_part_num := @extschema@.get_partition_hash(v_parent_relid, old_partition);
119+
/* Fetch name of old_partition's HASH constraint*/
120+
old_constr_name= @extschema@.build_check_constraint_name(old_partition::REGCLASS,
121+
part_attname);
122+
123+
/* Fetch definition of old_partition's HASH constraint*/
124+
SELECTpg_catalog.pg_get_constraintdef(oid)FROMpg_catalog.pg_constraint
125+
WHERE conrelid= old_partitionAND conname= old_constr_name
126+
INTO old_constr_def;
124127

125128
/* Detach old partition*/
126-
EXECUTE format('ALTER TABLE %s NO INHERIT %s', old_partition, v_parent_relid);
127-
EXECUTE format('ALTER TABLE %s DROP CONSTRAINT IF EXISTS %s',
128-
old_partition,
129-
@extschema@.build_check_constraint_name(old_partition::REGCLASS,
130-
v_attname));
131-
132-
/* Attach new one*/
133-
EXECUTE format('ALTER TABLE %s INHERIT %s', new_partition, v_parent_relid);
134-
EXECUTE format('ALTER TABLE %s ADD CONSTRAINT %s CHECK (%s)',
129+
EXECUTE format('ALTER TABLE %s NO INHERIT %s', old_partition, parent_relid);
130+
EXECUTE format('ALTER TABLE %s DROP CONSTRAINT %s',
131+
old_partition,
132+
old_constr_name);
133+
134+
/* Attach the new one*/
135+
EXECUTE format('ALTER TABLE %s INHERIT %s', new_partition, parent_relid);
136+
EXECUTE format('ALTER TABLE %s ADD CONSTRAINT %s %s',
135137
new_partition,
136-
@extschema@.build_check_constraint_name(new_partition::regclass,
137-
v_attname),
138-
@extschema@.build_hash_condition(new_partition::regclass,
139-
v_attname,
140-
v_part_count,
141-
v_part_num));
138+
@extschema@.build_check_constraint_name(new_partition::REGCLASS,
139+
part_attname),
140+
old_constr_def);
142141

143142
/* Fetch init_callback from 'params' table*/
144143
WITH stub_callback(stub)as (values (0))
145144
SELECT coalesce(init_callback,0::REGPROCEDURE)
146145
FROM stub_callback
147146
LEFT JOIN @extschema@.pathman_config_paramsAS params
148-
ONparams.partrel=v_parent_relid
149-
INTOv_init_callback;
147+
ONparams.partrel=parent_relid
148+
INTOp_init_callback;
150149

151-
PERFORM @extschema@.invoke_on_partition_created_callback(v_parent_relid,
150+
/* Finally invoke init_callback*/
151+
PERFORM @extschema@.invoke_on_partition_created_callback(parent_relid,
152152
new_partition,
153-
v_init_callback);
153+
p_init_callback);
154154

155155
/* Invalidate cache*/
156-
PERFORM @extschema@.on_update_partitions(v_parent_relid);
156+
PERFORM @extschema@.on_update_partitions(parent_relid);
157157

158158
RETURN new_partition;
159159
END
@@ -292,3 +292,14 @@ LANGUAGE C STRICT;
292292
CREATEOR REPLACE FUNCTION @extschema@.get_hash_part_idx(INTEGER,INTEGER)
293293
RETURNSINTEGERAS'pg_pathman','get_hash_part_idx'
294294
LANGUAGE C STRICT;
295+
296+
/*
297+
* Build hash condition for a CHECK CONSTRAINT
298+
*/
299+
CREATEOR REPLACE FUNCTION @extschema@.build_hash_condition(
300+
attribute_typeREGTYPE,
301+
attributeTEXT,
302+
partitions_countINT4,
303+
partitions_indexINT4)
304+
RETURNSTEXTAS'pg_pathman','build_hash_condition'
305+
LANGUAGE C STRICT;

‎init.sql

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -783,23 +783,3 @@ CREATE OR REPLACE FUNCTION @extschema@.invoke_on_partition_created_callback(
783783
init_callbackREGPROCEDURE)
784784
RETURNS VOIDAS'pg_pathman','invoke_on_partition_created_callback'
785785
LANGUAGE C;
786-
787-
/*
788-
* Build hash condition for a CHECK CONSTRAINT
789-
*/
790-
CREATEOR REPLACE FUNCTION @extschema@.build_hash_condition(
791-
parent_relidREGCLASS,
792-
attnameTEXT,
793-
partitions_countINT,
794-
partition_numberINT)
795-
RETURNSTEXTAS'pg_pathman','build_hash_condition'
796-
LANGUAGE C;
797-
798-
/*
799-
* Returns hash value for specified partition (0..N)
800-
*/
801-
CREATEOR REPLACE FUNCTION @extschema@.get_partition_hash(
802-
parent_relidREGCLASS,
803-
partitionREGCLASS)
804-
RETURNSINTAS'pg_pathman','get_partition_hash'
805-
LANGUAGE C;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp