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