1
+ /* **********************************************************************
2
+ * Modify config params table
3
+ **********************************************************************/
4
+ ALTER TABLE @extschema@.pathman_config_params ADD COLUMN init_callback REGPROCEDURENOT NULL DEFAULT0 ;
5
+ ALTER TABLE @extschema@.pathman_config_params ALTER COLUMN enable_parentSET 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
+ CREATEOR REPLACE FUNCTION @extschema@.check_security_policy(relation regclass)
13
+ RETURNS BOOLAS ' pg_pathman' ,' check_security_policy' LANGUAGE C STRICT;
14
+
15
+ CREATE POLICY deny_modificationON @extschema@.pathman_config
16
+ FOR ALL USING (check_security_policy(partrel));
17
+
18
+ CREATE POLICY deny_modificationON @extschema@.pathman_config_params
19
+ FOR ALL USING (check_security_policy(partrel));
20
+
21
+ CREATE POLICY allow_selectON @extschema@.pathman_config FORSELECT USING (true);
22
+
23
+ CREATE POLICY allow_selectON @extschema@.pathman_config_params FORSELECT 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 , OUTBIGINT );
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, OUTBIGINT ) STRICT;
44
+ ALTER FUNCTION @extschema@.disable_pathman_for(REGCLASS) STRICT;
45
+ ALTER FUNCTION @extschema@.get_plain_schema_and_relname(REGCLASS, OUTTEXT , OUTTEXT ) STRICT;
46
+
47
+ /* Create functions*/
48
+ CREATEOR REPLACE FUNCTION @extschema@.pathman_set_param(
49
+ relationREGCLASS,
50
+ paramTEXT ,
51
+ valueANYELEMENT)
52
+ RETURNS VOIDAS
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
+ CREATEOR REPLACE FUNCTION @extschema@.set_enable_parent(
64
+ relationREGCLASS,
65
+ valueBOOLEAN )
66
+ RETURNS VOIDAS
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
+ CREATEOR REPLACE FUNCTION @extschema@.partition_table_concurrently(
78
+ relationREGCLASS,
79
+ batch_sizeINTEGER DEFAULT1000 ,
80
+ sleep_timeFLOAT8 DEFAULT1 .0 )
81
+ RETURNS VOIDAS ' pg_pathman' ,' partition_table_concurrently'
82
+ LANGUAGE C STRICT;
83
+
84
+ /*
85
+ * Copy rows to partitions concurrently.
86
+ */
87
+ CREATEOR REPLACE FUNCTION @extschema@._partition_data_concurrent(
88
+ relationREGCLASS,
89
+ p_minANYELEMENT DEFAULTNULL ::text ,
90
+ p_maxANYELEMENT DEFAULTNULL ::text ,
91
+ p_limitINT DEFAULTNULL ,
92
+ OUT p_totalBIGINT )
93
+ AS
94
+ $$
95
+ DECLARE
96
+ v_attrTEXT ;
97
+ v_limit_clauseTEXT := ' ' ;
98
+ v_where_clauseTEXT := ' ' ;
99
+ ctidsTID[];
100
+
101
+ BEGIN
102
+ SELECT attname INTO v_attr
103
+ FROM @extschema@.pathman_configWHERE partrel= relation;
104
+
105
+ p_total := 0 ;
106
+
107
+ /* Format LIMIT clause if needed*/
108
+ IF NOT p_limit ISNULL 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 ISNULL THEN
114
+ v_where_clause := format(' %1$s >= $1' , v_attr);
115
+ END IF;
116
+
117
+ IF NOT p_max ISNULL THEN
118
+ IF NOT p_min ISNULL 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
+ CREATEOR REPLACE FUNCTION @extschema@.common_relation_checks(
155
+ relationREGCLASS,
156
+ p_attributeTEXT )
157
+ RETURNSBOOLEAN AS
158
+ $$
159
+ DECLARE
160
+ v_recRECORD;
161
+ is_referencedBOOLEAN ;
162
+ rel_persistenceCHAR ;
163
+
164
+ BEGIN
165
+ /* Ignore temporary tables*/
166
+ SELECT relpersistenceFROM 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_recIN (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;