Skip to content

Commit 3b6db77

Browse files
committed
improve stability and error handling
1 parent e676060 commit 3b6db77

File tree

11 files changed

+377
-182
lines changed

11 files changed

+377
-182
lines changed

Makefile

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,24 @@ DATA = pg_pathman--1.0--1.1.sql \
2525
PGFILEDESC = "pg_pathman - partitioning tool for PostgreSQL"
2626

2727
REGRESS = pathman_basic \
28-
pathman_only \
29-
pathman_cte \
3028
pathman_bgw \
31-
pathman_inserts \
32-
pathman_updates \
33-
pathman_domains \
34-
pathman_interval \
29+
pathman_calamity \
3530
pathman_callbacks \
31+
pathman_column_type \
32+
pathman_cte \
33+
pathman_domains \
3634
pathman_foreign_keys \
35+
pathman_inserts \
36+
pathman_interval \
37+
pathman_join_clause \
38+
pathman_only \
3739
pathman_permissions \
3840
pathman_rowmarks \
39-
pathman_join_clause \
4041
pathman_runtime_nodes \
41-
pathman_utility_stmt \
42-
pathman_column_type \
4342
pathman_update_trigger \
44-
pathman_calamity
43+
pathman_updates \
44+
pathman_utility_stmt
45+
4546

4647
EXTRA_REGRESS_OPTS=--temp-config=$(top_srcdir)/$(subdir)/conf.add
4748

expected/pathman_calamity.out

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,24 +244,45 @@ SELECT build_hash_condition('text', 'val', 10, NULL) IS NULL;
244244
SELECT build_hash_condition('calamity.part_test', 'val', 10, 1);
245245
ERROR: no hash function for type calamity.part_test
246246
/* check function build_range_condition() */
247-
SELECT build_range_condition('calamity.part_test', 'val', 10, 20);
247+
SELECT build_range_condition(NULL, 'val', 10, 20); /* not ok */
248+
ERROR: 'partition_relid' should not be NULL
249+
SELECT build_range_condition('calamity.part_test', NULL, 10, 20); /* not ok */
250+
ERROR: 'attribute' should not be NULL
251+
SELECT build_range_condition('calamity.part_test', 'val', 10, 20); /* OK */
248252
build_range_condition
249253
------------------------------
250254
((val >= 10) AND (val < 20))
251255
(1 row)
252256

253-
SELECT build_range_condition('calamity.part_test', 'val', 10, NULL);
257+
SELECT build_range_condition('calamity.part_test', 'val', 10, NULL); /* OK */
254258
build_range_condition
255259
-----------------------
256260
((val >= 10))
257261
(1 row)
258262

259-
SELECT build_range_condition('calamity.part_test', 'val', NULL, 10);
263+
SELECT build_range_condition('calamity.part_test', 'val', NULL, 10); /* OK */
260264
build_range_condition
261265
-----------------------
262266
((val < 10))
263267
(1 row)
264268

269+
/* check function validate_interval_value() */
270+
SELECT validate_interval_value(NULL, 'val', 2, '1 mon'); /* not ok */
271+
ERROR: 'partrel' should not be NULL
272+
SELECT validate_interval_value('calamity.part_test', NULL, 2, '1 mon'); /* not ok */
273+
ERROR: 'attname' should not be NULL
274+
SELECT validate_interval_value('calamity.part_test', 'val', NULL, '1 mon'); /* not ok */
275+
ERROR: 'parttype' should not be NULL
276+
SELECT validate_interval_value('calamity.part_test', 'val', 2, '1 mon'); /* not ok */
277+
ERROR: invalid input syntax for integer: "1 mon"
278+
SELECT validate_interval_value('calamity.part_test', 'val', 1, '1 mon'); /* not ok */
279+
ERROR: interval should be NULL for HASH partitioned table
280+
SELECT validate_interval_value('calamity.part_test', 'val', 2, NULL); /* OK */
281+
validate_interval_value
282+
-------------------------
283+
t
284+
(1 row)
285+
265286
/* check function validate_relname() */
266287
SELECT validate_relname('calamity.part_test');
267288
validate_relname
@@ -402,6 +423,21 @@ SELECT build_update_trigger_func_name(NULL) IS NULL;
402423
t
403424
(1 row)
404425

426+
/* check function build_sequence_name() */
427+
SELECT build_sequence_name('calamity.part_test'); /* ok */
428+
build_sequence_name
429+
------------------------
430+
calamity.part_test_seq
431+
(1 row)
432+
433+
SELECT build_sequence_name(1::REGCLASS); /* not ok */
434+
ERROR: relation "1" does not exist
435+
SELECT build_sequence_name(NULL) IS NULL;
436+
?column?
437+
----------
438+
t
439+
(1 row)
440+
405441
/* check function stop_concurrent_part_task() */
406442
SELECT stop_concurrent_part_task(1::regclass);
407443
ERROR: cannot find worker for relation "1"
@@ -453,6 +489,23 @@ SELECT generate_range_bounds('1-jan-2017'::DATE,
453489
{01-01-2017,01-02-2017,01-03-2017,01-04-2017,01-05-2017}
454490
(1 row)
455491

492+
SELECT check_range_available(NULL, NULL::INT4, NULL); /* not ok */
493+
ERROR: 'parent_relid' should not be NULL
494+
SELECT check_range_available('pg_class', 1, 10); /* OK (not partitioned) */
495+
WARNING: relation "pg_class" is not partitioned
496+
check_range_available
497+
-----------------------
498+
499+
(1 row)
500+
501+
SELECT has_update_trigger(NULL);
502+
has_update_trigger
503+
--------------------
504+
505+
(1 row)
506+
507+
SELECT has_update_trigger(0::REGCLASS); /* not ok */
508+
ERROR: relation "0" does not exist
456509
/* check invoke_on_partition_created_callback() */
457510
CREATE FUNCTION calamity.dummy_cb(arg jsonb) RETURNS void AS $$
458511
begin
@@ -463,7 +516,7 @@ $$ LANGUAGE plpgsql;
463516
SELECT invoke_on_partition_created_callback(NULL, 'calamity.part_test', 1);
464517
ERROR: 'parent_relid' should not be NULL
465518
SELECT invoke_on_partition_created_callback('calamity.part_test', NULL, 1);
466-
ERROR: 'partition' should not be NULL
519+
ERROR: 'partition_relid' should not be NULL
467520
SELECT invoke_on_partition_created_callback('calamity.part_test', 'calamity.part_test', 0);
468521
invoke_on_partition_created_callback
469522
--------------------------------------

expected/pathman_interval.out

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ INSERT INTO test_interval.abc VALUES (250);
2121
ERROR: cannot find appropriate partition for key '250'
2222
/* Set a trivial interval */
2323
SELECT set_interval('test_interval.abc', 0);
24-
ERROR: interval must not be trivial
24+
ERROR: interval should not be trivial
2525
/* Set a negative interval */
2626
SELECT set_interval('test_interval.abc', -100);
27-
ERROR: interval must not be negative
27+
ERROR: interval should not be negative
2828
/* We also shouldn't be able to set a trivial interval directly */
2929
UPDATE pathman_config SET range_interval = '0'
3030
WHERE partrel = 'test_interval.abc'::REGCLASS;
31-
ERROR: interval must not be trivial
31+
ERROR: interval should not be trivial
3232
/* Set a normal interval */
3333
SELECT set_interval('test_interval.abc', 1000);
3434
set_interval
@@ -64,14 +64,14 @@ INSERT INTO test_interval.abc VALUES (250);
6464
ERROR: cannot find appropriate partition for key '250'
6565
/* Set a trivial interval */
6666
SELECT set_interval('test_interval.abc', 0);
67-
ERROR: interval must not be trivial
67+
ERROR: interval should not be trivial
6868
/* Set a negative interval */
6969
SELECT set_interval('test_interval.abc', -100);
70-
ERROR: interval must not be negative
70+
ERROR: interval should not be negative
7171
/* We also shouldn't be able to set a trivial interval directly */
7272
UPDATE pathman_config SET range_interval = '0'
7373
WHERE partrel = 'test_interval.abc'::REGCLASS;
74-
ERROR: interval must not be trivial
74+
ERROR: interval should not be trivial
7575
/* Set a normal interval */
7676
SELECT set_interval('test_interval.abc', 1000);
7777
set_interval
@@ -107,14 +107,14 @@ INSERT INTO test_interval.abc VALUES (250);
107107
ERROR: cannot find appropriate partition for key '250'
108108
/* Set a trivial interval */
109109
SELECT set_interval('test_interval.abc', 0);
110-
ERROR: interval must not be trivial
110+
ERROR: interval should not be trivial
111111
/* Set a negative interval */
112112
SELECT set_interval('test_interval.abc', -100);
113-
ERROR: interval must not be negative
113+
ERROR: interval should not be negative
114114
/* We also shouldn't be able to set a trivial interval directly */
115115
UPDATE pathman_config SET range_interval = '0'
116116
WHERE partrel = 'test_interval.abc'::REGCLASS;
117-
ERROR: interval must not be trivial
117+
ERROR: interval should not be trivial
118118
/* Set a normal interval */
119119
SELECT set_interval('test_interval.abc', 1000);
120120
set_interval
@@ -148,7 +148,7 @@ SELECT set_interval('test_interval.abc', NULL::INTERVAL);
148148

149149
/* Set a trivial interval */
150150
SELECT set_interval('test_interval.abc', '1 second'::INTERVAL);
151-
ERROR: interval must not be trivial
151+
ERROR: interval should not be trivial
152152
/* Set a normal interval */
153153
SELECT set_interval('test_interval.abc', '1 month'::INTERVAL);
154154
set_interval
@@ -180,7 +180,7 @@ SELECT set_interval('test_interval.abc', NULL::FLOAT4);
180180

181181
/* Set a trivial interval */
182182
SELECT set_interval('test_interval.abc', 0);
183-
ERROR: interval must not be trivial
183+
ERROR: interval should not be trivial
184184
/* Set NaN float as interval */
185185
SELECT set_interval('test_interval.abc', 'NaN'::FLOAT4);
186186
ERROR: invalid floating point interval
@@ -212,7 +212,7 @@ SELECT set_interval('test_interval.abc', NULL::FLOAT8);
212212

213213
/* Set a trivial interval */
214214
SELECT set_interval('test_interval.abc', 0);
215-
ERROR: interval must not be trivial
215+
ERROR: interval should not be trivial
216216
/* Set NaN float as interval */
217217
SELECT set_interval('test_interval.abc', 'NaN'::FLOAT8);
218218
ERROR: invalid floating point interval
@@ -244,7 +244,7 @@ SELECT set_interval('test_interval.abc', NULL::NUMERIC);
244244

245245
/* Set a trivial interval */
246246
SELECT set_interval('test_interval.abc', 0);
247-
ERROR: interval must not be trivial
247+
ERROR: interval should not be trivial
248248
/* Set NaN numeric as interval */
249249
SELECT set_interval('test_interval.abc', 'NaN'::NUMERIC);
250250
ERROR: invalid numeric interval

init.sql

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -709,16 +709,6 @@ END
709709
$$ LANGUAGE plpgsql;
710710

711711

712-
/*
713-
* Check if tuple from first relation can be converted to fit the second one.
714-
*/
715-
CREATE OR REPLACE FUNCTION @extschema@.is_tuple_convertible(
716-
relation1 REGCLASS,
717-
relation2 REGCLASS)
718-
RETURNS BOOL AS 'pg_pathman', 'is_tuple_convertible'
719-
LANGUAGE C STRICT;
720-
721-
722712
/*
723713
* Function for UPDATE triggers.
724714
*/
@@ -859,11 +849,20 @@ LANGUAGE C STRICT;
859849
* Check if TYPE supports the specified operator.
860850
*/
861851
CREATE OR REPLACE FUNCTION @extschema@.is_operator_supported(
862-
type_oid OID,
852+
type_oid REGTYPE,
863853
opname TEXT)
864854
RETURNS BOOLEAN AS 'pg_pathman', 'is_operator_supported'
865855
LANGUAGE C STRICT;
866856

857+
/*
858+
* Check if tuple from first relation can be converted to fit the second one.
859+
*/
860+
CREATE OR REPLACE FUNCTION @extschema@.is_tuple_convertible(
861+
relation1 REGCLASS,
862+
relation2 REGCLASS)
863+
RETURNS BOOL AS 'pg_pathman', 'is_tuple_convertible'
864+
LANGUAGE C STRICT;
865+
867866

868867
/*
869868
* Build check constraint name for a specified relation's column.

range.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,7 +1088,7 @@ SET client_min_messages = WARNING;
10881088
* Construct CHECK constraint condition for a range partition.
10891089
*/
10901090
CREATE OR REPLACE FUNCTION @extschema@.build_range_condition(
1091-
p_relid REGCLASS,
1091+
partition_relid REGCLASS,
10921092
attribute TEXT,
10931093
start_value ANYELEMENT,
10941094
end_value ANYELEMENT)
@@ -1098,7 +1098,7 @@ LANGUAGE C;
10981098
CREATE OR REPLACE FUNCTION @extschema@.build_sequence_name(
10991099
parent_relid REGCLASS)
11001100
RETURNS TEXT AS 'pg_pathman', 'build_sequence_name'
1101-
LANGUAGE C;
1101+
LANGUAGE C STRICT;
11021102

11031103

11041104
/*

sql/pathman_calamity.sql

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ SELECT count(*) FROM calamity.part_test;
3636
DELETE FROM calamity.part_test;
3737

3838

39+
40+
41+
3942
/* test function create_range_partitions_internal() */
4043
SELECT create_range_partitions_internal(NULL, '{}'::INT[], NULL, NULL); /* not ok */
4144

@@ -116,9 +119,19 @@ SELECT build_hash_condition('text', 'val', 10, NULL) IS NULL;
116119
SELECT build_hash_condition('calamity.part_test', 'val', 10, 1);
117120

118121
/* check function build_range_condition() */
119-
SELECT build_range_condition('calamity.part_test', 'val', 10, 20);
120-
SELECT build_range_condition('calamity.part_test', 'val', 10, NULL);
121-
SELECT build_range_condition('calamity.part_test', 'val', NULL, 10);
122+
SELECT build_range_condition(NULL, 'val', 10, 20); /* not ok */
123+
SELECT build_range_condition('calamity.part_test', NULL, 10, 20); /* not ok */
124+
SELECT build_range_condition('calamity.part_test', 'val', 10, 20); /* OK */
125+
SELECT build_range_condition('calamity.part_test', 'val', 10, NULL); /* OK */
126+
SELECT build_range_condition('calamity.part_test', 'val', NULL, 10); /* OK */
127+
128+
/* check function validate_interval_value() */
129+
SELECT validate_interval_value(NULL, 'val', 2, '1 mon'); /* not ok */
130+
SELECT validate_interval_value('calamity.part_test', NULL, 2, '1 mon'); /* not ok */
131+
SELECT validate_interval_value('calamity.part_test', 'val', NULL, '1 mon'); /* not ok */
132+
SELECT validate_interval_value('calamity.part_test', 'val', 2, '1 mon'); /* not ok */
133+
SELECT validate_interval_value('calamity.part_test', 'val', 1, '1 mon'); /* not ok */
134+
SELECT validate_interval_value('calamity.part_test', 'val', 2, NULL); /* OK */
122135

123136
/* check function validate_relname() */
124137
SELECT validate_relname('calamity.part_test');
@@ -164,6 +177,11 @@ SELECT build_update_trigger_name(NULL) IS NULL;
164177
SELECT build_update_trigger_func_name('calamity.part_test');
165178
SELECT build_update_trigger_func_name(NULL) IS NULL;
166179

180+
/* check function build_sequence_name() */
181+
SELECT build_sequence_name('calamity.part_test'); /* ok */
182+
SELECT build_sequence_name(1::REGCLASS); /* not ok */
183+
SELECT build_sequence_name(NULL) IS NULL;
184+
167185
/* check function stop_concurrent_part_task() */
168186
SELECT stop_concurrent_part_task(1::regclass);
169187

@@ -183,6 +201,11 @@ SELECT generate_range_bounds('1-jan-2017'::DATE,
183201
'1 day'::INTERVAL,
184202
4); /* OK */
185203

204+
SELECT check_range_available(NULL, NULL::INT4, NULL); /* not ok */
205+
SELECT check_range_available('pg_class', 1, 10); /* OK (not partitioned) */
206+
207+
SELECT has_update_trigger(NULL);
208+
SELECT has_update_trigger(0::REGCLASS); /* not ok */
186209

187210
/* check invoke_on_partition_created_callback() */
188211
CREATE FUNCTION calamity.dummy_cb(arg jsonb) RETURNS void AS $$

src/init.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ char *
552552
build_check_constraint_name_relid_internal(Oid relid,
553553
AttrNumber attno)
554554
{
555+
AssertArg(OidIsValid(relid));
555556
return build_check_constraint_name_relname_internal(get_rel_name(relid), attno);
556557
}
557558

@@ -573,6 +574,7 @@ build_check_constraint_name_relname_internal(const char *relname,
573574
char *
574575
build_sequence_name_internal(Oid relid)
575576
{
577+
AssertArg(OidIsValid(relid));
576578
return psprintf("%s_seq", get_rel_name(relid));
577579
}
578580

@@ -583,6 +585,7 @@ build_sequence_name_internal(Oid relid)
583585
char *
584586
build_update_trigger_name_internal(Oid relid)
585587
{
588+
AssertArg(OidIsValid(relid));
586589
return psprintf("%s_upd_trig", get_rel_name(relid));
587590
}
588591

@@ -593,12 +596,8 @@ build_update_trigger_name_internal(Oid relid)
593596
char *
594597
build_update_trigger_func_name_internal(Oid relid)
595598
{
596-
Oid nspid = get_rel_namespace(relid);
597-
598-
return psprintf("%s.%s",
599-
quote_identifier(get_namespace_name(nspid)),
600-
quote_identifier(psprintf("%s_upd_trig_func",
601-
get_rel_name(relid))));
599+
AssertArg(OidIsValid(relid));
600+
return psprintf("%s_upd_trig_func", get_rel_name(relid));
602601
}
603602

604603

@@ -682,7 +681,7 @@ pathman_config_contains_relation(Oid relid, Datum *values, bool *isnull,
682681

683682
/*
684683
* Loads additional pathman parameters like 'enable_parent' or 'auto'
685-
* from PATHMAN_CONFIG_PARAMS
684+
* from PATHMAN_CONFIG_PARAMS.
686685
*/
687686
bool
688687
read_pathman_params(Oid relid, Datum *values, bool *isnull)
@@ -1128,6 +1127,7 @@ validate_hash_constraint(const Expr *expr,
11281127

11291128
return false;
11301129
}
1130+
11311131
/* needed for find_inheritance_children_array() function */
11321132
static int
11331133
oid_cmp(const void *p1, const void *p2)

0 commit comments

Comments
 (0)