Skip to content

Commit 79f3987

Browse files
committed
revised transaction support for partition management functions, clean & remove obsolete code
1 parent dc49c1d commit 79f3987

File tree

9 files changed

+355
-170
lines changed

9 files changed

+355
-170
lines changed

Diff for: expected/pg_pathman.out

+7-7
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ CREATE INDEX ON test.range_rel (dt);
5555
INSERT INTO test.range_rel (dt, txt)
5656
SELECT g, md5(g::TEXT) FROM generate_series('2015-01-01', '2015-04-30', '1 day'::interval) as g;
5757
SELECT pathman.create_range_partitions('test.range_rel', 'dt', '2015-01-01'::DATE, '1 month'::INTERVAL, 2);
58-
ERROR: Partitioning key 'dt' must be NOT NULL P0001
58+
ERROR: Partitioning key 'dt' must be NOT NULL
5959
ALTER TABLE test.range_rel ALTER COLUMN dt SET NOT NULL;
6060
SELECT pathman.create_range_partitions('test.range_rel', 'dt', '2015-01-01'::DATE, '1 month'::INTERVAL, 2);
61-
ERROR: Not enough partitions to fit all the values of 'dt' P0001
61+
ERROR: Not enough partitions to fit all the values of 'dt'
6262
SELECT pathman.create_range_partitions('test.range_rel', 'DT', '2015-01-01'::DATE, '1 month'::INTERVAL);
6363
NOTICE: sequence "range_rel_seq" does not exist, skipping
6464
NOTICE: Copying data to partitions...
@@ -932,7 +932,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE dt BETWEEN '2014-12-15' A
932932
(3 rows)
933933

934934
SELECT pathman.add_range_partition('test.range_rel', '2014-12-01'::DATE, '2015-01-02'::DATE);
935-
ERROR: Specified range overlaps with existing partitions P0001
935+
ERROR: Specified range overlaps with existing partitions
936936
SELECT pathman.add_range_partition('test.range_rel', '2014-12-01'::DATE, '2015-01-01'::DATE);
937937
NOTICE: Done!
938938
add_range_partition
@@ -952,7 +952,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE dt BETWEEN '2014-12-15' A
952952

953953
CREATE TABLE test.range_rel_archive (LIKE test.range_rel INCLUDING ALL);
954954
SELECT pathman.attach_range_partition('test.range_rel', 'test.range_rel_archive', '2014-01-01'::DATE, '2015-01-01'::DATE);
955-
ERROR: Specified range overlaps with existing partitions P0001
955+
ERROR: Specified range overlaps with existing partitions
956956
SELECT pathman.attach_range_partition('test.range_rel', 'test.range_rel_archive', '2014-01-01'::DATE, '2014-12-01'::DATE);
957957
attach_range_partition
958958
------------------------
@@ -991,12 +991,12 @@ CREATE TABLE test.range_rel_test1 (
991991
txt TEXT,
992992
abc INTEGER);
993993
SELECT pathman.attach_range_partition('test.range_rel', 'test.range_rel_test1', '2013-01-01'::DATE, '2014-01-01'::DATE);
994-
ERROR: Partition must have the exact same structure as parent P0001
994+
ERROR: Partition must have the exact same structure as parent
995995
CREATE TABLE test.range_rel_test2 (
996996
id SERIAL PRIMARY KEY,
997997
dt TIMESTAMP);
998998
SELECT pathman.attach_range_partition('test.range_rel', 'test.range_rel_test2', '2013-01-01'::DATE, '2014-01-01'::DATE);
999-
ERROR: Partition must have the exact same structure as parent P0001
999+
ERROR: Partition must have the exact same structure as parent
10001000
/*
10011001
* Check that altering table columns doesn't break trigger
10021002
*/
@@ -1559,7 +1559,7 @@ INSERT INTO messages SELECT g, md5(g::text) FROM generate_series(1, 10) as g;
15591559
INSERT INTO replies SELECT g, g, md5(g::text) FROM generate_series(1, 10) as g;
15601560
SELECT create_range_partitions('messages', 'id', 1, 100, 2);
15611561
WARNING: Foreign key 'replies_message_id_fkey' references to the relation 'messages'
1562-
ERROR: Relation 'messages' is referenced from other relations P0001
1562+
ERROR: Relation 'messages' is referenced from other relations
15631563
ALTER TABLE replies DROP CONSTRAINT replies_message_id_fkey;
15641564
SELECT create_range_partitions('messages', 'id', 1, 100, 2);
15651565
NOTICE: sequence "messages_seq" does not exist, skipping

Diff for: hash.sql

+2-6
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@ BEGIN
3030
PERFORM @[email protected]_relation_checks(relation, attribute);
3131

3232
v_type := @[email protected]_attribute_type_name(v_relname, attribute);
33-
-- IF v_type::regtype != 'integer'::regtype THEN
34-
-- RAISE EXCEPTION 'Attribute type must be INTEGER';
35-
-- END IF;
3633

3734
SELECT * INTO v_plain_schema, v_plain_relname
3835
FROM @[email protected]_plain_schema_and_relname(relation);
@@ -42,10 +39,9 @@ BEGIN
4239
/* Create partitions and update pg_pathman configuration */
4340
FOR partnum IN 0..partitions_count-1
4441
LOOP
45-
-- v_child_relname := @[email protected]_schema_qualified_name(relation, '.', suffix := '_' || partnum);
4642
v_child_relname := format('%s.%s',
47-
v_plain_schema,
48-
quote_ident(v_plain_relname || '_' || partnum));
43+
v_plain_schema,
44+
quote_ident(v_plain_relname || '_' || partnum));
4945

5046
EXECUTE format('CREATE TABLE %s (LIKE %s INCLUDING ALL)'
5147
, v_child_relname

Diff for: init.sql

-4
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,6 @@ BEGIN
104104
, relname);
105105
GET DIAGNOSTICS p_total = ROW_COUNT;
106106
RETURN;
107-
108-
-- EXCEPTION WHEN others THEN
109-
-- PERFORM on_remove_partitions(p_parent::regclass::integer);
110-
-- RAISE EXCEPTION '% %', SQLERRM, SQLSTATE;
111107
END
112108
$$
113109
LANGUAGE plpgsql;

Diff for: range.sql

+54-59
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,7 @@ BEGIN
107107
RETURN p_count;
108108

109109
EXCEPTION WHEN others THEN
110-
PERFORM @[email protected]_remove_partitions(p_relation::integer);
111-
RAISE EXCEPTION '% %', SQLERRM, SQLSTATE;
110+
RAISE EXCEPTION '%', SQLERRM;
112111
END
113112
$$ LANGUAGE plpgsql;
114113

@@ -188,6 +187,7 @@ BEGIN
188187
/* Create triggers */
189188
PERFORM @[email protected]_range_insert_trigger(p_relation, p_attribute);
190189
-- PERFORM create_hash_update_trigger(relation, attribute, partitions_count);
190+
191191
/* Notify backend about changes */
192192
PERFORM @[email protected]_create_partitions(p_relation::regclass::oid);
193193

@@ -197,8 +197,7 @@ BEGIN
197197
RETURN p_count;
198198

199199
EXCEPTION WHEN others THEN
200-
PERFORM @[email protected]_remove_partitions(p_relation::regclass::integer);
201-
RAISE EXCEPTION '% %', SQLERRM, SQLSTATE;
200+
RAISE EXCEPTION '%', SQLERRM;
202201
END
203202
$$ LANGUAGE plpgsql;
204203

@@ -262,8 +261,7 @@ BEGIN
262261
RETURN i;
263262

264263
EXCEPTION WHEN others THEN
265-
PERFORM @[email protected]_remove_partitions(p_relation::regclass::integer);
266-
RAISE EXCEPTION '% %', SQLERRM, SQLSTATE;
264+
RAISE EXCEPTION '%', SQLERRM;
267265
END
268266
$$ LANGUAGE plpgsql;
269267

@@ -322,8 +320,7 @@ BEGIN
322320
RETURN i;
323321

324322
EXCEPTION WHEN others THEN
325-
PERFORM @[email protected]_remove_partitions(p_relation::regclass::integer);
326-
RAISE EXCEPTION '% %', SQLERRM, SQLSTATE;
323+
RAISE EXCEPTION '%', SQLERRM;
327324
END
328325
$$ LANGUAGE plpgsql;
329326

@@ -409,19 +406,19 @@ CREATE OR REPLACE FUNCTION @[email protected]_single_range_partition(
409406
RETURNS TEXT AS
410407
$$
411408
DECLARE
412-
v_part_num INT;
409+
v_part_num INT;
413410
v_child_relname TEXT;
414-
v_plain_child_relname TEXT;
411+
v_plain_child_relname TEXT;
415412
v_attname TEXT;
416-
v_sql TEXT;
417-
v_cond TEXT;
418-
v_plain_schema TEXT;
419-
v_plain_relname TEXT;
420-
v_child_relname_exists INTEGER := 1;
421-
v_seq_name TEXT;
413+
v_sql TEXT;
414+
v_cond TEXT;
415+
v_plain_schema TEXT;
416+
v_plain_relname TEXT;
417+
v_child_relname_exists INTEGER := 1;
418+
v_seq_name TEXT;
422419
BEGIN
423-
v_attname := attname FROM @[email protected]_config
424-
WHERE relname::regclass = p_parent;
420+
v_attname := attname FROM @[email protected]_config
421+
WHERE relname::regclass = p_parent;
425422

426423
IF v_attname IS NULL THEN
427424
RAISE EXCEPTION 'Table % is not partitioned', quote_ident(p_parent::TEXT);
@@ -432,36 +429,36 @@ BEGIN
432429

433430
v_seq_name := @[email protected]_sequence_name(v_plain_schema, v_plain_relname);
434431

435-
/* get next value from sequence */
436-
LOOP
437-
v_part_num := nextval(v_seq_name);
438-
v_plain_child_relname := format('%s_%s', v_plain_relname, v_part_num);
439-
v_child_relname := format('%s.%s',
440-
v_plain_schema,
441-
quote_ident(v_plain_child_relname));
442-
v_child_relname_exists := count(*)
443-
FROM pg_class
444-
WHERE relnamespace::regnamespace || '.' || relname = v_child_relname
445-
LIMIT 1;
446-
EXIT WHEN v_child_relname_exists = 0;
447-
END LOOP;
448-
449-
EXECUTE format('CREATE TABLE %s (LIKE %s INCLUDING ALL)'
450-
, v_child_relname
451-
, p_parent);
452-
453-
EXECUTE format('ALTER TABLE %s INHERIT %s'
454-
, v_child_relname
455-
, p_parent);
456-
457-
v_cond := @[email protected]_range_condition(v_attname, p_start_value, p_end_value);
458-
v_sql := format('ALTER TABLE %s ADD CONSTRAINT %s CHECK (%s)'
459-
, v_child_relname
460-
, quote_ident(format('%s_%s_check', v_plain_schema, v_plain_child_relname))
461-
, v_cond);
462-
463-
EXECUTE v_sql;
464-
RETURN v_child_relname;
432+
/* get next value from sequence */
433+
LOOP
434+
v_part_num := nextval(v_seq_name);
435+
v_plain_child_relname := format('%s_%s', v_plain_relname, v_part_num);
436+
v_child_relname := format('%s.%s',
437+
v_plain_schema,
438+
quote_ident(v_plain_child_relname));
439+
v_child_relname_exists := count(*)
440+
FROM pg_class
441+
WHERE relnamespace::regnamespace || '.' || relname = v_child_relname
442+
LIMIT 1;
443+
EXIT WHEN v_child_relname_exists = 0;
444+
END LOOP;
445+
446+
EXECUTE format('CREATE TABLE %s (LIKE %s INCLUDING ALL)'
447+
, v_child_relname
448+
, p_parent);
449+
450+
EXECUTE format('ALTER TABLE %s INHERIT %s'
451+
, v_child_relname
452+
, p_parent);
453+
454+
v_cond := @[email protected]_range_condition(v_attname, p_start_value, p_end_value);
455+
v_sql := format('ALTER TABLE %s ADD CONSTRAINT %s CHECK (%s)'
456+
, v_child_relname
457+
, quote_ident(format('%s_%s_check', v_plain_schema, v_plain_child_relname))
458+
, v_cond);
459+
460+
EXECUTE v_sql;
461+
RETURN v_child_relname;
465462
END
466463
$$ LANGUAGE plpgsql;
467464

@@ -743,7 +740,7 @@ BEGIN
743740
RETURN v_part_name;
744741

745742
EXCEPTION WHEN others THEN
746-
RAISE EXCEPTION '% %', SQLERRM, SQLSTATE;
743+
RAISE EXCEPTION '%', SQLERRM;
747744
END
748745
$$
749746
LANGUAGE plpgsql;
@@ -817,7 +814,7 @@ BEGIN
817814
RETURN v_part_name;
818815

819816
EXCEPTION WHEN others THEN
820-
RAISE EXCEPTION '% %', SQLERRM, SQLSTATE;
817+
RAISE EXCEPTION '%', SQLERRM;
821818
END
822819
$$
823820
LANGUAGE plpgsql;
@@ -887,7 +884,7 @@ BEGIN
887884
RETURN v_part_name;
888885

889886
EXCEPTION WHEN others THEN
890-
RAISE EXCEPTION '% %', SQLERRM, SQLSTATE;
887+
RAISE EXCEPTION '%', SQLERRM;
891888
END
892889
$$
893890
LANGUAGE plpgsql;
@@ -926,7 +923,7 @@ BEGIN
926923
RETURN v_part_name;
927924

928925
EXCEPTION WHEN others THEN
929-
RAISE EXCEPTION '% %', SQLERRM, SQLSTATE;
926+
RAISE EXCEPTION '%', SQLERRM;
930927
END
931928
$$
932929
LANGUAGE plpgsql;
@@ -959,15 +956,13 @@ BEGIN
959956
/* Prevent concurrent partition management */
960957
PERFORM @[email protected]_partitions_lock();
961958

962-
-- p_relation := @[email protected]_relname(p_relation);
963-
964959
IF @[email protected]_overlap(p_relation::oid, p_start_value, p_end_value) != FALSE THEN
965960
RAISE EXCEPTION 'Specified range overlaps with existing partitions';
966961
END IF;
967962

968-
IF NOT @[email protected]_relations_equality(p_relation, p_partition) THEN
969-
RAISE EXCEPTION 'Partition must have the exact same structure as parent';
970-
END IF;
963+
IF NOT @[email protected]_relations_equality(p_relation, p_partition) THEN
964+
RAISE EXCEPTION 'Partition must have the exact same structure as parent';
965+
END IF;
971966

972967
/* Set inheritance */
973968
EXECUTE format('ALTER TABLE %s INHERIT %s'
@@ -1001,7 +996,7 @@ BEGIN
1001996
RETURN p_partition;
1002997

1003998
EXCEPTION WHEN others THEN
1004-
RAISE EXCEPTION '% %', SQLERRM, SQLSTATE;
999+
RAISE EXCEPTION '%', SQLERRM;
10051000
END
10061001
$$
10071002
LANGUAGE plpgsql;
@@ -1042,7 +1037,7 @@ BEGIN
10421037
RETURN p_partition;
10431038

10441039
EXCEPTION WHEN others THEN
1045-
RAISE EXCEPTION '% %', SQLERRM, SQLSTATE;
1040+
RAISE EXCEPTION '%', SQLERRM;
10461041
END
10471042
$$
10481043
LANGUAGE plpgsql;

Diff for: src/hooks.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,8 @@ pathman_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTb
342342
}
343343
}
344344

345-
void pg_pathman_enable_assign_hook(bool newval, void *extra)
345+
void
346+
pg_pathman_enable_assign_hook(bool newval, void *extra)
346347
{
347348
/* Return quickly if nothing has changed */
348349
if (newval == (pg_pathman_enable &&

Diff for: src/init.c

+12-4
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,9 @@ get_extension_schema()
168168
}
169169

170170
/*
171-
* Loads partitioned tables structure to hashtable
171+
* Loads partitioned tables structure to hashtable.
172+
*
173+
* TODO: reload just the specified relation
172174
*/
173175
void
174176
load_relations(bool reinitialize)
@@ -681,7 +683,8 @@ validate_hash_constraint(Expr *expr, PartRelationInfo *prel, int *hash)
681683
/* Check that function is the base hash function for the type */
682684
funcexpr = (FuncExpr *) first;
683685
if (funcexpr->funcid != prel->hash_proc ||
684-
(!IsA(linitial(funcexpr->args), Var) && !IsA(linitial(funcexpr->args), RelabelType)))
686+
(!IsA(linitial(funcexpr->args), Var) && !IsA(linitial(funcexpr->args),
687+
RelabelType)))
685688
return false;
686689

687690
/* Check that argument is partitioning key attribute */
@@ -723,14 +726,14 @@ create_range_restrictions_hashtable()
723726
}
724727

725728
/*
726-
* Remove partitions
729+
* Remove partitions from pathman's cache
727730
*/
728731
void
729732
remove_relation_info(Oid relid)
730733
{
731734
PartRelationInfo *prel;
732735
RangeRelation *rangerel;
733-
RelationKey key;
736+
RelationKey key;
734737

735738
key.dbid = MyDatabaseId;
736739
key.relid = relid;
@@ -739,21 +742,26 @@ remove_relation_info(Oid relid)
739742

740743
/* If there is nothing to remove then just return */
741744
if (!prel)
745+
{
746+
elog(DEBUG2, "pg_pathman's cache does not contain relation %u", relid);
742747
return;
748+
}
743749

744750
/* Remove children relations */
745751
switch (prel->parttype)
746752
{
747753
case PT_HASH:
748754
free_dsm_array(&prel->children);
749755
break;
756+
750757
case PT_RANGE:
751758
rangerel = get_pathman_range_relation(relid, NULL);
752759
free_dsm_array(&rangerel->ranges);
753760
free_dsm_array(&prel->children);
754761
hash_search(range_restrictions, (const void *) &key, HASH_REMOVE, NULL);
755762
break;
756763
}
764+
757765
prel->children_count = 0;
758766
hash_search(relations, (const void *) &key, HASH_REMOVE, 0);
759767
}

0 commit comments

Comments
 (0)