@@ -18,14 +18,6 @@ CREATE OR REPLACE FUNCTION @extschema@.create_hash_partitions(
1818 partition_data BOOLEAN DEFAULT TRUE)
1919RETURNS INTEGER AS
2020$$
21- DECLARE
22- v_child_relname TEXT ;
23- v_plain_schema TEXT ;
24- v_plain_relname TEXT ;
25- -- v_atttype REGTYPE;
26- -- v_hashfunc REGPROC;
27- v_init_callback REGPROCEDURE;
28-
2921BEGIN
3022 PERFORM @extschema@.validate_relname(parent_relid);
3123
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 );
@@ -82,21 +67,26 @@ CREATE OR REPLACE FUNCTION @extschema@.replace_hash_partition(
8267RETURNS REGCLASS AS
8368$$
8469DECLARE
85- v_attname TEXT ;
70+ parent_relid REGCLASS;
71+ part_attname TEXT ; /* partitioned column */
72+ old_constr_name TEXT ; /* name of old_partition's constraint */
73+ old_constr_def TEXT ; /* definition of old_partition's constraint */
8674 rel_persistence CHAR ;
87- v_init_callback REGPROCEDURE;
88- v_parent_relid REGCLASS;
89- v_part_count INT ;
90- v_part_num INT ;
75+ p_init_callback REGPROCEDURE;
76+
9177BEGIN
9278 PERFORM @extschema@.validate_relname(old_partition);
9379 PERFORM @extschema@.validate_relname(new_partition);
9480
9581 /* Parent relation */
96- v_parent_relid := @extschema@.get_parent_of_partition(old_partition);
82+ parent_relid := @extschema@.get_parent_of_partition(old_partition);
9783
9884 /* Acquire lock on parent */
99- PERFORM @extschema@.lock_partitioned_relation(v_parent_relid);
85+ PERFORM @extschema@.lock_partitioned_relation(parent_relid);
86+
87+ /* Acquire data modification lock (prevent further modifications) */
88+ PERFORM @extschema@.prevent_relation_modification(old_partition);
89+ PERFORM @extschema@.prevent_relation_modification(new_partition);
10090
10191 /* Ignore temporary tables */
10292 SELECT relpersistence FROM pg_catalog .pg_class
@@ -108,52 +98,54 @@ BEGIN
10898 END IF;
10999
110100 /* Check that new partition has an equal structure as parent does */
111- IF NOT @extschema@.validate_relations_equality(v_parent_relid , new_partition) THEN
101+ IF NOT @extschema@.validate_relations_equality(parent_relid , new_partition) THEN
112102 RAISE EXCEPTION ' partition must have the exact same structure as parent' ;
113103 END IF;
114104
115105 /* Get partitioning key */
116- v_attname := attname FROM @extschema@.pathman_config WHERE partrel = v_parent_relid ;
117- IF v_attname IS NULL THEN
118- RAISE EXCEPTION ' table "%" is not partitioned' , v_parent_relid ::TEXT ;
106+ part_attname := attname FROM @extschema@.pathman_config WHERE partrel = parent_relid ;
107+ IF part_attname IS NULL THEN
108+ RAISE EXCEPTION ' table "%" is not partitioned' , parent_relid ::TEXT ;
119109 END IF;
120110
121- /* Calculate partitions count and old partition's number */
122- v_part_count := count (* ) FROM @extschema@.pathman_partition_list WHERE parent = v_parent_relid;
123- v_part_num := @extschema@.get_partition_hash(v_parent_relid, old_partition);
111+ /* Fetch name of old_partition's HASH constraint */
112+ old_constr_name = @extschema@.build_check_constraint_name(old_partition::REGCLASS,
113+ part_attname);
114+
115+ /* Fetch definition of old_partition's HASH constraint */
116+ SELECT pg_catalog .pg_get_constraintdef (oid ) FROM pg_catalog .pg_constraint
117+ WHERE conrelid = old_partition AND conname = old_constr_name
118+ INTO old_constr_def;
124119
125120 /* 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)' ,
121+ EXECUTE format(' ALTER TABLE %s NO INHERIT %s' , old_partition, parent_relid);
122+ EXECUTE format(' ALTER TABLE %s DROP CONSTRAINT %s' ,
123+ old_partition,
124+ old_constr_name);
125+
126+ /* Attach the new one */
127+ EXECUTE format(' ALTER TABLE %s INHERIT %s' , new_partition, parent_relid);
128+ EXECUTE format(' ALTER TABLE %s ADD CONSTRAINT %s %s' ,
135129 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));
130+ @extschema@.build_check_constraint_name(new_partition::REGCLASS,
131+ part_attname),
132+ old_constr_def);
142133
143134 /* Fetch init_callback from 'params' table */
144135 WITH stub_callback(stub) as (values (0 ))
145136 SELECT coalesce(init_callback, 0 ::REGPROCEDURE)
146137 FROM stub_callback
147138 LEFT JOIN @extschema@.pathman_config_params AS params
148- ON params .partrel = v_parent_relid
149- INTO v_init_callback ;
139+ ON params .partrel = parent_relid
140+ INTO p_init_callback ;
150141
151- PERFORM @extschema@.invoke_on_partition_created_callback(v_parent_relid,
142+ /* Finally invoke init_callback */
143+ PERFORM @extschema@.invoke_on_partition_created_callback(parent_relid,
152144 new_partition,
153- v_init_callback );
145+ p_init_callback );
154146
155147 /* Invalidate cache */
156- PERFORM @extschema@.on_update_partitions(v_parent_relid );
148+ PERFORM @extschema@.on_update_partitions(parent_relid );
157149
158150 RETURN new_partition;
159151END
@@ -292,3 +284,14 @@ LANGUAGE C STRICT;
292284CREATE OR REPLACE FUNCTION @extschema@.get_hash_part_idx(INTEGER , INTEGER )
293285RETURNS INTEGER AS ' pg_pathman' , ' get_hash_part_idx'
294286LANGUAGE C STRICT;
287+
288+ /*
289+ * Build hash condition for a CHECK CONSTRAINT
290+ */
291+ CREATE OR REPLACE FUNCTION @extschema@.build_hash_condition(
292+ parent_relid REGCLASS,
293+ attribute TEXT ,
294+ part_count INT4,
295+ part_idx INT4)
296+ RETURNS TEXT AS ' pg_pathman' , ' build_hash_condition'
297+ LANGUAGE C STRICT;
0 commit comments