1
1
/* ------------------------------------------------------------------------
2
2
*
3
3
* range.sql
4
- * RANGE partitioning functions
4
+ * RANGE partitioning functions
5
5
*
6
6
* Copyright (c) 2015-2016, Postgres Professional
7
7
*
8
8
* ------------------------------------------------------------------------
9
9
*/
10
10
11
- CREATE OR REPLACE FUNCTION @extschema@.get_sequence_name(
12
- plain_schema TEXT ,
13
- plain_relname TEXT )
14
- RETURNS TEXT AS
15
- $$
16
- BEGIN
17
- RETURN format(' %s.%s' ,
18
- quote_ident(plain_schema),
19
- quote_ident(format(' %s_seq' , plain_relname)));
20
- END
21
- $$
22
- LANGUAGE plpgsql;
23
-
24
11
CREATE OR REPLACE FUNCTION @extschema@.create_or_replace_sequence(
25
- plain_schema TEXT ,
26
- plain_relname TEXT ,
12
+ parent_relid REGCLASS,
27
13
OUT seq_name TEXT )
28
14
AS $$
29
15
BEGIN
30
- seq_name := @extschema@.get_sequence_name(plain_schema, plain_relname);
16
+ seq_name := @extschema@.build_sequence_name(parent_relid);
17
+
31
18
EXECUTE format(' DROP SEQUENCE IF EXISTS %s' , seq_name);
32
19
EXECUTE format(' CREATE SEQUENCE %s START 1' , seq_name);
33
20
END
110
97
PERFORM @extschema@.common_relation_checks(parent_relid, attribute);
111
98
112
99
IF p_count < 0 THEN
113
- RAISE EXCEPTION ' ' ' p_count' ' must not be less than 0' ;
100
+ RAISE EXCEPTION ' " p_count" must not be less than 0' ;
114
101
END IF;
115
102
116
103
/* Try to determine partitions count if not set */
@@ -154,7 +141,7 @@ BEGIN
154
141
END IF;
155
142
156
143
/* Create sequence for child partitions names */
157
- PERFORM @extschema@.create_or_replace_sequence(schema, relname )
144
+ PERFORM @extschema@.create_or_replace_sequence(parent_relid )
158
145
FROM @extschema@.get_plain_schema_and_relname(parent_relid);
159
146
160
147
/* Insert new entry to pathman config */
@@ -269,7 +256,7 @@ BEGIN
269
256
END IF;
270
257
271
258
/* Create sequence for child partitions names */
272
- PERFORM @extschema@.create_or_replace_sequence(schema, relname )
259
+ PERFORM @extschema@.create_or_replace_sequence(parent_relid )
273
260
FROM @extschema@.get_plain_schema_and_relname(parent_relid);
274
261
275
262
/* Insert new entry to pathman config */
@@ -343,7 +330,7 @@ BEGIN
343
330
end_value);
344
331
345
332
/* Create sequence for child partitions names */
346
- PERFORM @extschema@.create_or_replace_sequence(schema, relname )
333
+ PERFORM @extschema@.create_or_replace_sequence(parent_relid )
347
334
FROM @extschema@.get_plain_schema_and_relname(parent_relid);
348
335
349
336
/* Insert new entry to pathman config */
@@ -413,7 +400,7 @@ BEGIN
413
400
end_value);
414
401
415
402
/* Create sequence for child partitions names */
416
- PERFORM @extschema@.create_or_replace_sequence(schema, relname )
403
+ PERFORM @extschema@.create_or_replace_sequence(parent_relid )
417
404
FROM @extschema@.get_plain_schema_and_relname(parent_relid);
418
405
419
406
/* Insert new entry to pathman config */
@@ -450,102 +437,6 @@ BEGIN
450
437
END
451
438
$$ LANGUAGE plpgsql;
452
439
453
- /*
454
- * Creates new RANGE partition. Returns partition name.
455
- * NOTE: This function SHOULD NOT take xact_handling lock (BGWs in 9.5).
456
- */
457
- CREATE OR REPLACE FUNCTION @extschema@.create_single_range_partition(
458
- parent_relid REGCLASS,
459
- start_value ANYELEMENT,
460
- end_value ANYELEMENT,
461
- partition_name TEXT DEFAULT NULL ,
462
- tablespace TEXT DEFAULT NULL )
463
- RETURNS REGCLASS AS
464
- $$
465
- DECLARE
466
- v_part_num INT ;
467
- v_child_relname TEXT ;
468
- v_plain_child_relname TEXT ;
469
- v_attname TEXT ;
470
- v_plain_schema TEXT ;
471
- v_plain_relname TEXT ;
472
- v_child_relname_exists BOOL;
473
- v_seq_name TEXT ;
474
- v_init_callback REGPROCEDURE;
475
-
476
- BEGIN
477
- v_attname := attname FROM @extschema@.pathman_config
478
- WHERE partrel = parent_relid;
479
-
480
- IF v_attname IS NULL THEN
481
- RAISE EXCEPTION ' table "%" is not partitioned' , parent_relid::TEXT ;
482
- END IF;
483
-
484
- SELECT * INTO v_plain_schema, v_plain_relname
485
- FROM @extschema@.get_plain_schema_and_relname(parent_relid);
486
-
487
- v_seq_name := @extschema@.get_sequence_name(v_plain_schema, v_plain_relname);
488
-
489
- IF partition_name IS NULL THEN
490
- /* Get next value from sequence */
491
- LOOP
492
- v_part_num := nextval(v_seq_name);
493
- v_plain_child_relname := format(' %s_%s' , v_plain_relname, v_part_num);
494
- v_child_relname := format(' %s.%s' ,
495
- quote_ident(v_plain_schema),
496
- quote_ident(v_plain_child_relname));
497
-
498
- v_child_relname_exists := count (* ) > 0
499
- FROM pg_class
500
- WHERE relname = v_plain_child_relname AND
501
- relnamespace = v_plain_schema::regnamespace
502
- LIMIT 1 ;
503
-
504
- EXIT WHEN v_child_relname_exists = false;
505
- END LOOP;
506
- ELSE
507
- v_child_relname := partition_name;
508
- END IF;
509
-
510
- IF tablespace IS NULL THEN
511
- tablespace := @extschema@.get_rel_tablespace_name(parent_relid);
512
- END IF;
513
-
514
- EXECUTE format(' CREATE TABLE %1$s (LIKE %2$s INCLUDING ALL)
515
- INHERITS (%2$s) TABLESPACE %3$s' ,
516
- v_child_relname,
517
- parent_relid::TEXT ,
518
- tablespace);
519
-
520
- EXECUTE format(' ALTER TABLE %s ADD CONSTRAINT %s CHECK (%s)' ,
521
- v_child_relname,
522
- @extschema@.build_check_constraint_name(v_child_relname::REGCLASS,
523
- v_attname),
524
- @extschema@.build_range_condition(v_attname,
525
- start_value,
526
- end_value));
527
-
528
- PERFORM @extschema@.copy_foreign_keys(parent_relid, v_child_relname::REGCLASS);
529
-
530
- /* Fetch init_callback from 'params' table */
531
- WITH stub_callback(stub) as (values (0 ))
532
- SELECT coalesce(init_callback, 0 ::REGPROCEDURE)
533
- FROM stub_callback
534
- LEFT JOIN @extschema@.pathman_config_params AS params
535
- ON params .partrel = parent_relid
536
- INTO v_init_callback;
537
-
538
- PERFORM @extschema@.invoke_on_partition_created_callback(parent_relid,
539
- v_child_relname::REGCLASS,
540
- v_init_callback,
541
- start_value,
542
- end_value);
543
-
544
- RETURN v_child_relname::REGCLASS;
545
- END
546
- $$ LANGUAGE plpgsql
547
- SET client_min_messages = WARNING;
548
-
549
440
/*
550
441
* Split RANGE partition
551
442
*/
@@ -1016,9 +907,10 @@ BEGIN
1016
907
END IF;
1017
908
1018
909
/* check range overlap */
1019
- IF @extschema@.partitions_count(parent_relid) > 0
1020
- AND @extschema@.check_overlap(parent_relid, start_value, end_value) THEN
1021
- RAISE EXCEPTION ' specified range overlaps with existing partitions' ;
910
+ IF @extschema@.partitions_count(parent_relid) > 0 THEN
911
+ PERFORM @extschema@.check_range_available(parent_relid,
912
+ start_value,
913
+ end_value);
1022
914
END IF;
1023
915
1024
916
/* Create new partition */
@@ -1133,9 +1025,8 @@ BEGIN
1133
1025
partition::TEXT ;
1134
1026
END IF;
1135
1027
1136
- IF @extschema@.check_overlap(parent_relid, start_value, end_value) THEN
1137
- RAISE EXCEPTION ' specified range overlaps with existing partitions' ;
1138
- END IF;
1028
+ /* check range overlap */
1029
+ PERFORM @extschema@.check_range_available(parent_relid, start_value, end_value);
1139
1030
1140
1031
IF NOT @extschema@.validate_relations_equality(parent_relid, partition) THEN
1141
1032
RAISE EXCEPTION ' partition must have the exact same structure as parent' ;
@@ -1321,6 +1212,20 @@ BEGIN
1321
1212
END
1322
1213
$$ LANGUAGE plpgsql;
1323
1214
1215
+ /*
1216
+ * Creates new RANGE partition. Returns partition name.
1217
+ * NOTE: This function SHOULD NOT take xact_handling lock (BGWs in 9.5).
1218
+ */
1219
+ CREATE OR REPLACE FUNCTION @extschema@.create_single_range_partition(
1220
+ parent_relid REGCLASS,
1221
+ start_value ANYELEMENT,
1222
+ end_value ANYELEMENT,
1223
+ partition_name TEXT DEFAULT NULL ,
1224
+ tablespace TEXT DEFAULT NULL )
1225
+ RETURNS REGCLASS AS ' pg_pathman' , ' create_single_range_partition_pl'
1226
+ LANGUAGE C
1227
+ SET client_min_messages = WARNING;
1228
+
1324
1229
/*
1325
1230
* Construct CHECK constraint condition for a range partition.
1326
1231
*/
@@ -1331,6 +1236,11 @@ CREATE OR REPLACE FUNCTION @extschema@.build_range_condition(
1331
1236
RETURNS TEXT AS ' pg_pathman' , ' build_range_condition'
1332
1237
LANGUAGE C;
1333
1238
1239
+ CREATE OR REPLACE FUNCTION @extschema@.build_sequence_name(
1240
+ parent_relid REGCLASS)
1241
+ RETURNS TEXT AS ' pg_pathman' , ' build_sequence_name'
1242
+ LANGUAGE C;
1243
+
1334
1244
/*
1335
1245
* Returns N-th range (as an array of two elements).
1336
1246
*/
@@ -1354,11 +1264,11 @@ LANGUAGE C;
1354
1264
* Checks if range overlaps with existing partitions.
1355
1265
* Returns TRUE if overlaps and FALSE otherwise.
1356
1266
*/
1357
- CREATE OR REPLACE FUNCTION @extschema@.check_overlap (
1267
+ CREATE OR REPLACE FUNCTION @extschema@.check_range_available (
1358
1268
parent_relid REGCLASS,
1359
1269
range_min ANYELEMENT,
1360
1270
range_max ANYELEMENT)
1361
- RETURNS BOOLEAN AS ' pg_pathman' , ' check_overlap '
1271
+ RETURNS VOID AS ' pg_pathman' , ' check_range_available_pl '
1362
1272
LANGUAGE C;
1363
1273
1364
1274
/*
0 commit comments