Skip to content

Commit 833707c

Browse files
committed
refactoring to make half open partitions work (not finished yet)
1 parent fd46919 commit 833707c

File tree

8 files changed

+419
-156
lines changed

8 files changed

+419
-156
lines changed

range.sql

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -505,15 +505,17 @@ BEGIN
505505
partition_name);
506506

507507
/* Copy data */
508-
v_cond := @extschema@.build_range_condition(v_attname, split_value, p_range[2]);
508+
v_cond := @extschema@.build_range_condition(v_new_partition::regclass,
509+
v_attname, split_value, p_range[2]);
509510
EXECUTE format('WITH part_data AS (DELETE FROM %s WHERE %s RETURNING *)
510511
INSERT INTO %s SELECT * FROM part_data',
511512
partition::TEXT,
512513
v_cond,
513514
v_new_partition);
514515

515516
/* Alter original partition */
516-
v_cond := @extschema@.build_range_condition(v_attname, p_range[1], split_value);
517+
v_cond := @extschema@.build_range_condition(partition::regclass,
518+
v_attname, p_range[1], split_value);
517519
v_check_name := @extschema@.build_check_constraint_name(partition, v_attname);
518520

519521
EXECUTE format('ALTER TABLE %s DROP CONSTRAINT %s',
@@ -612,6 +614,8 @@ DECLARE
612614
v_attname TEXT;
613615
v_atttype REGTYPE;
614616
v_check_name TEXT;
617+
v_lower_bound dummy%TYPE;
618+
v_upper_bound dummy%TYPE;
615619

616620
BEGIN
617621
SELECT attname FROM @extschema@.pathman_config
@@ -642,13 +646,28 @@ BEGIN
642646
partition1::TEXT,
643647
v_check_name);
644648

649+
/* Determine left bound */
650+
IF p_range[1] IS NULL OR p_range[3] IS NULL THEN
651+
v_lower_bound := NULL;
652+
ELSE
653+
v_lower_bound := least(p_range[1], p_range[3]);
654+
END IF;
655+
656+
/* Determine right bound */
657+
IF p_range[2] IS NULL OR p_range[4] IS NULL THEN
658+
v_upper_bound := NULL;
659+
ELSE
660+
v_upper_bound := greatest(p_range[2], p_range[4]);
661+
END IF;
662+
645663
/* and create a new one */
646664
EXECUTE format('ALTER TABLE %s ADD CONSTRAINT %s CHECK (%s)',
647665
partition1::TEXT,
648666
v_check_name,
649-
@extschema@.build_range_condition(v_attname,
650-
least(p_range[1], p_range[3]),
651-
greatest(p_range[2], p_range[4])));
667+
@extschema@.build_range_condition(partition1,
668+
v_attname,
669+
v_lower_bound,
670+
v_upper_bound));
652671

653672
/* Copy data from second partition to the first one */
654673
EXECUTE format('WITH part_data AS (DELETE FROM %s RETURNING *)
@@ -745,6 +764,10 @@ BEGIN
745764
USING parent_relid
746765
INTO p_range;
747766

767+
IF p_range[2] IS NULL THEN
768+
RAISE EXCEPTION 'Cannot append partition because last partition is half open';
769+
END IF;
770+
748771
IF @extschema@.is_date_type(p_atttype) THEN
749772
v_part_name := @extschema@.create_single_range_partition(
750773
parent_relid,
@@ -855,6 +878,10 @@ BEGIN
855878
USING parent_relid
856879
INTO p_range;
857880

881+
IF p_range[1] IS NULL THEN
882+
RAISE EXCEPTION 'Cannot prepend partition because first partition is half open';
883+
END IF;
884+
858885
IF @extschema@.is_date_type(p_atttype) THEN
859886
v_part_name := @extschema@.create_single_range_partition(
860887
parent_relid,
@@ -1045,7 +1072,8 @@ BEGIN
10451072
EXECUTE format('ALTER TABLE %s ADD CONSTRAINT %s CHECK (%s)',
10461073
partition::TEXT,
10471074
@extschema@.build_check_constraint_name(partition, v_attname),
1048-
@extschema@.build_range_condition(v_attname,
1075+
@extschema@.build_range_condition(partition,
1076+
v_attname,
10491077
start_value,
10501078
end_value));
10511079

@@ -1230,6 +1258,7 @@ SET client_min_messages = WARNING;
12301258
* Construct CHECK constraint condition for a range partition.
12311259
*/
12321260
CREATE OR REPLACE FUNCTION @extschema@.build_range_condition(
1261+
p_relid REGCLASS,
12331262
p_attname TEXT,
12341263
start_value ANYELEMENT,
12351264
end_value ANYELEMENT)

src/init.c

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -383,10 +383,13 @@ fill_prel_with_partitions(const Oid *partitions,
383383
&lower_null, &upper_null))
384384
{
385385
prel->ranges[i].child_oid = partitions[i];
386-
prel->ranges[i].min = lower;
387-
prel->ranges[i].max = upper;
388-
prel->ranges[i].infinite_min = lower_null;
389-
prel->ranges[i].infinite_max = upper_null;
386+
// prel->ranges[i].min = lower;
387+
// prel->ranges[i].max = upper;
388+
// prel->ranges[i].infinite_min = lower_null;
389+
// prel->ranges[i].infinite_max = upper_null;
390+
(&prel->ranges[i].min)->value = lower;
391+
MakeInfinitable(&prel->ranges[i].min, lower, lower_null);
392+
MakeInfinitable(&prel->ranges[i].max, upper, upper_null);
390393
}
391394
else
392395
{
@@ -428,13 +431,21 @@ fill_prel_with_partitions(const Oid *partitions,
428431
old_mcxt = MemoryContextSwitchTo(TopMemoryContext);
429432
for (i = 0; i < PrelChildrenCount(prel); i++)
430433
{
431-
prel->ranges[i].max = datumCopy(prel->ranges[i].max,
432-
prel->attbyval,
433-
prel->attlen);
434-
435-
prel->ranges[i].min = datumCopy(prel->ranges[i].min,
436-
prel->attbyval,
437-
prel->attlen);
434+
// prel->ranges[i].max = datumCopy(prel->ranges[i].max,
435+
// prel->attbyval,
436+
// prel->attlen);
437+
CopyInfinitable(&(prel->ranges[i].max),
438+
&(prel->ranges[i].max),
439+
prel->attbyval,
440+
prel->attlen);
441+
442+
// prel->ranges[i].min = datumCopy(prel->ranges[i].min,
443+
// prel->attbyval,
444+
// prel->attlen);
445+
CopyInfinitable(&prel->ranges[i].min,
446+
&prel->ranges[i].min,
447+
prel->attbyval,
448+
prel->attlen);
438449
}
439450
MemoryContextSwitchTo(old_mcxt);
440451

@@ -869,15 +880,21 @@ cmp_range_entries(const void *p1, const void *p2, void *arg)
869880
Oid cmp_proc_oid = *(Oid *) arg;
870881

871882
/* If range is half open */
872-
if (v1->infinite_min)
883+
if (IsInfinite(&v1->min))
873884
{
874-
if (v2->infinite_min)
875-
return Int32GetDatum(0);
885+
// if (IsInfinite(&v2->min))
886+
// return Int32GetDatum(0);
876887
return Int32GetDatum(-1);
877888
}
889+
if (IsInfinite(&v2->min))
890+
{
891+
return Int32GetDatum(1);
892+
}
878893

879894
/* Else if range is closed */
880-
return OidFunctionCall2(cmp_proc_oid, v1->min, v2->min);
895+
return OidFunctionCall2(cmp_proc_oid,
896+
InfinitableGetValue(&v1->min),
897+
InfinitableGetValue(&v2->min));
881898
}
882899

883900
/*
@@ -928,7 +945,7 @@ validate_range_constraint(const Expr *expr,
928945

929946
if (!expr)
930947
return false;
931-
*lower_null = *upper_null = false;
948+
*lower_null = *upper_null = true;
932949
tce = lookup_type_cache(prel->atttype, TYPECACHE_BTREE_OPFAMILY);
933950

934951
/* It could be either AND operator on top or just an OpExpr */

0 commit comments

Comments
 (0)