Skip to content

Commit b1c67ae

Browse files
committed
add drop_range_partition_expand_next() function
1 parent cea6ea5 commit b1c67ae

File tree

4 files changed

+109
-67
lines changed

4 files changed

+109
-67
lines changed

expected/pathman_basic.out

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,6 +1409,35 @@ SELECT pathman.drop_range_partition('test.num_range_rel_7');
14091409
test.num_range_rel_7
14101410
(1 row)
14111411

1412+
SELECT pathman.drop_range_partition_expand_next('test.num_range_rel_4');
1413+
drop_range_partition_expand_next
1414+
----------------------------------
1415+
1416+
(1 row)
1417+
1418+
SELECT * FROM pathman.pathman_partition_list WHERE parent = 'test.num_range_rel'::regclass;
1419+
parent | partition | parttype | partattr | range_min | range_max
1420+
--------------------+----------------------+----------+----------+-----------+-----------
1421+
test.num_range_rel | test.num_range_rel_1 | 2 | id | 0 | 1000
1422+
test.num_range_rel | test.num_range_rel_2 | 2 | id | 1000 | 2000
1423+
test.num_range_rel | test.num_range_rel_3 | 2 | id | 2000 | 3000
1424+
test.num_range_rel | test.num_range_rel_6 | 2 | id | 3000 | 5000
1425+
(4 rows)
1426+
1427+
SELECT pathman.drop_range_partition_expand_next('test.num_range_rel_6');
1428+
drop_range_partition_expand_next
1429+
----------------------------------
1430+
1431+
(1 row)
1432+
1433+
SELECT * FROM pathman.pathman_partition_list WHERE parent = 'test.num_range_rel'::regclass;
1434+
parent | partition | parttype | partattr | range_min | range_max
1435+
--------------------+----------------------+----------+----------+-----------+-----------
1436+
test.num_range_rel | test.num_range_rel_1 | 2 | id | 0 | 1000
1437+
test.num_range_rel | test.num_range_rel_2 | 2 | id | 1000 | 2000
1438+
test.num_range_rel | test.num_range_rel_3 | 2 | id | 2000 | 3000
1439+
(3 rows)
1440+
14121441
SELECT pathman.append_range_partition('test.range_rel');
14131442
append_range_partition
14141443
------------------------
@@ -1711,15 +1740,13 @@ SELECT COUNT(*) FROM ONLY test.hash_rel;
17111740

17121741
DROP TABLE test.hash_rel CASCADE;
17131742
SELECT pathman.drop_partitions('test.num_range_rel');
1714-
NOTICE: drop cascades to 4 other objects
1743+
NOTICE: drop cascades to 3 other objects
17151744
NOTICE: 998 rows copied from test.num_range_rel_1
17161745
NOTICE: 1000 rows copied from test.num_range_rel_2
17171746
NOTICE: 1000 rows copied from test.num_range_rel_3
1718-
NOTICE: 2 rows copied from test.num_range_rel_4
1719-
NOTICE: 0 rows copied from test.num_range_rel_6
17201747
drop_partitions
17211748
-----------------
1722-
5
1749+
3
17231750
(1 row)
17241751

17251752
DROP TABLE test.num_range_rel CASCADE;

range.sql

Lines changed: 13 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -533,68 +533,6 @@ END
533533
$$
534534
LANGUAGE plpgsql;
535535

536-
537-
/*
538-
* Merge RANGE partitions
539-
*/
540-
CREATE OR REPLACE FUNCTION @extschema@.merge_range_partitions(
541-
partition1 REGCLASS,
542-
partition2 REGCLASS)
543-
RETURNS VOID AS
544-
$$
545-
DECLARE
546-
v_parent1 REGCLASS;
547-
v_parent2 REGCLASS;
548-
v_attname TEXT;
549-
v_part_type INTEGER;
550-
v_atttype REGTYPE;
551-
552-
BEGIN
553-
IF partition1 = partition2 THEN
554-
RAISE EXCEPTION 'cannot merge partition with itself';
555-
END IF;
556-
557-
v_parent1 := @extschema@.get_parent_of_partition(partition1);
558-
v_parent2 := @extschema@.get_parent_of_partition(partition2);
559-
560-
/* Acquire data modification locks (prevent further modifications) */
561-
PERFORM @extschema@.prevent_relation_modification(partition1);
562-
PERFORM @extschema@.prevent_relation_modification(partition2);
563-
564-
IF v_parent1 != v_parent2 THEN
565-
RAISE EXCEPTION 'cannot merge partitions with different parents';
566-
END IF;
567-
568-
/* Acquire lock on parent */
569-
PERFORM @extschema@.lock_partitioned_relation(v_parent1);
570-
571-
SELECT attname, parttype
572-
FROM @extschema@.pathman_config
573-
WHERE partrel = v_parent1
574-
INTO v_attname, v_part_type;
575-
576-
IF v_attname IS NULL THEN
577-
RAISE EXCEPTION 'table "%" is not partitioned', v_parent1::TEXT;
578-
END IF;
579-
580-
/* Check if this is a RANGE partition */
581-
IF v_part_type != 2 THEN
582-
RAISE EXCEPTION 'specified partitions are not RANGE partitions';
583-
END IF;
584-
585-
v_atttype := @extschema@.get_attribute_type(partition1, v_attname);
586-
587-
EXECUTE format('SELECT @extschema@.merge_range_partitions_internal($1, $2, $3, NULL::%s)',
588-
@extschema@.get_base_type(v_atttype)::TEXT)
589-
USING v_parent1, partition1, partition2;
590-
591-
/* Tell backend to reload configuration */
592-
PERFORM @extschema@.on_update_partitions(v_parent1);
593-
END
594-
$$
595-
LANGUAGE plpgsql;
596-
597-
598536
/*
599537
* Merge multiple partitions. All data will be copied to the first one. The rest
600538
* of partitions will be dropped
@@ -617,7 +555,6 @@ BEGIN
617555
END
618556
$$ LANGUAGE plpgsql;
619557

620-
621558
/*
622559
* Append new partition.
623560
*/
@@ -952,6 +889,19 @@ LANGUAGE plpgsql
952889
SET pg_pathman.enable_partitionfilter = off; /* ensures that PartitionFilter is OFF */
953890

954891

892+
/*
893+
* Drops partition and expands the next partition so that it cover dropped
894+
* one
895+
*
896+
* This function was written in order to support Oracle-like ALTER TABLE ...
897+
* DROP PARTITION. In Oracle partitions only have upper bound and when
898+
* partition is dropped the next one automatically covers freed range
899+
*/
900+
CREATE OR REPLACE FUNCTION @extschema@.drop_range_partition_expand_next(relid REGCLASS)
901+
RETURNS VOID AS 'pg_pathman', 'drop_range_partition_expand_next'
902+
LANGUAGE C STRICT;
903+
904+
955905
/*
956906
* Attach range partition
957907
*/

sql/pathman_basic.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,11 @@ SELECT pathman.prepend_range_partition('test.num_range_rel');
400400
EXPLAIN (COSTS OFF) SELECT * FROM test.num_range_rel WHERE id < 0;
401401
SELECT pathman.drop_range_partition('test.num_range_rel_7');
402402

403+
SELECT pathman.drop_range_partition_expand_next('test.num_range_rel_4');
404+
SELECT * FROM pathman.pathman_partition_list WHERE parent = 'test.num_range_rel'::regclass;
405+
SELECT pathman.drop_range_partition_expand_next('test.num_range_rel_6');
406+
SELECT * FROM pathman.pathman_partition_list WHERE parent = 'test.num_range_rel'::regclass;
407+
403408
SELECT pathman.append_range_partition('test.range_rel');
404409
SELECT pathman.prepend_range_partition('test.range_rel');
405410
EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE dt BETWEEN '2014-12-15' AND '2015-01-15';

src/pl_range_funcs.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ PG_FUNCTION_INFO_V1( get_part_range_by_idx );
5959
PG_FUNCTION_INFO_V1( build_range_condition );
6060
PG_FUNCTION_INFO_V1( build_sequence_name );
6161
PG_FUNCTION_INFO_V1( merge_range_partitions );
62+
PG_FUNCTION_INFO_V1( drop_range_partition_expand_next );
6263

6364

6465
/*
@@ -690,3 +691,62 @@ drop_table(Oid relid)
690691

691692
RemoveRelations(n);
692693
}
694+
695+
/*
696+
* Drops partition and expands the next partition so that it cover dropped
697+
* one
698+
*
699+
* This function was written in order to support Oracle-like ALTER TABLE ...
700+
* DROP PARTITION. In Oracle partitions only have upper bound and when
701+
* partition is dropped the next one automatically covers freed range
702+
*/
703+
Datum
704+
drop_range_partition_expand_next(PG_FUNCTION_ARGS)
705+
{
706+
PartParentSearch parent_search;
707+
const PartRelationInfo *prel;
708+
RangeEntry *ranges;
709+
Oid relid = PG_GETARG_OID(0),
710+
parent;
711+
int i;
712+
713+
/* Get parent relid */
714+
parent = get_parent_of_partition(relid, &parent_search);
715+
if (parent_search != PPS_ENTRY_PART_PARENT)
716+
elog(ERROR, "relation \"%s\" is not a partition",
717+
get_rel_name_or_relid(relid));
718+
719+
prel = get_pathman_relation_info(parent);
720+
shout_if_prel_is_invalid(parent, prel, PT_RANGE);
721+
722+
ranges = PrelGetRangesArray(prel);
723+
724+
/* Looking for partition in child relations */
725+
for (i = 0; i < prel->children_count; i++)
726+
if (ranges[i].child_oid == relid)
727+
break;
728+
729+
/*
730+
* It must be in ranges array because we already know that table
731+
* is a partition
732+
*/
733+
Assert(i < prel->children_count);
734+
735+
/* If there is next partition then expand it */
736+
if (i < prel->children_count - 1)
737+
{
738+
RangeEntry *cur = &ranges[i],
739+
*next = &ranges[i+1];
740+
741+
recreate_range_constraint(next->child_oid,
742+
get_relid_attribute_name(prel->key, prel->attnum),
743+
prel->attnum,
744+
prel->atttype,
745+
&cur->min,
746+
&next->max);
747+
}
748+
749+
drop_table(relid);
750+
751+
PG_RETURN_VOID();
752+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy