Skip to content

Commit ab15bee

Browse files
committed
rewrited create_range_partitions() funcs using internal C function
1 parent 01ff60b commit ab15bee

File tree

2 files changed

+103
-37
lines changed

2 files changed

+103
-37
lines changed

range.sql

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,14 @@ CREATE OR REPLACE FUNCTION @extschema@.create_range_partitions(
9696
RETURNS INTEGER AS
9797
$$
9898
DECLARE
99-
v_rows_count BIGINT;
100-
v_atttype REGTYPE;
101-
v_max start_value%TYPE;
102-
v_cur_value start_value%TYPE := start_value;
103-
end_value start_value%TYPE;
104-
i INTEGER;
99+
v_rows_count BIGINT;
100+
v_atttype REGTYPE;
101+
v_tablespace TEXT;
102+
v_max start_value%TYPE;
103+
v_cur_value start_value%TYPE := start_value;
104+
end_value start_value%TYPE;
105+
part_count INTEGER;
106+
i INTEGER;
105107

106108
BEGIN
107109
attribute := lower(attribute);
@@ -159,20 +161,11 @@ BEGIN
159161
PERFORM @extschema@.create_or_replace_sequence(parent_relid)
160162
FROM @extschema@.get_plain_schema_and_relname(parent_relid);
161163

162-
/* Create first partition */
163-
FOR i IN 1..p_count
164-
LOOP
165-
EXECUTE
166-
format('SELECT @extschema@.create_single_range_partition($1, $2, $3::%s, tablespace:=$4)',
167-
v_atttype::TEXT)
168-
USING
169-
parent_relid,
170-
start_value,
171-
start_value + p_interval,
172-
@extschema@.get_tablespace(parent_relid);
173-
174-
start_value := start_value + p_interval;
175-
END LOOP;
164+
part_count := @extschema@.create_range_partitions_internal(
165+
parent_relid,
166+
@extschema@.generate_bounds(start_value, p_interval, p_count),
167+
NULL,
168+
NULL);
176169

177170
/* Notify backend about changes */
178171
PERFORM @extschema@.on_create_partitions(parent_relid);
@@ -185,7 +178,7 @@ BEGIN
185178
PERFORM @extschema@.set_enable_parent(parent_relid, true);
186179
END IF;
187180

188-
RETURN p_count;
181+
RETURN part_count;
189182
END
190183
$$ LANGUAGE plpgsql;
191184

@@ -202,11 +195,12 @@ CREATE OR REPLACE FUNCTION @extschema@.create_range_partitions(
202195
RETURNS INTEGER AS
203196
$$
204197
DECLARE
205-
v_rows_count BIGINT;
206-
v_max start_value%TYPE;
207-
v_cur_value start_value%TYPE := start_value;
208-
end_value start_value%TYPE;
209-
i INTEGER;
198+
v_rows_count BIGINT;
199+
v_max start_value%TYPE;
200+
v_cur_value start_value%TYPE := start_value;
201+
end_value start_value%TYPE;
202+
part_count INTEGER;
203+
i INTEGER;
210204

211205
BEGIN
212206
attribute := lower(attribute);
@@ -264,17 +258,11 @@ BEGIN
264258
PERFORM @extschema@.create_or_replace_sequence(parent_relid)
265259
FROM @extschema@.get_plain_schema_and_relname(parent_relid);
266260

267-
/* create first partition */
268-
FOR i IN 1..p_count
269-
LOOP
270-
PERFORM @extschema@.create_single_range_partition(
271-
parent_relid,
272-
start_value,
273-
start_value + p_interval,
274-
tablespace := @extschema@.get_tablespace(parent_relid));
275-
276-
start_value := start_value + p_interval;
277-
END LOOP;
261+
part_count := @extschema@.create_range_partitions_internal(
262+
parent_relid,
263+
@extschema@.generate_bounds(start_value, p_interval, p_count),
264+
NULL,
265+
NULL);
278266

279267
/* Notify backend about changes */
280268
PERFORM @extschema@.on_create_partitions(parent_relid);
@@ -483,6 +471,22 @@ RETURNS REGCLASS AS 'pg_pathman', 'create_range_partitions_internal'
483471
LANGUAGE C;
484472

485473

474+
CREATE OR REPLACE FUNCTION @extschema@.generate_bounds(
475+
p_start ANYELEMENT,
476+
p_interval INTERVAL,
477+
p_count INTEGER)
478+
RETURNS ANYARRAY AS 'pg_pathman', 'generate_bounds'
479+
LANGUAGE C;
480+
481+
482+
CREATE OR REPLACE FUNCTION @extschema@.generate_bounds(
483+
p_start ANYELEMENT,
484+
p_interval ANYELEMENT,
485+
p_count INTEGER)
486+
RETURNS ANYARRAY AS 'pg_pathman', 'generate_bounds'
487+
LANGUAGE C;
488+
489+
486490
/*
487491
* Split RANGE partition
488492
*/

src/pl_range_funcs.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ PG_FUNCTION_INFO_V1( drop_range_partition_expand_next );
7070
PG_FUNCTION_INFO_V1( validate_interval_value );
7171

7272
PG_FUNCTION_INFO_V1( create_range_partitions_internal );
73+
PG_FUNCTION_INFO_V1( generate_bounds );
7374

7475

7576
/*
@@ -1109,3 +1110,64 @@ create_range_partitions_internal(PG_FUNCTION_ARGS)
11091110

11101111
PG_RETURN_INT32(ndatums-1);
11111112
}
1113+
1114+
1115+
Datum
1116+
generate_bounds(PG_FUNCTION_ARGS)
1117+
{
1118+
/* input params */
1119+
Datum value = PG_GETARG_DATUM(0);
1120+
Oid v_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
1121+
Datum interval = PG_GETARG_DATUM(1);
1122+
Oid i_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
1123+
int count = PG_GETARG_INT32(2);
1124+
int i;
1125+
1126+
/* operator */
1127+
Oid plus_op_func;
1128+
Datum plus_op_result;
1129+
Oid plus_op_result_type;
1130+
1131+
/* array */
1132+
ArrayType *arr;
1133+
int16 elemlen;
1134+
bool elembyval;
1135+
char elemalign;
1136+
Datum *datums;
1137+
1138+
if (count < 1)
1139+
elog(ERROR, "Partitions count must be greater than zero");
1140+
1141+
/* Find suitable addition operator for given value and interval */
1142+
extract_op_func_and_ret_type("+", v_type, i_type,
1143+
&plus_op_func,
1144+
&plus_op_result_type);
1145+
1146+
get_typlenbyvalalign(v_type, &elemlen, &elembyval, &elemalign);
1147+
1148+
datums = palloc(sizeof(Datum) * (count + 1));
1149+
// datums[0] = datumCopy(value, elembyval, elemlen);
1150+
datums[0] = value;
1151+
1152+
/* calculate bounds */
1153+
for (i = 1; i <= count; i++)
1154+
{
1155+
/* Invoke addition operator and get a result */
1156+
plus_op_result = OidFunctionCall2(plus_op_func, value, interval);
1157+
1158+
if (plus_op_result_type != v_type)
1159+
plus_op_result = perform_type_cast(plus_op_result,
1160+
plus_op_result_type,
1161+
v_type, NULL);
1162+
1163+
value = datums[i] = plus_op_result;
1164+
}
1165+
1166+
/* build an array based on calculated datums */
1167+
arr = construct_array(datums, count + 1, v_type,
1168+
elemlen, elembyval, elemalign);
1169+
1170+
pfree(datums);
1171+
1172+
PG_RETURN_ARRAYTYPE_P(arr);
1173+
}

0 commit comments

Comments
 (0)