From ff27c5477403aacb3bbf4c1d6167cf7bcafa1f58 Mon Sep 17 00:00:00 2001 From: Gian Merlino Date: Tue, 10 Apr 2018 10:35:09 -0700 Subject: [PATCH] SQL: Remove useless boolean CASTs in filters. (#5619) --- .../sql/calcite/expression/Expressions.java | 9 ++++-- .../druid/sql/calcite/CalciteQueryTest.java | 28 +++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/sql/src/main/java/io/druid/sql/calcite/expression/Expressions.java b/sql/src/main/java/io/druid/sql/calcite/expression/Expressions.java index 3cff45e36546..8917260d7417 100644 --- a/sql/src/main/java/io/druid/sql/calcite/expression/Expressions.java +++ b/sql/src/main/java/io/druid/sql/calcite/expression/Expressions.java @@ -218,9 +218,12 @@ public static DimFilter toFilter( final RexNode expression ) { - if (expression.getKind() == SqlKind.AND - || expression.getKind() == SqlKind.OR - || expression.getKind() == SqlKind.NOT) { + if (expression.getKind() == SqlKind.CAST && expression.getType().getSqlTypeName() == SqlTypeName.BOOLEAN) { + // Calcite sometimes leaves errant, useless cast-to-booleans inside filters. Strip them and continue. + return toFilter(plannerContext, rowSignature, Iterables.getOnlyElement(((RexCall) expression).getOperands())); + } else if (expression.getKind() == SqlKind.AND + || expression.getKind() == SqlKind.OR + || expression.getKind() == SqlKind.NOT) { final List filters = Lists.newArrayList(); for (final RexNode rexNode : ((RexCall) expression).getOperands()) { final DimFilter nextFilter = toFilter( diff --git a/sql/src/test/java/io/druid/sql/calcite/CalciteQueryTest.java b/sql/src/test/java/io/druid/sql/calcite/CalciteQueryTest.java index 12c9372a0919..5130a218045d 100644 --- a/sql/src/test/java/io/druid/sql/calcite/CalciteQueryTest.java +++ b/sql/src/test/java/io/druid/sql/calcite/CalciteQueryTest.java @@ -2965,6 +2965,34 @@ public void testCountStarWithTimeFilter() throws Exception ); } + @Test + public void testRemoveUselessCaseWhen() throws Exception + { + testQuery( + "SELECT COUNT(*) FROM druid.foo\n" + + "WHERE\n" + + " CASE\n" + + " WHEN __time >= TIME_PARSE('2000-01-01 00:00:00', 'yyyy-MM-dd HH:mm:ss') AND __time < TIMESTAMP '2001-01-01 00:00:00'\n" + + " THEN true\n" + + " ELSE false\n" + + " END\n" + + "OR\n" + + " __time >= TIMESTAMP '2010-01-01 00:00:00' AND __time < TIMESTAMP '2011-01-01 00:00:00'", + ImmutableList.of( + Druids.newTimeseriesQueryBuilder() + .dataSource(CalciteTests.DATASOURCE1) + .intervals(QSS(Intervals.of("2000/2001"), Intervals.of("2010/2011"))) + .granularity(Granularities.ALL) + .aggregators(AGGS(new CountAggregatorFactory("a0"))) + .context(TIMESERIES_CONTEXT_DEFAULT) + .build() + ), + ImmutableList.of( + new Object[]{3L} + ) + ); + } + @Test public void testCountStarWithTimeMillisecondFilters() throws Exception {