Skip to content

Commit d3dea68

Browse files
committed
rewrite create_single_range_partition() function in C language
1 parent 1cd5a12 commit d3dea68

14 files changed

+568
-325
lines changed

hash.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* ------------------------------------------------------------------------
22
*
33
* hash.sql
4-
* HASH partitioning functions
4+
* HASH partitioning functions
55
*
66
* Copyright (c) 2015-2016, Postgres Professional
77
*

range.sql

Lines changed: 36 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,20 @@
11
/* ------------------------------------------------------------------------
22
*
33
* range.sql
4-
* RANGE partitioning functions
4+
* RANGE partitioning functions
55
*
66
* Copyright (c) 2015-2016, Postgres Professional
77
*
88
* ------------------------------------------------------------------------
99
*/
1010

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-
2411
CREATE OR REPLACE FUNCTION @extschema@.create_or_replace_sequence(
25-
plain_schema TEXT,
26-
plain_relname TEXT,
12+
parent_relid REGCLASS,
2713
OUT seq_name TEXT)
2814
AS $$
2915
BEGIN
30-
seq_name := @extschema@.get_sequence_name(plain_schema, plain_relname);
16+
seq_name := @extschema@.build_sequence_name(parent_relid);
17+
3118
EXECUTE format('DROP SEQUENCE IF EXISTS %s', seq_name);
3219
EXECUTE format('CREATE SEQUENCE %s START 1', seq_name);
3320
END
@@ -110,7 +97,7 @@ BEGIN
11097
PERFORM @extschema@.common_relation_checks(parent_relid, attribute);
11198

11299
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';
114101
END IF;
115102

116103
/* Try to determine partitions count if not set */
@@ -154,7 +141,7 @@ BEGIN
154141
END IF;
155142

156143
/* Create sequence for child partitions names */
157-
PERFORM @extschema@.create_or_replace_sequence(schema, relname)
144+
PERFORM @extschema@.create_or_replace_sequence(parent_relid)
158145
FROM @extschema@.get_plain_schema_and_relname(parent_relid);
159146

160147
/* Insert new entry to pathman config */
@@ -269,7 +256,7 @@ BEGIN
269256
END IF;
270257

271258
/* Create sequence for child partitions names */
272-
PERFORM @extschema@.create_or_replace_sequence(schema, relname)
259+
PERFORM @extschema@.create_or_replace_sequence(parent_relid)
273260
FROM @extschema@.get_plain_schema_and_relname(parent_relid);
274261

275262
/* Insert new entry to pathman config */
@@ -343,7 +330,7 @@ BEGIN
343330
end_value);
344331

345332
/* Create sequence for child partitions names */
346-
PERFORM @extschema@.create_or_replace_sequence(schema, relname)
333+
PERFORM @extschema@.create_or_replace_sequence(parent_relid)
347334
FROM @extschema@.get_plain_schema_and_relname(parent_relid);
348335

349336
/* Insert new entry to pathman config */
@@ -413,7 +400,7 @@ BEGIN
413400
end_value);
414401

415402
/* Create sequence for child partitions names */
416-
PERFORM @extschema@.create_or_replace_sequence(schema, relname)
403+
PERFORM @extschema@.create_or_replace_sequence(parent_relid)
417404
FROM @extschema@.get_plain_schema_and_relname(parent_relid);
418405

419406
/* Insert new entry to pathman config */
@@ -450,102 +437,6 @@ BEGIN
450437
END
451438
$$ LANGUAGE plpgsql;
452439

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-
549440
/*
550441
* Split RANGE partition
551442
*/
@@ -1016,9 +907,10 @@ BEGIN
1016907
END IF;
1017908

1018909
/* 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);
1022914
END IF;
1023915

1024916
/* Create new partition */
@@ -1133,9 +1025,8 @@ BEGIN
11331025
partition::TEXT;
11341026
END IF;
11351027

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);
11391030

11401031
IF NOT @extschema@.validate_relations_equality(parent_relid, partition) THEN
11411032
RAISE EXCEPTION 'partition must have the exact same structure as parent';
@@ -1321,6 +1212,20 @@ BEGIN
13211212
END
13221213
$$ LANGUAGE plpgsql;
13231214

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+
13241229
/*
13251230
* Construct CHECK constraint condition for a range partition.
13261231
*/
@@ -1331,6 +1236,11 @@ CREATE OR REPLACE FUNCTION @extschema@.build_range_condition(
13311236
RETURNS TEXT AS 'pg_pathman', 'build_range_condition'
13321237
LANGUAGE C;
13331238

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+
13341244
/*
13351245
* Returns N-th range (as an array of two elements).
13361246
*/
@@ -1354,11 +1264,11 @@ LANGUAGE C;
13541264
* Checks if range overlaps with existing partitions.
13551265
* Returns TRUE if overlaps and FALSE otherwise.
13561266
*/
1357-
CREATE OR REPLACE FUNCTION @extschema@.check_overlap(
1267+
CREATE OR REPLACE FUNCTION @extschema@.check_range_available(
13581268
parent_relid REGCLASS,
13591269
range_min ANYELEMENT,
13601270
range_max ANYELEMENT)
1361-
RETURNS BOOLEAN AS 'pg_pathman', 'check_overlap'
1271+
RETURNS VOID AS 'pg_pathman', 'check_range_available_pl'
13621272
LANGUAGE C;
13631273

13641274
/*

sql/pathman_basic.sql

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -280,13 +280,13 @@ CREATE TABLE test.num_range_rel (
280280
id SERIAL PRIMARY KEY,
281281
txt TEXT);
282282
SELECT pathman.create_range_partitions('test.num_range_rel', 'id', 1000, 1000, 4);
283-
SELECT pathman.check_overlap('test.num_range_rel'::regclass::oid, 4001, 5000);
284-
SELECT pathman.check_overlap('test.num_range_rel'::regclass::oid, 4000, 5000);
285-
SELECT pathman.check_overlap('test.num_range_rel'::regclass::oid, 3999, 5000);
286-
SELECT pathman.check_overlap('test.num_range_rel'::regclass::oid, 3000, 3500);
287-
SELECT pathman.check_overlap('test.num_range_rel'::regclass::oid, 0, 999);
288-
SELECT pathman.check_overlap('test.num_range_rel'::regclass::oid, 0, 1000);
289-
SELECT pathman.check_overlap('test.num_range_rel'::regclass::oid, 0, 1001);
283+
SELECT pathman.check_range_available('test.num_range_rel'::regclass, 4001, 5000);
284+
SELECT pathman.check_range_available('test.num_range_rel'::regclass, 4000, 5000);
285+
SELECT pathman.check_range_available('test.num_range_rel'::regclass, 3999, 5000);
286+
SELECT pathman.check_range_available('test.num_range_rel'::regclass, 3000, 3500);
287+
SELECT pathman.check_range_available('test.num_range_rel'::regclass, 0, 999);
288+
SELECT pathman.check_range_available('test.num_range_rel'::regclass, 0, 1000);
289+
SELECT pathman.check_range_available('test.num_range_rel'::regclass, 0, 1001);
290290

291291
/* CaMeL cAsE table names and attributes */
292292
CREATE TABLE test."TeSt" (a INT NOT NULL, b INT);

src/init.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,17 @@ build_check_constraint_name_internal(Oid relid, AttrNumber attno)
572572
return psprintf("pathman_%s_%u_check", get_rel_name(relid), attno);
573573
}
574574

575+
/*
576+
* Generate part sequence name for a parent.
577+
*
578+
* This function does not perform sanity checks at all.
579+
*/
580+
char *
581+
build_sequence_name_internal(Oid relid)
582+
{
583+
return psprintf("%s_seq", get_rel_name(relid));
584+
}
585+
575586
/*
576587
* Check that relation 'relid' is partitioned by pg_pathman.
577588
*

src/init.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ Oid *find_inheritance_children_array(Oid parentrelId,
116116
char *build_check_constraint_name_internal(Oid relid,
117117
AttrNumber attno);
118118

119+
char *build_sequence_name_internal(Oid relid);
120+
119121
bool pathman_config_contains_relation(Oid relid,
120122
Datum *values,
121123
bool *isnull,

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