Skip to content

Commit 6b88f51

Browse files
committed
remove useless functions and dead code, refactoring and locks for function replace_hash_partition()
1 parent 87034f1 commit 6b88f51

File tree

3 files changed

+73
-121
lines changed

3 files changed

+73
-121
lines changed

hash.sql

Lines changed: 52 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,6 @@ CREATE OR REPLACE FUNCTION @extschema@.create_hash_partitions(
1818
partition_data BOOLEAN DEFAULT TRUE)
1919
RETURNS 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-
2921
BEGIN
3022
PERFORM @extschema@.validate_relname(parent_relid);
3123

@@ -40,13 +32,6 @@ BEGIN
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(
8267
RETURNS REGCLASS AS
8368
$$
8469
DECLARE
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+
9177
BEGIN
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;
159151
END
@@ -292,3 +284,14 @@ LANGUAGE C STRICT;
292284
CREATE OR REPLACE FUNCTION @extschema@.get_hash_part_idx(INTEGER, INTEGER)
293285
RETURNS INTEGER AS 'pg_pathman', 'get_hash_part_idx'
294286
LANGUAGE 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;

init.sql

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -783,23 +783,3 @@ CREATE OR REPLACE FUNCTION @extschema@.invoke_on_partition_created_callback(
783783
init_callback REGPROCEDURE)
784784
RETURNS VOID AS 'pg_pathman', 'invoke_on_partition_created_callback'
785785
LANGUAGE C;
786-
787-
/*
788-
* Build hash condition for a CHECK CONSTRAINT
789-
*/
790-
CREATE OR REPLACE FUNCTION @extschema@.build_hash_condition(
791-
parent_relid REGCLASS,
792-
attname TEXT,
793-
partitions_count INT,
794-
partition_number INT)
795-
RETURNS TEXT AS 'pg_pathman', 'build_hash_condition'
796-
LANGUAGE C;
797-
798-
/*
799-
* Returns hash value for specified partition (0..N)
800-
*/
801-
CREATE OR REPLACE FUNCTION @extschema@.get_partition_hash(
802-
parent_relid REGCLASS,
803-
partition REGCLASS)
804-
RETURNS INT AS 'pg_pathman', 'get_partition_hash'
805-
LANGUAGE C;

src/pl_hash_funcs.c

Lines changed: 21 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@
2222
/* Function declarations */
2323

2424
PG_FUNCTION_INFO_V1( create_hash_partitions_internal );
25+
2526
PG_FUNCTION_INFO_V1( get_type_hash_func );
2627
PG_FUNCTION_INFO_V1( get_hash_part_idx );
28+
2729
PG_FUNCTION_INFO_V1( build_hash_condition );
28-
PG_FUNCTION_INFO_V1( get_partition_hash );
2930

3031

3132
/*
@@ -90,68 +91,36 @@ get_hash_part_idx(PG_FUNCTION_ARGS)
9091
Datum
9192
build_hash_condition(PG_FUNCTION_ARGS)
9293
{
94+
Oid parent = PG_GETARG_OID(0);
95+
text *attname = PG_GETARG_TEXT_P(1);
96+
uint32 part_count = PG_GETARG_UINT32(2);
97+
uint32 part_idx = PG_GETARG_UINT32(3);
98+
9399
TypeCacheEntry *tce;
100+
Oid attype;
101+
char *attname_cstring = text_to_cstring(attname);
94102

95-
Oid parent = PG_GETARG_OID(0);
96-
text *attname = PG_GETARG_TEXT_P(1);
97-
uint32 partitions_count = PG_GETARG_UINT32(2);
98-
uint32 partition_number = PG_GETARG_UINT32(3);
99-
Oid attyp;
100-
char *result;
103+
char *result;
101104

102-
if (partition_number >= partitions_count)
103-
elog(ERROR,
104-
"Partition number cannot exceed partitions count");
105+
if (part_idx >= part_count)
106+
elog(ERROR, "'part_idx' must be lower than 'part_count'");
105107

106108
/* Get attribute type and its hash function oid */
107-
attyp = get_attribute_type(parent, text_to_cstring(attname), false);
108-
if (attyp == InvalidOid)
109-
elog(ERROR,
110-
"Relation '%s' has no attribute '%s'",
111-
get_rel_name(parent),
112-
text_to_cstring(attname));
109+
attype = get_attribute_type(parent, attname_cstring, false);
110+
if (attype == InvalidOid)
111+
elog(ERROR, "relation \"%s\" has no attribute \"%s\"",
112+
get_rel_name(parent),
113+
attname_cstring);
113114

114-
tce = lookup_type_cache(attyp, TYPECACHE_HASH_PROC);
115+
tce = lookup_type_cache(attype, TYPECACHE_HASH_PROC);
115116

116117
/* Create hash condition CSTRING */
117118
result = psprintf("%s.get_hash_part_idx(%s(%s), %u) = %u",
118119
get_namespace_name(get_pathman_schema()),
119120
get_func_name(tce->hash_proc),
120-
text_to_cstring(attname),
121-
partitions_count,
122-
partition_number);
121+
attname_cstring,
122+
part_count,
123+
part_idx);
123124

124125
PG_RETURN_TEXT_P(cstring_to_text(result));
125126
}
126-
127-
/*
128-
* Returns hash value for specified partition (0..N)
129-
*/
130-
Datum
131-
get_partition_hash(PG_FUNCTION_ARGS)
132-
{
133-
const PartRelationInfo *prel;
134-
Oid parent = PG_GETARG_OID(0);
135-
Oid partition = PG_GETARG_OID(1);
136-
Oid *children;
137-
int i;
138-
139-
/* Validate partition type */
140-
prel = get_pathman_relation_info(parent);
141-
if (!prel || prel->parttype != PT_HASH)
142-
elog(ERROR,
143-
"Relation '%s' isn't partitioned by hash",
144-
get_rel_name(parent));
145-
146-
/* Searching for partition */
147-
children = PrelGetChildrenArray(prel);
148-
for (i=0; i<prel->children_count; i++)
149-
if (children[i] == partition)
150-
PG_RETURN_UINT32(i);
151-
152-
/* If we get here then there is no such partition for specified parent */
153-
elog(ERROR,
154-
"Relation '%s' isn't a part of partitioned table '%s'",
155-
get_rel_name(parent),
156-
get_rel_name(partition));
157-
}

0 commit comments

Comments
 (0)