mirror of https://github.com/apache/druid.git
parent
b6941551ae
commit
bcea05e4e8
|
@ -118,48 +118,23 @@ public class CombineAndSimplifyBounds extends BottomUpTransform
|
||||||
* Simplify BoundDimFilters that are children of an OR or an AND.
|
* Simplify BoundDimFilters that are children of an OR or an AND.
|
||||||
*
|
*
|
||||||
* @param children the filters
|
* @param children the filters
|
||||||
* @param disjunction true for disjunction, false for conjunction
|
* @param disjunction true for OR, false for AND
|
||||||
*
|
*
|
||||||
* @return simplified filters
|
* @return simplified filters
|
||||||
*/
|
*/
|
||||||
private static DimFilter doSimplify(final List<DimFilter> children, boolean disjunction)
|
private static DimFilter doSimplify(final List<DimFilter> children, boolean disjunction)
|
||||||
{
|
{
|
||||||
// Copy children list
|
// Copy the list of child filters. We'll modify the copy and eventually return it.
|
||||||
final List<DimFilter> newChildren = Lists.newArrayList(children);
|
final List<DimFilter> newChildren = Lists.newArrayList(children);
|
||||||
|
|
||||||
// Group Bound filters by dimension, extractionFn, and comparator and compute a RangeSet for each one.
|
// Group Bound filters by dimension, extractionFn, and comparator and compute a RangeSet for each one.
|
||||||
final Map<BoundRefKey, List<BoundDimFilter>> bounds = new HashMap<>();
|
final Map<BoundRefKey, List<BoundDimFilter>> bounds = new HashMap<>();
|
||||||
|
|
||||||
final Iterator<DimFilter> iterator = newChildren.iterator();
|
for (final DimFilter child : newChildren) {
|
||||||
while (iterator.hasNext()) {
|
if (child instanceof BoundDimFilter) {
|
||||||
final DimFilter child = iterator.next();
|
|
||||||
|
|
||||||
if (child.equals(Filtration.matchNothing())) {
|
|
||||||
// Child matches nothing, equivalent to FALSE
|
|
||||||
// OR with FALSE => ignore
|
|
||||||
// AND with FALSE => always false, short circuit
|
|
||||||
if (disjunction) {
|
|
||||||
iterator.remove();
|
|
||||||
} else {
|
|
||||||
return Filtration.matchNothing();
|
|
||||||
}
|
|
||||||
} else if (child.equals(Filtration.matchEverything())) {
|
|
||||||
// Child matches everything, equivalent to TRUE
|
|
||||||
// OR with TRUE => always true, short circuit
|
|
||||||
// AND with TRUE => ignore
|
|
||||||
if (disjunction) {
|
|
||||||
return Filtration.matchEverything();
|
|
||||||
} else {
|
|
||||||
iterator.remove();
|
|
||||||
}
|
|
||||||
} else if (child instanceof BoundDimFilter) {
|
|
||||||
final BoundDimFilter bound = (BoundDimFilter) child;
|
final BoundDimFilter bound = (BoundDimFilter) child;
|
||||||
final BoundRefKey boundRefKey = BoundRefKey.from(bound);
|
final BoundRefKey boundRefKey = BoundRefKey.from(bound);
|
||||||
List<BoundDimFilter> filterList = bounds.get(boundRefKey);
|
final List<BoundDimFilter> filterList = bounds.computeIfAbsent(boundRefKey, k -> new ArrayList<>());
|
||||||
if (filterList == null) {
|
|
||||||
filterList = new ArrayList<>();
|
|
||||||
bounds.put(boundRefKey, filterList);
|
|
||||||
}
|
|
||||||
filterList.add(bound);
|
filterList.add(bound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,25 +159,13 @@ public class CombineAndSimplifyBounds extends BottomUpTransform
|
||||||
|
|
||||||
if (rangeSet.asRanges().isEmpty()) {
|
if (rangeSet.asRanges().isEmpty()) {
|
||||||
// range set matches nothing, equivalent to FALSE
|
// range set matches nothing, equivalent to FALSE
|
||||||
// OR with FALSE => ignore
|
newChildren.add(Filtration.matchNothing());
|
||||||
// AND with FALSE => always false, short circuit
|
|
||||||
if (disjunction) {
|
|
||||||
newChildren.add(Filtration.matchNothing());
|
|
||||||
} else {
|
|
||||||
return Filtration.matchNothing();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final Range<BoundValue> range : rangeSet.asRanges()) {
|
for (final Range<BoundValue> range : rangeSet.asRanges()) {
|
||||||
if (!range.hasLowerBound() && !range.hasUpperBound()) {
|
if (!range.hasLowerBound() && !range.hasUpperBound()) {
|
||||||
// range matches all, equivalent to TRUE
|
// range matches all, equivalent to TRUE
|
||||||
// AND with TRUE => ignore
|
newChildren.add(Filtration.matchEverything());
|
||||||
// OR with TRUE => always true; short circuit
|
|
||||||
if (disjunction) {
|
|
||||||
return Filtration.matchEverything();
|
|
||||||
} else {
|
|
||||||
newChildren.add(Filtration.matchEverything());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
newChildren.add(Bounds.toFilter(boundRefKey, range));
|
newChildren.add(Bounds.toFilter(boundRefKey, range));
|
||||||
}
|
}
|
||||||
|
@ -210,8 +173,44 @@ public class CombineAndSimplifyBounds extends BottomUpTransform
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finally: Go through newChildren, removing or potentially exiting early based on TRUE / FALSE marker filters.
|
||||||
Preconditions.checkState(newChildren.size() > 0, "newChildren.size > 0");
|
Preconditions.checkState(newChildren.size() > 0, "newChildren.size > 0");
|
||||||
if (newChildren.size() == 1) {
|
|
||||||
|
final Iterator<DimFilter> iterator = newChildren.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
final DimFilter newChild = iterator.next();
|
||||||
|
|
||||||
|
if (Filtration.matchNothing().equals(newChild)) {
|
||||||
|
// Child matches nothing, equivalent to FALSE
|
||||||
|
// OR with FALSE => ignore
|
||||||
|
// AND with FALSE => always false, short circuit
|
||||||
|
if (disjunction) {
|
||||||
|
iterator.remove();
|
||||||
|
} else {
|
||||||
|
return Filtration.matchNothing();
|
||||||
|
}
|
||||||
|
} else if (Filtration.matchEverything().equals(newChild)) {
|
||||||
|
// Child matches everything, equivalent to TRUE
|
||||||
|
// OR with TRUE => always true, short circuit
|
||||||
|
// AND with TRUE => ignore
|
||||||
|
if (disjunction) {
|
||||||
|
return Filtration.matchEverything();
|
||||||
|
} else {
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newChildren.isEmpty()) {
|
||||||
|
// If "newChildren" is empty at this point, it must have consisted entirely of TRUE / FALSE marker filters.
|
||||||
|
if (disjunction) {
|
||||||
|
// Must have been all FALSE filters (the only kind we would have removed above).
|
||||||
|
return Filtration.matchNothing();
|
||||||
|
} else {
|
||||||
|
// Must have been all TRUE filters (the only kind we would have removed above).
|
||||||
|
return Filtration.matchEverything();
|
||||||
|
}
|
||||||
|
} else if (newChildren.size() == 1) {
|
||||||
return newChildren.get(0);
|
return newChildren.get(0);
|
||||||
} else {
|
} else {
|
||||||
return disjunction ? new OrDimFilter(newChildren) : new AndDimFilter(newChildren);
|
return disjunction ? new OrDimFilter(newChildren) : new AndDimFilter(newChildren);
|
||||||
|
|
|
@ -1891,6 +1891,28 @@ public class CalciteQueryTest extends BaseCalciteQueryTest
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGroupByNothingWithImpossibleTimeFilter() throws Exception
|
||||||
|
{
|
||||||
|
// Regression test for https://github.com/apache/incubator-druid/issues/7671
|
||||||
|
|
||||||
|
testQuery(
|
||||||
|
"SELECT COUNT(*) FROM druid.foo\n"
|
||||||
|
+ "WHERE FLOOR(__time TO DAY) = TIMESTAMP '2000-01-02 01:00:00'\n"
|
||||||
|
+ "OR FLOOR(__time TO DAY) = TIMESTAMP '2000-01-02 02:00:00'",
|
||||||
|
ImmutableList.of(
|
||||||
|
Druids.newTimeseriesQueryBuilder()
|
||||||
|
.dataSource(CalciteTests.DATASOURCE1)
|
||||||
|
.intervals(querySegmentSpec())
|
||||||
|
.granularity(Granularities.ALL)
|
||||||
|
.aggregators(aggregators(new CountAggregatorFactory("a0")))
|
||||||
|
.context(TIMESERIES_CONTEXT_DEFAULT)
|
||||||
|
.build()
|
||||||
|
),
|
||||||
|
ImmutableList.of()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGroupByOneColumnWithLiterallyFalseFilter() throws Exception
|
public void testGroupByOneColumnWithLiterallyFalseFilter() throws Exception
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue