Skip to content

Commit bea88a9

Browse files
committed
tests for zero partitions case
1 parent 0731552 commit bea88a9

File tree

5 files changed

+80
-24
lines changed

5 files changed

+80
-24
lines changed

init.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,15 @@ SELECT pg_catalog.pg_extension_config_dump('@extschema@.pathman_config_params',
7272
CREATE OR REPLACE FUNCTION @extschema@.invalidate_relcache(relid OID)
7373
RETURNS VOID AS 'pg_pathman' LANGUAGE C STRICT;
7474

75+
CREATE OR REPLACE FUNCTION @extschema@.partitions_count(relation REGCLASS)
76+
RETURNS INT AS
77+
$$
78+
BEGIN
79+
RETURN count(*) FROM pg_inherits WHERE inhparent = relation;
80+
END
81+
$$
82+
LANGUAGE plpgsql;
83+
7584
/* Include parent relation into query plan's for specified relation */
7685
CREATE OR REPLACE FUNCTION @extschema@.enable_parent(relation REGCLASS)
7786
RETURNS VOID AS

range.sql

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ BEGIN
5959
p_attribute := lower(p_attribute);
6060
PERFORM @extschema@.common_relation_checks(parent_relid, p_attribute);
6161

62+
IF p_count < 0 THEN
63+
RAISE EXCEPTION 'Partitions count must not be less than zero';
64+
END IF;
65+
6266
/* Try to determine partitions count if not set */
6367
IF p_count IS NULL THEN
6468
EXECUTE format('SELECT count(*), max(%s) FROM %s', p_attribute, parent_relid)
@@ -76,13 +80,19 @@ BEGIN
7680
END LOOP;
7781
END IF;
7882

79-
/* Check boundaries */
80-
EXECUTE format('SELECT @extschema@.check_boundaries(''%s'', ''%s'', ''%s'', ''%s''::%s)',
81-
parent_relid,
82-
p_attribute,
83-
p_start_value,
84-
p_start_value + p_interval * p_count,
85-
pg_typeof(p_start_value));
83+
/*
84+
* In case when user doesn't want to automatically create partitions
85+
* and specifies partition count as 0 then do not check boundaries
86+
*/
87+
IF p_count != 0 THEN
88+
/* Check boundaries */
89+
EXECUTE format('SELECT @extschema@.check_boundaries(''%s'', ''%s'', ''%s'', ''%s''::%s)',
90+
parent_relid,
91+
p_attribute,
92+
p_start_value,
93+
p_start_value + p_interval * p_count,
94+
pg_typeof(p_start_value));
95+
END IF;
8696

8797
SELECT * INTO v_plain_schema, v_plain_relname
8898
FROM @extschema@.get_plain_schema_and_relname(parent_relid);
@@ -147,8 +157,8 @@ BEGIN
147157
p_attribute := lower(p_attribute);
148158
PERFORM @extschema@.common_relation_checks(parent_relid, p_attribute);
149159

150-
IF p_count <= 0 THEN
151-
RAISE EXCEPTION 'Partitions count must be greater than zero';
160+
IF p_count < 0 THEN
161+
RAISE EXCEPTION 'Partitions count must not be less than zero';
152162
END IF;
153163

154164
/* Try to determine partitions count if not set */
@@ -172,11 +182,17 @@ BEGIN
172182
END LOOP;
173183
END IF;
174184

175-
/* check boundaries */
176-
PERFORM @extschema@.check_boundaries(parent_relid,
177-
p_attribute,
178-
p_start_value,
179-
p_start_value + p_interval * p_count);
185+
/*
186+
* In case when user doesn't want to automatically create partitions
187+
* and specifies partition count as 0 then do not check boundaries
188+
*/
189+
IF p_count != 0 THEN
190+
/* check boundaries */
191+
PERFORM @extschema@.check_boundaries(parent_relid,
192+
p_attribute,
193+
p_start_value,
194+
p_start_value + p_interval * p_count);
195+
END IF;
180196

181197
SELECT * INTO v_plain_schema, v_plain_relname
182198
FROM @extschema@.get_plain_schema_and_relname(parent_relid);
@@ -521,7 +537,8 @@ BEGIN
521537
v_new_partition := @extschema@.create_single_range_partition(
522538
@extschema@.get_schema_qualified_name(v_parent_relid),
523539
p_value,
524-
p_range[2]);
540+
p_range[2],
541+
partition_name);
525542

526543
/* Copy data */
527544
v_cond := @extschema@.build_range_condition(v_attname, p_value, p_range[2]);
@@ -736,6 +753,10 @@ DECLARE
736753
v_part_name TEXT;
737754

738755
BEGIN
756+
IF @extschema@.partitions_count(parent_relid) = 0 THEN
757+
RAISE EXCEPTION 'Cannot append to empty partitions set';
758+
END IF;
759+
739760
p_range := @extschema@.get_range_by_idx(parent_relid, -1, 0);
740761

741762
IF @extschema@.is_date_type(p_atttype::regtype) THEN
@@ -825,6 +846,10 @@ DECLARE
825846
v_part_name TEXT;
826847

827848
BEGIN
849+
IF @extschema@.partitions_count(parent_relid) = 0 THEN
850+
RAISE EXCEPTION 'Cannot prepend to empty partitions set';
851+
END IF;
852+
828853
p_range := @extschema@.get_range_by_idx(parent_relid, 0, 0);
829854

830855
IF @extschema@.is_date_type(p_atttype::regtype) THEN
@@ -865,17 +890,17 @@ RETURNS TEXT AS
865890
$$
866891
DECLARE
867892
v_part_name TEXT;
868-
869893
BEGIN
870-
/* check range overlap */
871-
IF @extschema@.check_overlap(parent_relid, p_start_value, p_end_value) THEN
872-
RAISE EXCEPTION 'Specified range overlaps with existing partitions';
873-
END IF;
874-
875894
IF p_start_value >= p_end_value THEN
876895
RAISE EXCEPTION 'Failed to create partition: p_start_value is greater than p_end_value';
877896
END IF;
878897

898+
/* check range overlap */
899+
IF @extschema@.partitions_count(parent_relid) > 0
900+
AND @extschema@.check_overlap(parent_relid, p_start_value, p_end_value) THEN
901+
RAISE EXCEPTION 'Specified range overlaps with existing partitions';
902+
END IF;
903+
879904
/* Create new partition */
880905
v_part_name :=@extschema@.create_single_range_partition(
881906
parent_relid,

sql/pg_pathman.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,21 @@ CREATE TABLE test.range_rel_test2 (
471471
dt TIMESTAMP);
472472
SELECT pathman.attach_range_partition('test.range_rel', 'test.range_rel_test2', '2013-01-01'::DATE, '2014-01-01'::DATE);
473473

474+
/*
475+
* Zero partitions count and adding partitions with specified name
476+
*/
477+
CREATE TABLE test.zero(
478+
id SERIAL PRIMARY KEY,
479+
value INT NOT NULL);
480+
INSERT INTO test.zero SELECT g, g FROM generate_series(1, 100) as g;
481+
SELECT pathman.create_range_partitions('test.zero', 'value', 50, 10, 0);
482+
SELECT pathman.append_range_partition('test.zero', 'test.zero_0');
483+
SELECT pathman.prepend_range_partition('test.zero', 'test.zero_1');
484+
SELECT pathman.add_range_partition('test.zero', 50, 70, 'test.zero_50');
485+
SELECT pathman.append_range_partition('test.zero', 'test.zero_appended');
486+
SELECT pathman.prepend_range_partition('test.zero', 'test.zero_prepended');
487+
SELECT pathman.split_range_partition('test.zero_50', 60, 'test.zero_60');
488+
474489
/*
475490
* Check that altering table columns doesn't break trigger
476491
*/

src/pl_funcs.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,12 @@ on_partitions_created_internal(Oid partitioned_table, bool add_callbacks)
9696
static void
9797
on_partitions_updated_internal(Oid partitioned_table, bool add_callbacks)
9898
{
99-
/* TODO: shall we emit relcache invalidation event here? */
99+
bool found;
100+
100101
elog(DEBUG2, "on_partitions_updated() [add_callbacks = %s] "
101102
"triggered for relation %u",
102103
(add_callbacks ? "true" : "false"), partitioned_table);
104+
invalidate_pathman_relation_info(partitioned_table, &found);
103105
}
104106

105107
static void

src/worker.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,7 @@ partition_data_bg_worker_main(Datum main_arg)
498498
SPI_connect();
499499
PushActiveSnapshot(GetTransactionSnapshot());
500500

501+
/* Do some preparation within the first iteration */
501502
if (sql == NULL)
502503
{
503504
MemoryContext oldcontext;
@@ -530,10 +531,12 @@ partition_data_bg_worker_main(Datum main_arg)
530531
}
531532
PG_CATCH();
532533
{
534+
ErrorData *error;
533535
EmitErrorReport();
536+
error = CopyErrorData();
537+
elog(LOG, "Worker error: %s", error->message);
534538
FlushErrorState();
535539

536-
elog(WARNING, "Error #%u", failures_count);
537540
/*
538541
* The most common exception we can catch here is a deadlock with
539542
* concurrent user queries. Check that attempts count doesn't exceed
@@ -543,7 +546,9 @@ partition_data_bg_worker_main(Datum main_arg)
543546
{
544547
pfree(sql);
545548
args->status = WS_FREE;
546-
elog(ERROR, "Failures count exceeded 100. Finishing...");
549+
elog(LOG,
550+
"The concurrent partitioning worker exiting because the "
551+
"maximum attempts count exceeded. See the error message below");
547552
exit(1);
548553
}
549554
failed = true;

0 commit comments

Comments
 (0)