8000 bsearch: fix non-eq WHERE conditions pointing to gaps (issue #117) · postgrespro/pg_pathman@81668ed · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

8000
Appearance settings

Commit 81668ed

Browse files
committed
bsearch: fix non-eq WHERE conditions pointing to gaps (issue #117)
1 parent c858cc1 commit 81668ed

File tree

1 file changed

+46
-39
lines changed

1 file changed

+46
-39
lines changed

src/pg_pathman.c

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -591,22 +591,20 @@ select_range_partitions(const Datum value,
591591
WrapperNode *result) /* returned partitions */
592592
{
593593
bool lossy = false,
594-
is_less,
595-
is_greater;
596-
597-
#ifdef USE_ASSERT_CHECKING
598-
bool found = false;
599-
int counter = 0;
600-
#endif
594+
miss_left, /* 'value' is less than left bound */
595+
miss_right; /* 'value' is greater that right bound */
601596

602597
int startidx = 0,
603598
endidx = nranges - 1,
604599
cmp_min,
605600
cmp_max,
606-
i;
601+
i = 0;
607602

608603
Bound value_bound = MakeBound(value); /* convert value to Bound */
609604

605+
#ifdef USE_ASSERT_CHECKING
606+
int counter = 0;
607+
#endif
610608

611609
/* Initial value (no missing partitions found) */
612610
result->found_gap = false;
@@ -628,9 +626,9 @@ select_range_partitions(const Datum value,
628626
cmp_min = cmp_bounds(cmp_func, collid, &value_bound, &ranges[startidx].min);
629627
cmp_max = cmp_bounds(cmp_func, collid, &value_bound, &ranges[endidx].max);
630628

631-
if ((cmp_min <= 0 && strategy == BTLessStrategyNumber) ||
632-
(cmp_min < 0 && (strategy == BTLessEqualStrategyNumber ||
633-
strategy == BTEqualStrategyNumber)))
629+
if ((cmp_min <= 0 && strategy == BTLessStrategyNumber) ||
630+
(cmp_min < 0 && (strategy == BTLessEqualStrategyNumber ||
631+
strategy == BTEqualStrategyNumber)))
634632
{
635633
result->rangeset = NIL;
636634
return;
@@ -644,7 +642,7 @@ select_range_partitions(const Datum value,
644642
return;
645643
}
646644

647-
if ((cmp_min < 0 && strategy == BTGreaterStrategyNumber) ||
645+
if ((cmp_min < 0 && strategy == BTGreaterStrategyNumber) ||
648646
(cmp_min <= 0 && strategy == BTGreaterEqualStrategyNumber))
649647
{
650648
result->rangeset = list_make1_irange(make_irange(startidx,
@@ -677,44 +675,55 @@ select_range_partitions(const Datum value,
677675
cmp_min = cmp_bounds(cmp_func, collid, &value_bound, &ranges[i].min);
678676
cmp_max = cmp_bounds(cmp_func, collid, &value_bound, &ranges[i].max);
679677

680-
is_less = (cmp_min < 0 || (cmp_min == 0 && strategy == BTLessStrategyNumber));
681-
is_greater = (cmp_max > 0 || (cmp_max >= 0 && strategy != BTLessStrategyNumber));
678+
/* How is 'value' located with respect to left & right bounds? */
679+
miss_left = (cmp_min < 0 || (cmp_min == 0 && strategy == BTLessStrategyNumber));
680+
miss_right = (cmp_max > 0 || (cmp_max == 0 && strategy != BTLessStrategyNumber));
682681

683-
if (!is_less && !is_greater)
682+
/* Searched value is inside of partition */
683+
if (!miss_left && !miss_right)
684684
{
685-
if (strategy == BTGreaterEqualStrategyNumber && cmp_min == 0)
685+
/* 'value' == 'min' and we want everything on the right */
686+
if (cmp_min == 0 && strategy == BTGreaterEqualStrategyNumber)
686687
lossy = false;
687-
else if (strategy == BTLessStrategyNumber && cmp_max == 0)
688+
/* 'value' == 'max' and we want everything on the left */
689+
else if (cmp_max == 0 && strategy == BTLessStrategyNumber)
688690
lossy = false;
689-
else
690-
lossy = true;
691+
/* We're somewhere in the middle */
692+
else lossy = true;
691693

692-
#ifdef USE_ASSERT_CHECKING
693-
found = true;
694-
#endif
695-
break;
694+
break; /* just exit loop */
696695
}
697696

698697
/* Indices have met, looks like there's no partition */
699698
if (startidx >= endidx)
700699
{
701-
result->rangeset = NIL;
700+
result->rangeset = NIL;
702701
result->found_gap = true;
703-
return;
702+
703+
/* Return if it's "key = value" */
704+
if (strategy == BTEqualStrategyNumber)
705+
return;
706+
707+
if ((miss_left && (strategy == BTLessStrategyNumber ||
708+
strategy == BTLessEqualStrategyNumber)) ||
709+
(miss_right && (strategy == BTGreaterStrategyNumber ||
710+
strategy == BTGreaterEqualStrategyNumber)))
711+
lossy = true;
712+
else
713+
lossy = false;
714+
715+
break; /* just exit loop */
704716
}
705717

706-
if (is_less)
718+
if (miss_left)
707719
endidx = i - 1;
708-
else if (is_greater)
720+
else if (miss_right)
709721
startidx = i + 1;
710722

711723
/* For debug's sake */
712724
Assert(++counter < 100);
713725
}
714726

715-
/* Should've been found by now */
716-
Assert(found);
717-
718727
/* Filter partitions */
719728
switch(strategy)
720729
{
@@ -743,18 +752,16 @@ select_range_partitions(const Datum value,
743752
{
744753
result->rangeset = list_make1_irange(make_irange(i, i, IR_LOSSY));
745754
if (i < nranges - 1)
746-
result->rangeset =
747-
lappend_irange(result->rangeset,
748-
make_irange(i + 1,
749-
nranges - 1,
750-
IR_COMPLETE));
755+
result->rangeset = lappend_irange(result->rangeset,
756+
make_irange(i + 1,
757+
nranges - 1,
758+
IR_COMPLETE));
751759
}
752760
else
753761
{
754-
result->rangeset =
755-
list_make1_irange(make_irange(i,
756-
nranges - 1,
757-
IR_COMPLETE));
762+
result->rangeset = list_make1_irange(make_irange(i,
763+
nranges - 1,
764+
IR_COMPLETE));
758765
}
759766
break;
760767

0 commit comments

Comments
 (0)
0