1
+ /* **********************************************************************
2
+ * Modify config params table
3
+ **********************************************************************/
4
+ ALTER TABLE @extschema@.pathman_config_params ADD COLUMN init_callback REGPROCEDURE NOT NULL DEFAULT 0 ;
5
+ ALTER TABLE @extschema@.pathman_config_params ALTER COLUMN enable_parent SET DEFAULT FALSE;
6
+
7
+ /* Enable permissions */
8
+ GRANT SELECT , INSERT, UPDATE , DELETE
9
+ ON @extschema@.pathman_config, @extschema@.pathman_config_params
10
+ TO public;
11
+
12
+ CREATE OR REPLACE FUNCTION @extschema@.check_security_policy(relation regclass)
13
+ RETURNS BOOL AS ' pg_pathman' , ' check_security_policy' LANGUAGE C STRICT;
14
+
15
+ CREATE POLICY deny_modification ON @extschema@.pathman_config
16
+ FOR ALL USING (check_security_policy(partrel));
17
+
18
+ CREATE POLICY deny_modification ON @extschema@.pathman_config_params
19
+ FOR ALL USING (check_security_policy(partrel));
20
+
21
+ CREATE POLICY allow_select ON @extschema@.pathman_config FOR SELECT USING (true);
22
+
23
+ CREATE POLICY allow_select ON @extschema@.pathman_config_params FOR SELECT USING (true);
24
+
25
+ ALTER TABLE @extschema@.pathman_config ENABLE ROW LEVEL SECURITY;
26
+ ALTER TABLE @extschema@.pathman_config_params ENABLE ROW LEVEL SECURITY;
27
+
28
+ GRANT SELECT ON @extschema@.pathman_concurrent_part_tasks TO PUBLIC;
29
+
30
+ /* Drop irrelevant functions */
31
+ DROP FUNCTION @extschema@.invalidate_relcache(OID );
32
+ DROP FUNCTION @extschema@.pathman_set_param(REGCLASS, TEXT , BOOLEAN );
33
+ DROP FUNCTION @extschema@.enable_parent(REGCLASS);
34
+ DROP FUNCTION @extschema@.disable_parent(relation REGCLASS);
35
+ DROP FUNCTION @extschema@.enable_auto(relation REGCLASS);
36
+ DROP FUNCTION @extschema@.disable_auto(relation REGCLASS);
37
+ DROP FUNCTION @extschema@.partition_table_concurrently(relation regclass);
38
+ DROP FUNCTION @extschema@._partition_data_concurrent(REGCLASS, ANYELEMENT, ANYELEMENT, INT , OUT BIGINT );
39
+ DROP FUNCTION @extschema@.common_relation_checks(REGCLASS, TEXT );
40
+
41
+ /* Alter functions' modifiers */
42
+ ALTER FUNCTION @extschema@.partitions_count(REGCLASS) STRICT;
43
+ ALTER FUNCTION @extschema@.partition_data(REGCLASS, OUT BIGINT ) STRICT;
44
+ ALTER FUNCTION @extschema@.disable_pathman_for(REGCLASS) STRICT;
45
+ ALTER FUNCTION @extschema@.get_plain_schema_and_relname(REGCLASS, OUT TEXT , OUT TEXT ) STRICT;
46
+
47
+ /* Create functions */
48
+ CREATE OR REPLACE FUNCTION @extschema@.pathman_set_param(
49
+ relation REGCLASS,
50
+ param TEXT ,
51
+ value ANYELEMENT)
52
+ RETURNS VOID AS
53
+ $$
54
+ BEGIN
55
+ EXECUTE format(' INSERT INTO @extschema@.pathman_config_params
56
+ (partrel, %1$s) VALUES ($1, $2)
57
+ ON CONFLICT (partrel) DO UPDATE SET %1$s = $2' , param)
58
+ USING relation, value;
59
+ END
60
+ $$
61
+ LANGUAGE plpgsql;
62
+
63
+ CREATE OR REPLACE FUNCTION @extschema@.set_enable_parent(
64
+ relation REGCLASS,
65
+ value BOOLEAN )
66
+ RETURNS VOID AS
67
+ $$
68
+ BEGIN
69
+ PERFORM @extschema@.pathman_set_param(relation, ' enable_parent' , value);
70
+ END
71
+ $$
72
+ LANGUAGE plpgsql STRICT;
73
+
74
+ /*
75
+ * Partition table using ConcurrentPartWorker.
76
+ */
77
+ CREATE OR REPLACE FUNCTION @extschema@.partition_table_concurrently(
78
+ relation REGCLASS,
79
+ batch_size INTEGER DEFAULT 1000 ,
80
+ sleep_time FLOAT8 DEFAULT 1 .0 )
81
+ RETURNS VOID AS ' pg_pathman' , ' partition_table_concurrently'
82
+ LANGUAGE C STRICT;
83
+
84
+ /*
85
+ * Copy rows to partitions concurrently.
86
+ */
87
+ CREATE OR REPLACE FUNCTION @extschema@._partition_data_concurrent(
88
+ relation REGCLASS,
89
+ p_min ANYELEMENT DEFAULT NULL ::text ,
90
+ p_max ANYELEMENT DEFAULT NULL ::text ,
91
+ p_limit INT DEFAULT NULL ,
92
+ OUT p_total BIGINT )
93
+ AS
94
+ $$
95
+ DECLARE
96
+ v_attr TEXT ;
97
+ v_limit_clause TEXT := ' ' ;
98
+ v_where_clause TEXT := ' ' ;
99
+ ctids TID[];
100
+
101
+ BEGIN
102
+ SELECT attname INTO v_attr
103
+ FROM @extschema@.pathman_config WHERE partrel = relation;
104
+
105
+ p_total := 0 ;
106
+
107
+ /* Format LIMIT clause if needed */
108
+ IF NOT p_limit IS NULL THEN
109
+ v_limit_clause := format(' LIMIT %s' , p_limit);
110
+ END IF;
111
+
112
+ /* Format WHERE clause if needed */
113
+ IF NOT p_min IS NULL THEN
114
+ v_where_clause := format(' %1$s >= $1' , v_attr);
115
+ END IF;
116
+
117
+ IF NOT p_max IS NULL THEN
118
+ IF NOT p_min IS NULL THEN
119
+ v_where_clause := v_where_clause || ' AND ' ;
120
+ END IF;
121
+ v_where_clause := v_where_clause || format(' %1$s < $2' , v_attr);
122
+ END IF;
123
+
124
+ IF v_where_clause != ' ' THEN
125
+ v_where_clause := ' WHERE ' || v_where_clause;
126
+ END IF;
127
+
128
+ /* Lock rows and copy data */
129
+ RAISE NOTICE ' Copying data to partitions...' ;
130
+ EXECUTE format(' SELECT array(SELECT ctid FROM ONLY %1$s %2$s %3$s FOR UPDATE NOWAIT)' ,
131
+ relation, v_where_clause, v_limit_clause)
132
+ USING p_min, p_max
133
+ INTO ctids;
134
+
135
+ EXECUTE format('
136
+ WITH data AS (
137
+ DELETE FROM ONLY %1$s WHERE ctid = ANY($1) RETURNING *)
138
+ INSERT INTO %1$s SELECT * FROM data' ,
139
+ relation)
140
+ USING ctids;
141
+
142
+ /* Get number of inserted rows */
143
+ GET DIAGNOSTICS p_total = ROW_COUNT;
144
+ RETURN;
145
+ END
146
+ $$
147
+ LANGUAGE plpgsql
148
+ SET pg_pathman .enable_partitionfilter = on ; /* ensures that PartitionFilter is ON */
149
+
150
+ /*
151
+ * Aggregates several common relation checks before partitioning.
152
+ * Suitable for every partitioning type.
153
+ */
154
+ CREATE OR REPLACE FUNCTION @extschema@.common_relation_checks(
155
+ relation REGCLASS,
156
+ p_attribute TEXT )
157
+ RETURNS BOOLEAN AS
158
+ $$
159
+ DECLARE
160
+ v_rec RECORD;
161
+ is_referenced BOOLEAN ;
162
+ rel_persistence CHAR ;
163
+
164
+ BEGIN
165
+ /* Ignore temporary tables */
166
+ SELECT relpersistence FROM pg_catalog .pg_class
167
+ WHERE oid = relation INTO rel_persistence;
168
+
169
+ IF rel_persistence = ' t' ::CHAR THEN
170
+ RAISE EXCEPTION ' temporary table "%" cannot be partitioned' ,
171
+ relation::TEXT ;
172
+ END IF;
173
+
174
+ IF EXISTS (SELECT * FROM @extschema@.pathman_config
175
+ WHERE partrel = relation) THEN
176
+ RAISE EXCEPTION ' relation "%" has already been partitioned' , relation;
177
+ END IF;
178
+
179
+ IF @extschema@.is_attribute_nullable(relation, p_attribute) THEN
180
+ RAISE EXCEPTION ' partitioning key ' ' %' ' must be NOT NULL' , p_attribute;
181
+ END IF;
182
+
183
+ /* Check if there are foreign keys that reference the relation */
184
+ FOR v_rec IN (SELECT * FROM pg_catalog .pg_constraint
185
+ WHERE confrelid = relation::REGCLASS::OID )
186
+ LOOP
187
+ is_referenced := TRUE;
188
+ RAISE WARNING ' foreign key "%" references relation "%"' ,
189
+ v_rec .conname , relation;
190
+ END LOOP;
191
+
192
+ IF is_referenced THEN
193
+ RAISE EXCEPTION ' relation "%" is referenced from other relations' , relation;
194
+ END IF;
195
+
196
+ RETURN TRUE;
197
+ END
198
+ $$
199
+ LANGUAGE plpgsql;
0 commit comments