Skip to content

Commit f45faec

Browse files
authored
Skip dimension slices when we have empty dimension restriction (#9728)
During hypertable expansion, we process the qualifiers to derive the range for a dimension variable that encloses all matching rows. This range is used to find the chunks that could possibly contain these rows. When the qualifiers are contradictory, an invalid range can arise, with upper bound below lower bound. At the moment such a range can still match some dimension slices, because the dimension slice ends are checked against this range separately. The chunk will then be excluded by the Postgres constraint exclusion that handles contradictory clauses. Add a simple check to not match such contradictory search ranges, to save some work. In the long run, this moves the hypertable expansion closer to feature parity with Postgres constraint exclusion, which is costly and maybe could be avoided eventually. This is not visible in any tests, because the Postgres constrain exclusion compensates for whatever our hypertable expansion might miss.
1 parent 501714a commit f45faec

1 file changed

Lines changed: 42 additions & 0 deletions

File tree

src/hypertable_restrict_info.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,48 @@ gather_restriction_dimension_vectors(const HypertableRestrictInfo *hri)
727727
{
728728
const DimensionRestrictInfoOpen *open = (const DimensionRestrictInfoOpen *) dri;
729729

730+
/*
731+
* If the WHERE clause contains contradictory qualifiers, we can
732+
* arrive at a degenerate dimension restriction where
733+
* upper_bound < lower_bound. No row can match such restriction,
734+
* but some slices still can, because we're checking the slice
735+
* ends separately:
736+
* slice_start <= upper_bound < lower_bound <= slice_end
737+
* The chunk will pass our hypertable expansion and will later
738+
* be excluded by the Postgres constraint exclusion that handles
739+
* contradictory clauses. We can easily avoid this unneeded work
740+
* now. Return early when the lower bound is strictly above the
741+
* upper bound.
742+
*/
743+
if (open->upper_strategy != InvalidStrategy &&
744+
open->lower_strategy != InvalidStrategy)
745+
{
746+
Assert(open->upper_strategy == BTLessEqualStrategyNumber ||
747+
open->upper_strategy == BTLessStrategyNumber);
748+
Assert(open->lower_strategy == BTGreaterEqualStrategyNumber ||
749+
open->lower_strategy == BTGreaterStrategyNumber);
750+
751+
if (open->lower_bound > open->upper_bound)
752+
{
753+
/* No rows can match. */
754+
break;
755+
}
756+
else if (open->lower_bound == open->upper_bound)
757+
{
758+
/*
759+
* Some rows can match if both intervals are inclusive.
760+
*/
761+
if (open->upper_strategy != BTLessEqualStrategyNumber ||
762+
open->lower_strategy != BTGreaterEqualStrategyNumber)
763+
{
764+
break;
765+
}
766+
}
767+
}
768+
769+
/*
770+
* Find the slices matching the dimension restriction.
771+
*/
730772
ts_dimension_slice_scan_iterator_set_range(&it,
731773
open->base.dimension->fd.id,
732774
open->upper_strategy,

0 commit comments

Comments
 (0)