-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathhash.sql
More file actions
132 lines (110 loc) · 3.8 KB
/
hash.sql
File metadata and controls
132 lines (110 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* ------------------------------------------------------------------------
*
* hash.sql
* HASH sharding functions
*
* Copyright (c) 2017, Postgres Professional
*
* ------------------------------------------------------------------------
*/
/*
* Creates foreign hash partitions for specified relation
*/
CREATE OR REPLACE FUNCTION @extschema@.create_foreign_hash_partitions(
parent_relid REGCLASS,
attribute TEXT,
partitions_count INT4,
foreign_servers TEXT[],
partition_data BOOLEAN DEFAULT TRUE,
partition_names TEXT[] DEFAULT NULL,
distibution_proc REGPROC DEFAULT '@extschema@.distribute_partitions_among_servers')
RETURNS INTEGER AS
$$
DECLARE
v_partition_relid REGCLASS;
v_part_name TEXT;
v_foreign_server TEXT;
v_check_name TEXT;
v_cond TEXT;
v_atttype REGTYPE;
cur_partition_idx INT4 := 0;
BEGIN
PERFORM @extschema@.validate_relname(parent_relid);
IF partition_data = true THEN
/* Acquire data modification lock */
PERFORM @extschema@.prevent_relation_modification(parent_relid);
ELSE
/* Acquire lock on parent */
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
END IF;
attribute := lower(attribute);
PERFORM @extschema@.common_relation_checks(parent_relid, attribute);
/* Check if foreign servers array is null */
IF foreign_servers IS NULL THEN
RAISE EXCEPTION '"foreign_servers" should not be NULL';
END IF;
/* Check dimensions of foreign servers array */
IF array_ndims(foreign_servers) IS NULL OR
array_ndims(foreign_servers) != 1 THEN
RAISE EXCEPTION '"foreign_servers" should have exactly 1 dimension';
END IF;
/* Check if foreign servers array is empty */
IF array_length(foreign_servers, 1) = 0 THEN
RAISE EXCEPTION '"foreign_servers" should not be empty';
END IF;
/* Build partition names if needed */
IF partition_names IS NULL THEN
SELECT array_agg(quote_ident(schema) || '.' ||
quote_ident(relname || '_' ||
partition_idx))
FROM @extschema@.get_plain_schema_and_relname(parent_relid),
generate_series(1, partitions_count) AS partition_idx
INTO partition_names;
ELSE
IF array_ndims(partition_names) IS NULL OR
array_ndims(partition_names) != 1 THEN
RAISE EXCEPTION '"partition_names" should have exactly 1 dimension';
END IF;
IF array_length(partition_names, 1) != partitions_count THEN
RAISE EXCEPTION '"partition_names" should have exactly "partitions_count" members';
END IF;
END IF;
/* Insert new entry to pathman config */
INSERT INTO @extschema@.pathman_config (partrel, attname, parttype)
VALUES (parent_relid, attribute, 1);
/* Create partitions */
FOR v_part_name, v_foreign_server IN
EXECUTE format('SELECT * FROM %s($1, $2)', distibution_proc)
USING partition_names, foreign_servers
LOOP
EXECUTE format('CREATE FOREIGN TABLE %s() INHERITS (%s) SERVER %s',
v_part_name,
parent_relid::TEXT,
v_foreign_server);
v_partition_relid := v_part_name::REGCLASS;
SELECT @extschema@.get_base_type(atttypid) FROM pg_catalog.pg_attribute
WHERE attname = attribute AND attrelid = parent_relid
INTO v_atttype;
v_cond := @extschema@.build_hash_condition(v_atttype,
attribute,
partitions_count,
cur_partition_idx);
v_check_name := @extschema@.build_check_constraint_name(v_partition_relid,
attribute);
EXECUTE format('ALTER TABLE %s ADD CONSTRAINT %s CHECK (%s)',
v_partition_relid,
v_check_name,
v_cond);
cur_partition_idx := cur_partition_idx + 1;
END LOOP;
/* Copy data */
IF partition_data = true THEN
PERFORM @extschema@.set_enable_parent(parent_relid, false);
PERFORM @extschema@.partition_data(parent_relid);
ELSE
PERFORM @extschema@.set_enable_parent(parent_relid, true);
END IF;
RETURN partitions_count;
END
$$ LANGUAGE plpgsql
SET client_min_messages = WARNING;