Skip to content

Commit b9b20ec

Browse files
committed
Merge branch 'rel_future_beta' of https://github.com/postgrespro/pg_pathman into rel_future_beta
2 parents 484551a + 609813b commit b9b20ec

15 files changed

+752
-426
lines changed

expected/pathman_basic.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1610,9 +1610,9 @@ NOTICE: sequence "zero_seq" does not exist, skipping
16101610
(1 row)
16111611

16121612
SELECT pathman.append_range_partition('test.zero', 'test.zero_0');
1613-
ERROR: cannot append to empty partitions set
1613+
ERROR: relation "zero" has no partitions
16141614
SELECT pathman.prepend_range_partition('test.zero', 'test.zero_1');
1615-
ERROR: cannot prepend to empty partitions set
1615+
ERROR: relation "zero" has no partitions
16161616
SELECT pathman.add_range_partition('test.zero', 50, 70, 'test.zero_50');
16171617
add_range_partition
16181618
---------------------

expected/pathman_calamity.out

Lines changed: 34 additions & 20 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);
@@ -230,26 +258,12 @@ SELECT get_base_type(NULL) IS NULL;
230258
t
231259
(1 row)
232260

233-
/* check function get_attribute_type() */
234-
SELECT get_attribute_type('calamity.part_test', 'val');
235-
get_attribute_type
236-
--------------------
237-
integer
238-
(1 row)
239-
240-
SELECT get_attribute_type('calamity.part_test', NULL) IS NULL;
241-
?column?
242-
----------
243-
t
244-
(1 row)
245-
246-
SELECT get_attribute_type(NULL, 'val') IS NULL;
247-
?column?
248-
----------
249-
t
250-
(1 row)
251-
252-
SELECT get_attribute_type(NULL, NULL) IS NULL;
261+
/* check function get_partition_key_type() */
262+
SELECT get_partition_key_type('calamity.part_test');
263+
ERROR: relation "part_test" has no partitions
264+
SELECT get_partition_key_type(0::regclass);
265+
ERROR: relation "0" has no partitions
266+
SELECT get_partition_key_type(NULL) IS NULL;
253267
?column?
254268
----------
255269
t

expected/pathman_inserts.out

Lines changed: 219 additions & 3 deletions
Large diffs are not rendered by default.

hash.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ BEGIN
261261
quote_ident(plain_relname || '_%s');
262262

263263
/* Fetch base hash function for atttype */
264-
atttype := @extschema@.get_attribute_type(parent_relid, attr);
264+
atttype := @extschema@.get_partition_key_type(parent_relid);
265265

266266
/* Format function definition and execute it */
267267
EXECUTE format(func, funcname, attr, partitions_count, att_val_fmt,

init.sql

Lines changed: 38 additions & 14 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.
@@ -704,15 +737,6 @@ CREATE OR REPLACE FUNCTION @extschema@.get_base_type(
704737
RETURNS REGTYPE AS 'pg_pathman', 'get_base_type_pl'
705738
LANGUAGE C STRICT;
706739

707-
/*
708-
* Returns attribute type name for relation.
709-
*/
710-
CREATE OR REPLACE FUNCTION @extschema@.get_attribute_type(
711-
relid REGCLASS,
712-
attname TEXT)
713-
RETURNS REGTYPE AS 'pg_pathman', 'get_attribute_type_pl'
714-
LANGUAGE C STRICT;
715-
716740
/*
717741
* Return partition key type
718742
*/

range.sql

Lines changed: 10 additions & 48 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
*/
@@ -488,22 +464,18 @@ BEGIN
488464
/* Acquire data modification lock (prevent further modifications) */
489465
PERFORM @extschema@.prevent_relation_modification(partition_relid);
490466

467+
v_atttype = @extschema@.get_partition_key_type(v_parent);
468+
491469
SELECT attname, parttype
492470
FROM @extschema@.pathman_config
493471
WHERE partrel = v_parent
494472
INTO v_attname, v_part_type;
495473

496-
IF v_attname IS NULL THEN
497-
RAISE EXCEPTION 'table "%" is not partitioned', v_parent::TEXT;
498-
END IF;
499-
500474
/* Check if this is a RANGE partition */
501475
IF v_part_type != 2 THEN
502476
RAISE EXCEPTION '"%" is not a RANGE partition', partition_relid::TEXT;
503477
END IF;
504478

505-
v_atttype = @extschema@.get_attribute_type(v_parent, v_attname);
506-
507479
/* Get partition values range */
508480
EXECUTE format('SELECT @extschema@.get_part_range($1, NULL::%s)',
509481
@extschema@.get_base_type(v_atttype)::TEXT)
@@ -589,7 +561,6 @@ CREATE OR REPLACE FUNCTION @extschema@.append_range_partition(
589561
RETURNS TEXT AS
590562
$$
591563
DECLARE
592-
v_attname TEXT;
593564
v_atttype REGTYPE;
594565
v_part_name TEXT;
595566
v_interval TEXT;
@@ -600,16 +571,12 @@ BEGIN
600571
/* Acquire lock on parent */
601572
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
602573

603-
SELECT attname, range_interval
574+
v_atttype := @extschema@.get_partition_key_type(parent_relid);
575+
576+
SELECT range_interval
604577
FROM @extschema@.pathman_config
605578
WHERE partrel = parent_relid
606-
INTO v_attname, v_interval;
607-
608-
IF v_attname IS NULL THEN
609-
RAISE EXCEPTION 'table "%" is not partitioned', parent_relid::TEXT;
610-
END IF;
611-
612-
v_atttype := @extschema@.get_attribute_type(parent_relid, v_attname);
579+
INTO v_interval;
613580

614581
EXECUTE
615582
format('SELECT @extschema@.append_partition_internal($1, $2, $3, ARRAY[]::%s[], $4, $5)',
@@ -700,7 +667,6 @@ CREATE OR REPLACE FUNCTION @extschema@.prepend_range_partition(
700667
RETURNS TEXT AS
701668
$$
702669
DECLARE
703-
v_attname TEXT;
704670
v_atttype REGTYPE;
705671
v_part_name TEXT;
706672
v_interval TEXT;
@@ -711,16 +677,12 @@ BEGIN
711677
/* Acquire lock on parent */
712678
PERFORM @extschema@.lock_partitioned_relation(parent_relid);
713679

714-
SELECT attname, range_interval
680+
v_atttype := @extschema@.get_partition_key_type(parent_relid);
681+
682+
SELECT range_interval
715683
FROM @extschema@.pathman_config
716684
WHERE partrel = parent_relid
717-
INTO v_attname, v_interval;
718-
719-
IF v_attname IS NULL THEN
720-
RAISE EXCEPTION 'table "%" is not partitioned', parent_relid::TEXT;
721-
END IF;
722-
723-
v_atttype := @extschema@.get_attribute_type(parent_relid, v_attname);
685+
INTO v_interval;
724686

725687
EXECUTE
726688
format('SELECT @extschema@.prepend_partition_internal($1, $2, $3, ARRAY[]::%s[], $4, $5)',

sql/pathman_calamity.sql

Lines changed: 16 additions & 5 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);
@@ -77,11 +89,10 @@ SELECT get_base_type('int4'::regtype);
7789
SELECT get_base_type('calamity.test_domain'::regtype);
7890
SELECT get_base_type(NULL) IS NULL;
7991

80-
/* check function get_attribute_type() */
81-
SELECT get_attribute_type('calamity.part_test', 'val');
82-
SELECT get_attribute_type('calamity.part_test', NULL) IS NULL;
83-
SELECT get_attribute_type(NULL, 'val') IS NULL;
84-
SELECT get_attribute_type(NULL, NULL) IS NULL;
92+
/* check function get_partition_key_type() */
93+
SELECT get_partition_key_type('calamity.part_test');
94+
SELECT get_partition_key_type(0::regclass);
95+
SELECT get_partition_key_type(NULL) IS NULL;
8596

8697
/* check function build_check_constraint_name_attnum() */
8798
SELECT build_check_constraint_name('calamity.part_test', 1::int2);

sql/pathman_inserts.sql

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,34 @@ INSERT INTO test_inserts.storage SELECT i * 2, i, i, i::text FROM generate_serie
1111
CREATE UNIQUE INDEX ON test_inserts.storage(a);
1212
SELECT create_range_partitions('test_inserts.storage', 'b', 1, 10);
1313

14+
/*
15+
* attach before and after insertion triggers to partitioned table
16+
*/
17+
/* prepare trigger functions */
18+
CREATE OR REPLACE FUNCTION test_inserts.print_cols_before_change() RETURNS TRIGGER AS $$
19+
BEGIN
20+
RAISE NOTICE 'BEFORE INSERTION TRIGGER ON TABLE % HAS EXPIRED. INSERTED ROW: %', tg_table_name, new;
21+
RETURN new;
22+
END;
23+
$$ LANGUAGE plpgsql;
24+
CREATE OR REPLACE FUNCTION test_inserts.print_cols_after_change() RETURNS TRIGGER AS $$
25+
BEGIN
26+
RAISE NOTICE 'AFTER INSERTION TRIGGER ON TABLE % HAS EXPIRED. INSERTED ROW: %', tg_table_name, new;
27+
RETURN new;
28+
END;
29+
$$ LANGUAGE plpgsql;
30+
/* set triggers on existing first partition and new generated partitions */
31+
CREATE TRIGGER print_new_row_before_insert BEFORE INSERT ON test_inserts.storage_1
32+
FOR EACH ROW EXECUTE PROCEDURE test_inserts.print_cols_before_change();
33+
CREATE TRIGGER print_new_row_after_insert AFTER INSERT ON test_inserts.storage_1
34+
FOR EACH ROW EXECUTE PROCEDURE test_inserts.print_cols_after_change();
35+
CREATE OR REPLACE FUNCTION test_inserts.set_triggers(args jsonb) RETURNS VOID AS $$
36+
BEGIN
37+
EXECUTE format('create trigger print_new_row_before_insert before insert on %s.%s for each row execute procedure test_inserts.print_cols_before_change();', args->>'partition_schema', args->>'partition');
38+
EXECUTE format('create trigger print_new_row_after_insert after insert on %s.%s for each row execute procedure test_inserts.print_cols_after_change();', args->>'partition_schema', args->>'partition');
39+
END;
40+
$$ LANGUAGE plpgsql;
41+
SELECT set_init_callback('test_inserts.storage', 'test_inserts.set_triggers');
1442

1543
/* we don't support ON CONLICT */
1644
INSERT INTO test_inserts.storage VALUES(0, 0, 0, 'UNSUPPORTED_1')
@@ -29,7 +57,7 @@ SELECT * FROM test_inserts.storage_11;
2957
INSERT INTO test_inserts.storage VALUES(3, 0, 0, 'PREPEND...') RETURNING a + b / 3;
3058
SELECT * FROM test_inserts.storage_11;
3159

32-
/* cause a conflict (a = 0) */
60+
/* cause an unique index conflict (a = 0) */
3361
INSERT INTO test_inserts.storage VALUES(0, 0, 0, 'CONFLICT') RETURNING *;
3462

3563

@@ -59,7 +87,7 @@ INSERT INTO test_inserts.storage VALUES(111, 0, 'DROP_COL_1...') RETURNING b * 2
5987
ALTER TABLE test_inserts.storage DROP COLUMN c CASCADE;
6088

6189

62-
/* will have 3 columns (b, c, d) */
90+
/* will have 2 columns (b, d) */
6391
SELECT append_range_partition('test_inserts.storage');
6492
INSERT INTO test_inserts.storage (b, d) VALUES (121, '2 cols!');
6593
SELECT * FROM test_inserts.storage_14; /* direct access */

0 commit comments

Comments
 (0)