Skip to content

Commit 01ff60b

Browse files
committed
added relnames and tablespaces arguments to create_range_partitions_internal() function
1 parent bf219ed commit 01ff60b

File tree

5 files changed

+160
-141
lines changed

5 files changed

+160
-141
lines changed

range.sql

Lines changed: 44 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,29 @@ BEGIN
6060
END
6161
$$ LANGUAGE plpgsql;
6262

63+
64+
CREATE OR REPLACE FUNCTION @extschema@.prepare_for_partitioning(
65+
parent_relid REGCLASS,
66+
attribute TEXT,
67+
partition_data BOOLEAN)
68+
RETURNS VOID AS
69+
$$
70+
BEGIN
71+
PERFORM @extschema@.validate_relname(parent_relid);
72+
73+
IF partition_data = true THEN
74+
/* Acquire data modification lock */
75+
PERFORM @extschema@.prevent_relation_modification(parent_relid);
76+
ELSE
77+
/* Acquire lock on parent */
78+
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
79+
END IF;
80+
81+
attribute := lower(attribute);
82+
PERFORM @extschema@.common_relation_checks(parent_relid, attribute);
83+
END
84+
$$ LANGUAGE plpgsql;
85+
6386
/*
6487
* Creates RANGE partitions for specified relation based on datetime attribute
6588
*/
@@ -81,18 +104,8 @@ DECLARE
81104
i INTEGER;
82105

83106
BEGIN
84-
PERFORM @extschema@.validate_relname(parent_relid);
85-
86-
IF partition_data = true THEN
87-
/* Acquire data modification lock */
88-
PERFORM @extschema@.prevent_relation_modification(parent_relid);
89-
ELSE
90-
/* Acquire lock on parent */
91-
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
92-
END IF;
93-
94107
attribute := lower(attribute);
95-
PERFORM @extschema@.common_relation_checks(parent_relid, attribute);
108+
PERFORM @extschema@.prepare_for_partitioning(parent_relid, attribute, partition_data);
96109

97110
IF p_count < 0 THEN
98111
RAISE EXCEPTION '"p_count" must not be less than 0';
@@ -196,18 +209,8 @@ DECLARE
196209
i INTEGER;
197210

198211
BEGIN
199-
PERFORM @extschema@.validate_relname(parent_relid);
200-
201-
IF partition_data = true THEN
202-
/* Acquire data modification lock */
203-
PERFORM @extschema@.prevent_relation_modification(parent_relid);
204-
ELSE
205-
/* Acquire lock on parent */
206-
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
207-
END IF;
208-
209212
attribute := lower(attribute);
210-
PERFORM @extschema@.common_relation_checks(parent_relid, attribute);
213+
PERFORM @extschema@.prepare_for_partitioning(parent_relid, attribute, partition_data);
211214

212215
IF p_count < 0 THEN
213216
RAISE EXCEPTION 'partitions count must not be less than zero';
@@ -304,18 +307,8 @@ DECLARE
304307
part_count INTEGER := 0;
305308

306309
BEGIN
307-
PERFORM @extschema@.validate_relname(parent_relid);
308-
309-
IF partition_data = true THEN
310-
/* Acquire data modification lock */
311-
PERFORM @extschema@.prevent_relation_modification(parent_relid);
312-
ELSE
313-
/* Acquire lock on parent */
314-
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
315-
END IF;
316-
317310
attribute := lower(attribute);
318-
PERFORM @extschema@.common_relation_checks(parent_relid, attribute);
311+
PERFORM @extschema@.prepare_for_partitioning(parent_relid, attribute, partition_data);
319312

320313
/* Check boundaries */
321314
PERFORM @extschema@.check_boundaries(parent_relid,
@@ -374,18 +367,8 @@ DECLARE
374367
part_count INTEGER := 0;
375368

376369
BEGIN
377-
PERFORM @extschema@.validate_relname(parent_relid);
378-
379-
IF partition_data = true THEN
380-
/* Acquire data modification lock */
381-
PERFORM @extschema@.prevent_relation_modification(parent_relid);
382-
ELSE
383-
/* Acquire lock on parent */
384-
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
385-
END IF;
386-
387370
attribute := lower(attribute);
388-
PERFORM @extschema@.common_relation_checks(parent_relid, attribute);
371+
PERFORM @extschema@.prepare_for_partitioning(parent_relid, attribute, partition_data);
389372

390373
/* Check boundaries */
391374
PERFORM @extschema@.check_boundaries(parent_relid,
@@ -435,7 +418,10 @@ $$ LANGUAGE plpgsql;
435418
CREATE OR REPLACE FUNCTION @extschema@.create_range_partitions2(
436419
parent_relid REGCLASS,
437420
attribute TEXT,
438-
bounds ANYARRAY)
421+
bounds ANYARRAY,
422+
relnames TEXT[] DEFAULT NULL,
423+
tablespaces TEXT[] DEFAULT NULL,
424+
partition_data BOOLEAN DEFAULT TRUE)
439425
RETURNS INTEGER AS
440426
$$
441427
DECLARE
@@ -449,18 +435,8 @@ BEGIN
449435
RAISE EXCEPTION 'Bounds array must have at least two values';
450436
END IF;
451437

452-
PERFORM @extschema@.validate_relname(parent_relid);
453-
454-
IF partition_data = true THEN
455-
/* Acquire data modification lock */
456-
PERFORM @extschema@.prevent_relation_modification(parent_relid);
457-
ELSE
458-
/* Acquire lock on parent */
459-
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
460-
END IF;
461-
462438
attribute := lower(attribute);
463-
PERFORM @extschema@.common_relation_checks(parent_relid, attribute);
439+
PERFORM @extschema@.prepare_for_partitioning(parent_relid, attribute, partition_data);
464440

465441
/* Check boundaries */
466442
PERFORM @extschema@.check_boundaries(parent_relid,
@@ -476,7 +452,10 @@ BEGIN
476452
FROM @extschema@.get_plain_schema_and_relname(parent_relid);
477453

478454
/* Create partitions */
479-
part_count := @extschema@.create_range_partitions_internal(parent_relid, bounds);
455+
part_count := @extschema@.create_range_partitions_internal(parent_relid,
456+
bounds,
457+
relnames,
458+
tablespaces);
480459

481460
/* Notify backend about changes */
482461
PERFORM @extschema@.on_create_partitions(parent_relid);
@@ -489,15 +468,17 @@ BEGIN
489468
PERFORM @extschema@.set_enable_parent(parent_relid, true);
490469
END IF;
491470

492-
RETURN 0;
471+
RETURN part_count;
493472
END
494473
$$
495474
LANGUAGE plpgsql;
496475

497476

498477
CREATE OR REPLACE FUNCTION @extschema@.create_range_partitions_internal(
499478
parent_relid REGCLASS,
500-
value ANYARRAY)
479+
bounds ANYARRAY,
480+
relnames TEXT[],
481+
tablespaces TEXT[])
501482
RETURNS REGCLASS AS 'pg_pathman', 'create_range_partitions_internal'
502483
LANGUAGE C;
503484

@@ -640,7 +621,8 @@ BEGIN
640621

641622
v_atttype := @extschema@.get_partition_key_type(parent_relid);
642623

643-
IF NOT @extschema@.is_operator_supported(v_atttype, '+') THEN
624+
IF NOT @extschema@.is_date_type(v_atttype) AND
625+
NOT @extschema@.is_operator_supported(v_atttype, '+') THEN
644626
RAISE EXCEPTION 'Type % doesn''t support ''+'' operator', v_atttype::regtype;
645627
END IF;
646628

@@ -749,7 +731,8 @@ BEGIN
749731

750732
v_atttype := @extschema@.get_partition_key_type(parent_relid);
751733

752-
IF NOT @extschema@.is_operator_supported(v_atttype, '-') THEN
734+
IF NOT @extschema@.is_date_type(v_atttype) AND
735+
NOT @extschema@.is_operator_supported(v_atttype, '-') THEN
753736
RAISE EXCEPTION 'Type % doesn''t support ''-'' operator', v_atttype::regtype;
754737
END IF;
755738

src/include/utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ Datum perform_type_cast(Datum value, Oid in_type, Oid out_type, bool *success);
6363
Datum extract_binary_interval_from_text(Datum interval_text,
6464
Oid part_atttype,
6565
Oid *interval_type);
66-
66+
char **deconstruct_text_array(Datum array, int *array_size);
67+
RangeVar ** qualified_relnames_to_rangevars(char **relnames, size_t nrelnames);
6768

6869

6970
#endif /* PATHMAN_UTILS_H */

src/pl_hash_funcs.c

Lines changed: 1 addition & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include "relation_info.h"
1414
#include "utils.h"
1515

16-
#include "catalog/namespace.h"
1716
#include "catalog/pg_type.h"
1817
#include "utils/builtins.h"
1918
#include "utils/typcache.h"
@@ -22,9 +21,6 @@
2221
#include "utils/array.h"
2322

2423

25-
static char **deconstruct_text_array(Datum array, int *array_size);
26-
27-
2824
/* Function declarations */
2925

3026
PG_FUNCTION_INFO_V1( create_hash_partitions_internal );
@@ -89,16 +85,7 @@ create_hash_partitions_internal(PG_FUNCTION_ARGS)
8985
elog(ERROR, "size of 'tablespaces' must be equal to 'partitions_count'");
9086

9187
/* Convert partition names into RangeVars */
92-
if (partition_names)
93-
{
94-
rangevars = palloc(sizeof(RangeVar) * partition_names_size);
95-
for (i = 0; i < partition_names_size; i++)
96-
{
97-
List *nl = stringToQualifiedNameList(partition_names[i]);
98-
99-
rangevars[i] = makeRangeVarFromNameList(nl);
100-
}
101-
}
88+
rangevars = qualified_relnames_to_rangevars(partition_names, partitions_count);
10289

10390
/* Finally create HASH partitions */
10491
for (i = 0; i < partitions_count; i++)
@@ -181,64 +168,3 @@ build_hash_condition(PG_FUNCTION_ARGS)
181168

182169
PG_RETURN_TEXT_P(cstring_to_text(result));
183170
}
184-
185-
186-
/*
187-
* ------------------
188-
* Helper functions
189-
* ------------------
190-
*/
191-
192-
/* Convert Datum into CSTRING array */
193-
static char **
194-
deconstruct_text_array(Datum array, int *array_size)
195-
{
196-
ArrayType *array_ptr = DatumGetArrayTypeP(array);
197-
int16 elemlen;
198-
bool elembyval;
199-
char elemalign;
200-
201-
Datum *elem_values;
202-
bool *elem_nulls;
203-
204-
int arr_size = 0;
205-
206-
/* Check type invariant */
207-
Assert(ARR_ELEMTYPE(array_ptr) == TEXTOID);
208-
209-
/* Check number of dimensions */
210-
if (ARR_NDIM(array_ptr) > 1)
211-
elog(ERROR, "'partition_names' and 'tablespaces' may contain only 1 dimension");
212-
213-
get_typlenbyvalalign(ARR_ELEMTYPE(array_ptr),
214-
&elemlen, &elembyval, &elemalign);
215-
216-
deconstruct_array(array_ptr,
217-
ARR_ELEMTYPE(array_ptr),
218-
elemlen, elembyval, elemalign,
219-
&elem_values, &elem_nulls, &arr_size);
220-
221-
/* If there are actual values, convert them into CSTRINGs */
222-
if (arr_size > 0)
223-
{
224-
char **strings = palloc(arr_size * sizeof(char *));
225-
int i;
226-
227-
for (i = 0; i < arr_size; i++)
228-
{
229-
if (elem_nulls[i])
230-
elog(ERROR, "'partition_names' and 'tablespaces' may not contain NULLs");
231-
232-
strings[i] = TextDatumGetCString(elem_values[i]);
233-
}
234-
235-
/* Return an array and it's size */
236-
*array_size = arr_size;
237-
return strings;
238-
}
239-
/* Else emit ERROR */
240-
else elog(ERROR, "'partition_names' and 'tablespaces' may not be empty");
241-
242-
/* Keep compiler happy */
243-
return NULL;
244-
}

src/pl_range_funcs.c

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,12 +1015,18 @@ Datum
10151015
create_range_partitions_internal(PG_FUNCTION_ARGS)
10161016
{
10171017
Oid relid = PG_GETARG_OID(0);
1018-
// char *attname = TextDatumGetCString(PG_GETARG_TEXT_P(1));
10191018
int16 typlen;
10201019
bool typbyval;
10211020
char typalign;
10221021
FmgrInfo cmp_func;
10231022

1023+
/* partition names and tablespaces */
1024+
char **partnames = NULL;
1025+
RangeVar **rangevars = NULL;
1026+
char **tablespaces = NULL;
1027+
int npartnames = 0;
1028+
int ntablespaces = 0;
1029+
10241030
/* bounds */
10251031
ArrayType *arr = PG_GETARG_ARRAYTYPE_P(1);
10261032
Oid elemtype = ARR_ELEMTYPE(arr);
@@ -1029,12 +1035,33 @@ create_range_partitions_internal(PG_FUNCTION_ARGS)
10291035
int ndatums;
10301036
int i;
10311037

1038+
/* Extract partition names */
1039+
if (!PG_ARGISNULL(2))
1040+
{
1041+
partnames = deconstruct_text_array(PG_GETARG_DATUM(2), &npartnames);
1042+
rangevars = qualified_relnames_to_rangevars(partnames, npartnames);
1043+
}
1044+
1045+
/* Extract partition tablespaces */
1046+
if (!PG_ARGISNULL(3))
1047+
tablespaces = deconstruct_text_array(PG_GETARG_DATUM(3), &ntablespaces);
1048+
10321049
/* Extract bounds */
10331050
get_typlenbyvalalign(elemtype, &typlen, &typbyval, &typalign);
10341051
deconstruct_array(arr, elemtype,
10351052
typlen, typbyval, typalign,
10361053
&datums, &nulls, &ndatums);
10371054

1055+
if (partnames && npartnames != ndatums-1)
1056+
ereport(ERROR, (errmsg("wrong length of relnames array"),
1057+
errdetail("relnames number must be less than "
1058+
"bounds array length by one")));
1059+
1060+
if (tablespaces && ntablespaces != ndatums-1)
1061+
ereport(ERROR, (errmsg("wrong length of tablespaces array"),
1062+
errdetail("tablespaces number must be less than "
1063+
"bounds array length by one")));
1064+
10381065
/* Check if bounds array is ascending */
10391066
fill_type_cmp_fmgr_info(&cmp_func,
10401067
getBaseType(elemtype),
@@ -1069,14 +1096,16 @@ create_range_partitions_internal(PG_FUNCTION_ARGS)
10691096
Bound end = nulls[i+1] ?
10701097
MakeBoundInf(PLUS_INFINITY) :
10711098
MakeBound(datums[i+1]);
1099+
RangeVar *rv = npartnames > 0 ? rangevars[i] : NULL;
1100+
char *tablespace = ntablespaces > 0 ? tablespaces[i] : NULL;
10721101

10731102
(void) create_single_range_partition_internal(relid,
10741103
&start,
10751104
&end,
10761105
elemtype,
1077-
NULL,
1078-
NULL);
1106+
rv,
1107+
tablespace);
10791108
}
10801109

1081-
PG_RETURN_VOID();
1110+
PG_RETURN_INT32(ndatums-1);
10821111
}

0 commit comments

Comments
 (0)