Skip to content

Commit c4723e3

Browse files
committed
improve functions validate_interval_value() & set_interval()
1 parent 05caed2 commit c4723e3

File tree

7 files changed

+105
-41
lines changed

7 files changed

+105
-41
lines changed

expected/pathman_calamity.out

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,34 @@ NOTICE: function calamity.part_test_upd_trig_func() does not exist, skipping
132132
4
133133
(1 row)
134134

135+
DELETE FROM calamity.part_test;
136+
/* check function validate_interval_value() */
137+
SELECT set_interval('pg_catalog.pg_class', 100); /* not ok */
138+
ERROR: table "pg_class" is not partitioned by RANGE
139+
INSERT INTO calamity.part_test SELECT generate_series(1, 30);
140+
SELECT create_range_partitions('calamity.part_test', 'val', 1, 10);
141+
create_range_partitions
142+
-------------------------
143+
3
144+
(1 row)
145+
146+
SELECT set_interval('calamity.part_test', 100); /* ok */
147+
set_interval
148+
--------------
149+
150+
(1 row)
151+
152+
SELECT set_interval('calamity.part_test', 15.6); /* not ok */
153+
ERROR: invalid input syntax for integer: "15.6"
154+
SELECT set_interval('calamity.part_test', 'abc'::text); /* not ok */
155+
ERROR: invalid input syntax for integer: "abc"
156+
SELECT drop_partitions('calamity.part_test', true);
157+
NOTICE: function calamity.part_test_upd_trig_func() does not exist, skipping
158+
drop_partitions
159+
-----------------
160+
3
161+
(1 row)
162+
135163
DELETE FROM calamity.part_test;
136164
/* check function build_hash_condition() */
137165
SELECT build_hash_condition('int4', 'val', 10, 1);

init.sql

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
* text to Datum
1616
*/
1717
CREATE OR REPLACE FUNCTION @extschema@.validate_interval_value(
18-
parent REGCLASS,
19-
interval_value TEXT)
18+
partrel REGCLASS,
19+
attname TEXT,
20+
parttype INTEGER,
21+
range_interval TEXT)
2022
RETURNS BOOL AS 'pg_pathman', 'validate_interval_value'
21-
LANGUAGE C STRICT;
23+
LANGUAGE C;
2224

2325

2426
/*
@@ -36,8 +38,14 @@ CREATE TABLE IF NOT EXISTS @extschema@.pathman_config (
3638
parttype INTEGER NOT NULL,
3739
range_interval TEXT,
3840

39-
CHECK (parttype IN (1, 2)), /* check for allowed part types */
40-
CHECK (@extschema@.validate_interval_value(partrel, range_interval))
41+
/* check for allowed part types */
42+
CHECK (parttype IN (1, 2)),
43+
44+
/* check for correct interval */
45+
CHECK (@extschema@.validate_interval_value(partrel,
46+
attname,
47+
parttype,
48+
range_interval))
4149
);
4250

4351

@@ -190,6 +198,31 @@ END
190198
$$
191199
LANGUAGE plpgsql STRICT;
192200

201+
/*
202+
* Set (or reset) default interval for auto created partitions
203+
*/
204+
CREATE OR REPLACE FUNCTION @extschema@.set_interval(
205+
relation REGCLASS,
206+
value ANYELEMENT)
207+
RETURNS VOID AS
208+
$$
209+
DECLARE
210+
affected INTEGER;
211+
BEGIN
212+
UPDATE @extschema@.pathman_config
213+
SET range_interval = value::text
214+
WHERE partrel = relation AND parttype = 2;
215+
216+
/* Check number of affected rows */
217+
GET DIAGNOSTICS affected = ROW_COUNT;
218+
219+
IF affected = 0 THEN
220+
RAISE EXCEPTION 'table "%" is not partitioned by RANGE', relation;
221+
END IF;
222+
END
223+
$$
224+
LANGUAGE plpgsql;
225+
193226

194227
/*
195228
* Show all existing parents and partitions.

range.sql

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -435,30 +435,6 @@ BEGIN
435435
END
436436
$$ LANGUAGE plpgsql;
437437

438-
439-
/*
440-
* Set (or reset) default interval for auto created partitions
441-
*/
442-
CREATE OR REPLACE FUNCTION @extschema@.set_interval(parent REGCLASS, value ANYELEMENT)
443-
RETURNS VOID AS
444-
$$
445-
DECLARE
446-
affected INTEGER;
447-
BEGIN
448-
UPDATE @extschema@.pathman_config
449-
SET range_interval = value::text
450-
WHERE partrel = parent;
451-
452-
GET DIAGNOSTICS affected = ROW_COUNT;
453-
454-
IF affected = 0 THEN
455-
RAISE EXCEPTION 'table "%" is not partitioned', parent;
456-
END IF;
457-
END
458-
$$
459-
LANGUAGE plpgsql;
460-
461-
462438
/*
463439
* Split RANGE partition
464440
*/

sql/pathman_calamity.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@ SELECT drop_partitions('calamity.part_test', true);
4545
DELETE FROM calamity.part_test;
4646

4747

48+
/* check function validate_interval_value() */
49+
SELECT set_interval('pg_catalog.pg_class', 100); /* not ok */
50+
51+
INSERT INTO calamity.part_test SELECT generate_series(1, 30);
52+
SELECT create_range_partitions('calamity.part_test', 'val', 1, 10);
53+
SELECT set_interval('calamity.part_test', 100); /* ok */
54+
SELECT set_interval('calamity.part_test', 15.6); /* not ok */
55+
SELECT set_interval('calamity.part_test', 'abc'::text); /* not ok */
56+
SELECT drop_partitions('calamity.part_test', true);
57+
DELETE FROM calamity.part_test;
58+
59+
4860
/* check function build_hash_condition() */
4961
SELECT build_hash_condition('int4', 'val', 10, 1);
5062
SELECT build_hash_condition('text', 'val', 10, 1);

src/pl_funcs.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -765,9 +765,7 @@ lock_partitioned_relation(PG_FUNCTION_ARGS)
765765
Datum
766766
prevent_relation_modification(PG_FUNCTION_ARGS)
767767
{
768-
Oid relid = PG_GETARG_OID(0);
769-
770-
(void) prevent_relation_modification_internal(relid);
768+
prevent_relation_modification_internal(PG_GETARG_OID(0));
771769

772770
PG_RETURN_VOID();
773771
}

src/pl_range_funcs.c

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -610,16 +610,33 @@ drop_range_partition_expand_next(PG_FUNCTION_ARGS)
610610
Datum
611611
validate_interval_value(PG_FUNCTION_ARGS)
612612
{
613-
const PartRelationInfo *prel;
614-
Oid parent = PG_GETARG_OID(0);
615-
Datum interval = PG_GETARG_DATUM(1);
613+
Oid partrel = PG_GETARG_OID(0);
614+
text *attname = PG_GETARG_TEXT_P(1);
615+
PartType parttype = DatumGetPartType(PG_GETARG_DATUM(2));
616+
Datum range_interval = PG_GETARG_DATUM(3);
616617

617-
/* TODO!!! */
618-
prel = get_pathman_relation_info(parent);
619-
if (!prel)
620-
PG_RETURN_BOOL(true);
618+
char *attname_cstr;
619+
Oid atttype; /* type of partitioned attribute */
620+
621+
if (PG_ARGISNULL(0))
622+
elog(ERROR, "'partrel' should not be NULL");
623+
624+
if (PG_ARGISNULL(1))
625+
elog(ERROR, "'attname' should not be NULL");
626+
627+
if (PG_ARGISNULL(2))
628+
elog(ERROR, "'parttype' should not be NULL");
629+
630+
/* it's OK if interval is NULL and table is HASH-partitioned */
631+
if (PG_ARGISNULL(3))
632+
PG_RETURN_BOOL(parttype == PT_HASH);
633+
634+
/* Convert attname to CSTRING and fetch column's type */
635+
attname_cstr = text_to_cstring(attname);
636+
atttype = get_attribute_type(partrel, attname_cstr, false);
621637

622-
extract_binary_interval_from_text(interval, prel->atttype, NULL);
638+
/* Try converting textual representation */
639+
extract_binary_interval_from_text(range_interval, atttype, NULL);
623640

624641
PG_RETURN_BOOL(true);
625642
}

src/utils.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ extract_binary_interval_from_text(Datum interval_text, /* interval as TEXT */
450450
ReleaseSysCache(htup);
451451
}
452452
else
453-
elog(ERROR, "Cannot find input function for type %u", part_atttype);
453+
elog(ERROR, "cannot find input function for type %u", part_atttype);
454454

455455
/*
456456
* Convert interval from CSTRING to 'prel->atttype'.

0 commit comments

Comments
 (0)