You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2017/10/02 21:00:09 UTC
[09/15] calcite git commit: [CALCITE-1987] Implement EXTRACT for JDBC
(Pavel Gubin)
[CALCITE-1987] Implement EXTRACT for JDBC (Pavel Gubin)
Remove EXTRACT_DATE function (it's all just EXTRACTi now),
and revise Druid adapter.
Close apache/calcite#539
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/796a28f9
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/796a28f9
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/796a28f9
Branch: refs/heads/master
Commit: 796a28f9a9d49a16971135074f315d536eb929cf
Parents: 8441e79
Author: pavelgubin <pa...@contiamo.com>
Authored: Thu Sep 14 14:53:41 2017 +0200
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Oct 2 11:13:43 2017 -0700
----------------------------------------------------------------------
.../calcite/adapter/enumerable/RexImpTable.java | 163 ++++++++++++++++++-
.../calcite/sql/fun/SqlStdOperatorTable.java | 5 -
.../sql2rel/StandardConvertletTable.java | 154 +-----------------
.../calcite/rel/rules/DateRangeRulesTest.java | 118 ++++++--------
.../java/org/apache/calcite/test/JdbcTest.java | 24 +++
.../apache/calcite/test/SqlValidatorTest.java | 1 -
.../org/apache/calcite/test/RelOptRulesTest.xml | 20 +--
.../org/apache/calcite/test/DruidAdapterIT.java | 64 ++++----
.../calcite/test/DruidDateRangeRulesTest.java | 24 +--
9 files changed, 283 insertions(+), 290 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/796a28f9/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
index 0b3aa84..3f99182 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
@@ -125,7 +125,7 @@ import static org.apache.calcite.sql.fun.SqlStdOperatorTable.DIVIDE_INTEGER;
import static org.apache.calcite.sql.fun.SqlStdOperatorTable.ELEMENT;
import static org.apache.calcite.sql.fun.SqlStdOperatorTable.EQUALS;
import static org.apache.calcite.sql.fun.SqlStdOperatorTable.EXP;
-import static org.apache.calcite.sql.fun.SqlStdOperatorTable.EXTRACT_DATE;
+import static org.apache.calcite.sql.fun.SqlStdOperatorTable.EXTRACT;
import static org.apache.calcite.sql.fun.SqlStdOperatorTable.FIRST_VALUE;
import static org.apache.calcite.sql.fun.SqlStdOperatorTable.FLOOR;
import static org.apache.calcite.sql.fun.SqlStdOperatorTable.GREATER_THAN;
@@ -323,8 +323,8 @@ public class RexImpTable {
new DatetimeArithmeticImplementor(), false);
defineImplementor(MINUS_DATE, NullPolicy.STRICT,
new DatetimeArithmeticImplementor(), false);
- defineMethod(EXTRACT_DATE, BuiltInMethod.UNIX_DATE_EXTRACT.method,
- NullPolicy.STRICT);
+ defineImplementor(EXTRACT, NullPolicy.STRICT,
+ new ExtractImplementor(), false);
defineImplementor(FLOOR, NullPolicy.STRICT,
new FloorImplementor(BuiltInMethod.FLOOR.method.getName(),
BuiltInMethod.UNIX_TIMESTAMP_FLOOR.method,
@@ -1889,6 +1889,163 @@ public class RexImpTable {
}
}
+ /** Implementor for the {@code EXTRACT(unit FROM datetime)} function. */
+ private static class ExtractImplementor implements NotNullImplementor {
+ public Expression implement(RexToLixTranslator translator, RexCall call,
+ List<Expression> translatedOperands) {
+ final TimeUnitRange timeUnitRange =
+ (TimeUnitRange) ((ConstantExpression) translatedOperands.get(0)).value;
+ final TimeUnit unit = timeUnitRange.startUnit;
+ Expression operand = translatedOperands.get(1);
+ final SqlTypeName sqlTypeName =
+ call.operands.get(1).getType().getSqlTypeName();
+ switch (unit) {
+ case MILLENNIUM:
+ case CENTURY:
+ case YEAR:
+ case QUARTER:
+ case MONTH:
+ case DAY:
+ case DOW:
+ case DOY:
+ case WEEK:
+ switch (sqlTypeName) {
+ case INTERVAL_YEAR:
+ case INTERVAL_YEAR_MONTH:
+ case INTERVAL_MONTH:
+ case INTERVAL_DAY:
+ case INTERVAL_DAY_HOUR:
+ case INTERVAL_DAY_MINUTE:
+ case INTERVAL_DAY_SECOND:
+ case INTERVAL_HOUR:
+ case INTERVAL_HOUR_MINUTE:
+ case INTERVAL_HOUR_SECOND:
+ case INTERVAL_MINUTE:
+ case INTERVAL_MINUTE_SECOND:
+ case INTERVAL_SECOND:
+ break;
+ case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
+ operand = Expressions.call(
+ BuiltInMethod.TIMESTAMP_WITH_LOCAL_TIME_ZONE_TO_TIMESTAMP.method,
+ operand,
+ Expressions.call(BuiltInMethod.TIME_ZONE.method, translator.getRoot()));
+ // fall through
+ case TIMESTAMP:
+ operand = Expressions.divide(operand,
+ Expressions.constant(TimeUnit.DAY.multiplier.longValue()));
+ // fall through
+ case DATE:
+ return Expressions.call(BuiltInMethod.UNIX_DATE_EXTRACT.method,
+ translatedOperands.get(0), operand);
+ default:
+ throw new AssertionError("unexpected " + sqlTypeName);
+ }
+ break;
+ case DECADE:
+ switch (sqlTypeName) {
+ case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
+ operand = Expressions.call(
+ BuiltInMethod.TIMESTAMP_WITH_LOCAL_TIME_ZONE_TO_TIMESTAMP.method,
+ operand,
+ Expressions.call(BuiltInMethod.TIME_ZONE.method, translator.getRoot()));
+ // fall through
+ case TIMESTAMP:
+ operand = Expressions.divide(operand,
+ Expressions.constant(TimeUnit.DAY.multiplier.longValue()));
+ // fall through
+ case DATE:
+ operand = Expressions.call(
+ BuiltInMethod.UNIX_DATE_EXTRACT.method,
+ Expressions.constant(TimeUnitRange.YEAR), operand);
+ return Expressions.divide(operand,
+ Expressions.constant(
+ unit.multiplier.divideToIntegralValue(TimeUnit.YEAR.multiplier)
+ .longValue()));
+ }
+ break;
+ case EPOCH:
+ switch (sqlTypeName) {
+ case DATE:
+ // convert to milliseconds
+ operand = Expressions.multiply(operand,
+ Expressions.constant(TimeUnit.DAY.multiplier.longValue()));
+ // fall through
+ case TIMESTAMP:
+ // convert to seconds
+ return Expressions.divide(operand,
+ Expressions.constant(TimeUnit.SECOND.multiplier.longValue()));
+ case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
+ operand = Expressions.call(
+ BuiltInMethod.TIMESTAMP_WITH_LOCAL_TIME_ZONE_TO_TIMESTAMP.method,
+ operand,
+ Expressions.call(BuiltInMethod.TIME_ZONE.method, translator.getRoot()));
+ return Expressions.divide(operand,
+ Expressions.constant(TimeUnit.SECOND.multiplier.longValue()));
+ case INTERVAL_YEAR:
+ case INTERVAL_YEAR_MONTH:
+ case INTERVAL_MONTH:
+ case INTERVAL_DAY:
+ case INTERVAL_DAY_HOUR:
+ case INTERVAL_DAY_MINUTE:
+ case INTERVAL_DAY_SECOND:
+ case INTERVAL_HOUR:
+ case INTERVAL_HOUR_MINUTE:
+ case INTERVAL_HOUR_SECOND:
+ case INTERVAL_MINUTE:
+ case INTERVAL_MINUTE_SECOND:
+ case INTERVAL_SECOND:
+ // no convertlet conversion, pass it as extract
+ throw new AssertionError("unexpected " + sqlTypeName);
+ }
+ break;
+ }
+
+ operand = mod(operand, getFactor(unit));
+ if (unit == TimeUnit.QUARTER) {
+ operand = Expressions.subtract(operand, Expressions.constant(1L));
+ }
+ operand = Expressions.divide(operand,
+ Expressions.constant(unit.multiplier.longValue()));
+ if (unit == TimeUnit.QUARTER) {
+ operand = Expressions.add(operand, Expressions.constant(1L));
+ }
+ return operand;
+ }
+
+ }
+
+ private static Expression mod(Expression operand, long factor) {
+ if (factor == 1L) {
+ return operand;
+ } else {
+ return Expressions.modulo(operand, Expressions.constant(factor));
+ }
+ }
+
+ private static long getFactor(TimeUnit unit) {
+ switch (unit) {
+ case DAY:
+ return 1L;
+ case HOUR:
+ return TimeUnit.DAY.multiplier.longValue();
+ case MINUTE:
+ return TimeUnit.HOUR.multiplier.longValue();
+ case SECOND:
+ return TimeUnit.MINUTE.multiplier.longValue();
+ case MONTH:
+ return TimeUnit.YEAR.multiplier.longValue();
+ case QUARTER:
+ return TimeUnit.YEAR.multiplier.longValue();
+ case YEAR:
+ case DECADE:
+ case CENTURY:
+ case MILLENNIUM:
+ return 1L;
+ default:
+ throw Util.unexpected(unit);
+ }
+ }
+
/** Implementor for the SQL {@code CASE} operator. */
private static class CaseImplementor implements CallImplementor {
public Expression implement(RexToLixTranslator translator, RexCall call,
http://git-wip-us.apache.org/repos/asf/calcite/blob/796a28f9/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
index 7b6b771..c8adf5e 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
@@ -1235,11 +1235,6 @@ public class SqlStdOperatorTable extends ReflectiveSqlOperatorTable {
}
};
- /** Internal operator that extracts time periods (year, month, date) from a
- * date in internal format (number of days since epoch). */
- public static final SqlSpecialOperator EXTRACT_DATE =
- new SqlSpecialOperator("EXTRACT_DATE", SqlKind.EXTRACT);
-
//-------------------------------------------------------------
// FUNCTIONS
//-------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/796a28f9/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
index 14bff94..4c45716 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
@@ -18,7 +18,6 @@ package org.apache.calcite.sql2rel;
import org.apache.calcite.avatica.util.DateTimeUtils;
import org.apache.calcite.avatica.util.TimeUnit;
-import org.apache.calcite.avatica.util.TimeUnitRange;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.type.RelDataType;
@@ -635,158 +634,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
SqlRexContext cx,
SqlExtractFunction op,
SqlCall call) {
- final RexBuilder rexBuilder = cx.getRexBuilder();
- final List<SqlNode> operands = call.getOperandList();
- final List<RexNode> exprs = convertExpressionList(cx, operands,
- SqlOperandTypeChecker.Consistency.NONE);
-
- // TODO: Will need to use decimal type for seconds with precision
- RelDataType resType =
- cx.getTypeFactory().createSqlType(SqlTypeName.BIGINT);
- resType =
- cx.getTypeFactory().createTypeWithNullability(
- resType,
- exprs.get(1).getType().isNullable());
- RexNode res = rexBuilder.makeReinterpretCast(
- resType, exprs.get(1), rexBuilder.makeLiteral(false));
-
- final TimeUnit unit =
- ((SqlIntervalQualifier) operands.get(0)).getStartUnit();
- final SqlTypeName sqlTypeName = exprs.get(1).getType().getSqlTypeName();
- switch (unit) {
- case MILLENNIUM:
- case CENTURY:
- case YEAR:
- case QUARTER:
- case MONTH:
- case DAY:
- case DOW:
- case DOY:
- case WEEK:
- switch (sqlTypeName) {
- case INTERVAL_YEAR:
- case INTERVAL_YEAR_MONTH:
- case INTERVAL_MONTH:
- case INTERVAL_DAY:
- case INTERVAL_DAY_HOUR:
- case INTERVAL_DAY_MINUTE:
- case INTERVAL_DAY_SECOND:
- case INTERVAL_HOUR:
- case INTERVAL_HOUR_MINUTE:
- case INTERVAL_HOUR_SECOND:
- case INTERVAL_MINUTE:
- case INTERVAL_MINUTE_SECOND:
- case INTERVAL_SECOND:
- break;
- case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
- RelDataType type =
- cx.getTypeFactory().createSqlType(SqlTypeName.TIMESTAMP);
- type = cx.getTypeFactory().createTypeWithNullability(
- type,
- exprs.get(1).getType().isNullable());
- res = rexBuilder.makeCast(type, res);
- // fall through
- case TIMESTAMP:
- res = divide(rexBuilder, res, TimeUnit.DAY.multiplier);
- // fall through
- case DATE:
- return rexBuilder.makeCall(resType, SqlStdOperatorTable.EXTRACT_DATE,
- ImmutableList.of(exprs.get(0), res));
- default:
- throw new AssertionError("unexpected " + sqlTypeName);
- }
- break;
- case DECADE:
- switch (sqlTypeName) {
- case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
- RelDataType type =
- cx.getTypeFactory().createSqlType(SqlTypeName.TIMESTAMP);
- type = cx.getTypeFactory().createTypeWithNullability(
- type,
- exprs.get(1).getType().isNullable());
- res = rexBuilder.makeCast(type, res);
- // fall through
- case TIMESTAMP:
- res = divide(rexBuilder, res, TimeUnit.DAY.multiplier);
- // fall through
- case DATE:
- res = rexBuilder.makeCall(resType, SqlStdOperatorTable.EXTRACT_DATE,
- ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.YEAR), res));
- return divide(rexBuilder, res, unit.multiplier.divide(TimeUnit.YEAR.multiplier));
- }
- break;
- case EPOCH:
- switch (sqlTypeName) {
- case DATE:
- // convert to milliseconds
- res = rexBuilder.makeCall(resType, SqlStdOperatorTable.MULTIPLY,
- ImmutableList.of(res, rexBuilder.makeExactLiteral(TimeUnit.DAY.multiplier)));
- // fall through
- case TIMESTAMP:
- // convert to seconds
- return divide(rexBuilder, res, TimeUnit.SECOND.multiplier);
- case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
- RelDataType type =
- cx.getTypeFactory().createSqlType(SqlTypeName.TIMESTAMP);
- type = cx.getTypeFactory().createTypeWithNullability(
- type,
- exprs.get(1).getType().isNullable());
- return divide(
- rexBuilder,
- rexBuilder.makeCast(type, res),
- TimeUnit.SECOND.multiplier);
- case INTERVAL_YEAR:
- case INTERVAL_YEAR_MONTH:
- case INTERVAL_MONTH:
- case INTERVAL_DAY:
- case INTERVAL_DAY_HOUR:
- case INTERVAL_DAY_MINUTE:
- case INTERVAL_DAY_SECOND:
- case INTERVAL_HOUR:
- case INTERVAL_HOUR_MINUTE:
- case INTERVAL_HOUR_SECOND:
- case INTERVAL_MINUTE:
- case INTERVAL_MINUTE_SECOND:
- case INTERVAL_SECOND:
- // no convertlet conversion, pass it as extract
- return convertFunction(cx, (SqlFunction) call.getOperator(), call);
- }
- break;
- }
-
- res = mod(rexBuilder, resType, res, getFactor(unit));
- if (unit == TimeUnit.QUARTER) {
- res = minus(rexBuilder, res, rexBuilder.makeExactLiteral(BigDecimal.ONE));
- }
- res = divide(rexBuilder, res, unit.multiplier);
- if (unit == TimeUnit.QUARTER) {
- res = plus(rexBuilder, res, rexBuilder.makeExactLiteral(BigDecimal.ONE));
- }
- return res;
- }
-
- private static BigDecimal getFactor(TimeUnit unit) {
- switch (unit) {
- case DAY:
- return BigDecimal.ONE;
- case HOUR:
- return TimeUnit.DAY.multiplier;
- case MINUTE:
- return TimeUnit.HOUR.multiplier;
- case SECOND:
- return TimeUnit.MINUTE.multiplier;
- case MONTH:
- return TimeUnit.YEAR.multiplier;
- case QUARTER:
- return TimeUnit.YEAR.multiplier;
- case YEAR:
- case DECADE:
- case CENTURY:
- case MILLENNIUM:
- return BigDecimal.ONE;
- default:
- throw Util.unexpected(unit);
- }
+ return convertFunction(cx, (SqlFunction) call.getOperator(), call);
}
private RexNode mod(RexBuilder rexBuilder, RelDataType resType, RexNode res,
http://git-wip-us.apache.org/repos/asf/calcite/blob/796a28f9/core/src/test/java/org/apache/calcite/rel/rules/DateRangeRulesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/rel/rules/DateRangeRulesTest.java b/core/src/test/java/org/apache/calcite/rel/rules/DateRangeRulesTest.java
index ea7b58b..5fd746d 100644
--- a/core/src/test/java/org/apache/calcite/rel/rules/DateRangeRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/rel/rules/DateRangeRulesTest.java
@@ -53,34 +53,34 @@ public class DateRangeRulesTest {
assertThat(DateRangeRules.extractTimeUnits(f.literal(1)), is(set()));
// extract YEAR from a DATE column
- checkDateRange(f, e, is("AND(>=($8, 2014-01-01), <($8, 2015-01-01))"));
+ checkDateRange(f, e, is("AND(>=($9, 2014-01-01), <($9, 2015-01-01))"));
checkDateRange(f, f.eq(f.exYear, f.literal(2014)),
- is("AND(>=($8, 2014-01-01), <($8, 2015-01-01))"));
+ is("AND(>=($9, 2014-01-01), <($9, 2015-01-01))"));
checkDateRange(f, f.ge(f.exYear, f.literal(2014)),
- is(">=($8, 2014-01-01)"));
+ is(">=($9, 2014-01-01)"));
checkDateRange(f, f.gt(f.exYear, f.literal(2014)),
- is(">=($8, 2015-01-01)"));
+ is(">=($9, 2015-01-01)"));
checkDateRange(f, f.lt(f.exYear, f.literal(2014)),
- is("<($8, 2014-01-01)"));
+ is("<($9, 2014-01-01)"));
checkDateRange(f, f.le(f.exYear, f.literal(2014)),
- is("<($8, 2015-01-01)"));
+ is("<($9, 2015-01-01)"));
checkDateRange(f, f.ne(f.exYear, f.literal(2014)),
- is("<>(EXTRACT_DATE(FLAG(YEAR), $8), 2014)"));
+ is("<>(EXTRACT(FLAG(YEAR), $9), 2014)"));
}
@Test public void testExtractYearFromTimestampColumn() {
final Fixture2 f = new Fixture2();
- checkDateRange(f, f.eq(f.exYearTs, f.literal(2014)),
+ checkDateRange(f, f.eq(f.exYear, f.literal(2014)),
is("AND(>=($9, 2014-01-01), <($9, 2015-01-01))"));
- checkDateRange(f, f.ge(f.exYearTs, f.literal(2014)),
+ checkDateRange(f, f.ge(f.exYear, f.literal(2014)),
is(">=($9, 2014-01-01)"));
- checkDateRange(f, f.gt(f.exYearTs, f.literal(2014)),
+ checkDateRange(f, f.gt(f.exYear, f.literal(2014)),
is(">=($9, 2015-01-01)"));
- checkDateRange(f, f.lt(f.exYearTs, f.literal(2014)),
+ checkDateRange(f, f.lt(f.exYear, f.literal(2014)),
is("<($9, 2014-01-01)"));
- checkDateRange(f, f.le(f.exYearTs, f.literal(2014)),
+ checkDateRange(f, f.le(f.exYear, f.literal(2014)),
is("<($9, 2015-01-01)"));
- checkDateRange(f, f.ne(f.exYearTs, f.literal(2014)),
+ checkDateRange(f, f.ne(f.exYear, f.literal(2014)),
is("<>(EXTRACT(FLAG(YEAR), $9), 2014)"));
}
@@ -88,10 +88,10 @@ public class DateRangeRulesTest {
final Fixture2 f = new Fixture2();
checkDateRange(f,
f.and(f.eq(f.exYear, f.literal(2014)), f.eq(f.exMonth, f.literal(6))),
- is("AND(AND(>=($8, 2014-01-01), <($8, 2015-01-01)),"
- + " AND(>=($8, 2014-06-01), <($8, 2014-07-01)))"),
- is("AND(>=($8, 2014-01-01), <($8, 2015-01-01),"
- + " >=($8, 2014-06-01), <($8, 2014-07-01))"));
+ is("AND(AND(>=($9, 2014-01-01), <($9, 2015-01-01)),"
+ + " AND(>=($9, 2014-06-01), <($9, 2014-07-01)))"),
+ is("AND(>=($9, 2014-01-01), <($9, 2015-01-01),"
+ + " >=($9, 2014-06-01), <($9, 2014-07-01))"));
}
/** Test case for
@@ -100,16 +100,16 @@ public class DateRangeRulesTest {
@Test public void testExtractYearAndMonthFromDateColumn2() {
final Fixture2 f = new Fixture2();
final String s1 = "AND("
- + "AND(>=($8, 2000-01-01), <($8, 2001-01-01)),"
+ + "AND(>=($9, 2000-01-01), <($9, 2001-01-01)),"
+ " OR("
- + "AND(>=($8, 2000-02-01), <($8, 2000-03-01)), "
- + "AND(>=($8, 2000-03-01), <($8, 2000-04-01)), "
- + "AND(>=($8, 2000-05-01), <($8, 2000-06-01))))";
- final String s2 = "AND(>=($8, 2000-01-01), <($8, 2001-01-01),"
+ + "AND(>=($9, 2000-02-01), <($9, 2000-03-01)), "
+ + "AND(>=($9, 2000-03-01), <($9, 2000-04-01)), "
+ + "AND(>=($9, 2000-05-01), <($9, 2000-06-01))))";
+ final String s2 = "AND(>=($9, 2000-01-01), <($9, 2001-01-01),"
+ " OR("
- + "AND(>=($8, 2000-02-01), <($8, 2000-03-01)), "
- + "AND(>=($8, 2000-03-01), <($8, 2000-04-01)), "
- + "AND(>=($8, 2000-05-01), <($8, 2000-06-01))))";
+ + "AND(>=($9, 2000-02-01), <($9, 2000-03-01)), "
+ + "AND(>=($9, 2000-03-01), <($9, 2000-04-01)), "
+ + "AND(>=($9, 2000-05-01), <($9, 2000-06-01))))";
final RexNode e =
f.and(f.eq(f.exYear, f.literal(2000)),
f.or(f.eq(f.exMonth, f.literal(2)),
@@ -122,14 +122,14 @@ public class DateRangeRulesTest {
final Fixture2 f = new Fixture2();
checkDateRange(f,
f.and(f.eq(f.exYear, f.literal(2010)), f.eq(f.exDay, f.literal(31))),
- is("AND(AND(>=($8, 2010-01-01), <($8, 2011-01-01)),"
- + " OR(AND(>=($8, 2010-01-31), <($8, 2010-02-01)),"
- + " AND(>=($8, 2010-03-31), <($8, 2010-04-01)),"
- + " AND(>=($8, 2010-05-31), <($8, 2010-06-01)),"
- + " AND(>=($8, 2010-07-31), <($8, 2010-08-01)),"
- + " AND(>=($8, 2010-08-31), <($8, 2010-09-01)),"
- + " AND(>=($8, 2010-10-31), <($8, 2010-11-01)),"
- + " AND(>=($8, 2010-12-31), <($8, 2011-01-01))))"));
+ is("AND(AND(>=($9, 2010-01-01), <($9, 2011-01-01)),"
+ + " OR(AND(>=($9, 2010-01-31), <($9, 2010-02-01)),"
+ + " AND(>=($9, 2010-03-31), <($9, 2010-04-01)),"
+ + " AND(>=($9, 2010-05-31), <($9, 2010-06-01)),"
+ + " AND(>=($9, 2010-07-31), <($9, 2010-08-01)),"
+ + " AND(>=($9, 2010-08-31), <($9, 2010-09-01)),"
+ + " AND(>=($9, 2010-10-31), <($9, 2010-11-01)),"
+ + " AND(>=($9, 2010-12-31), <($9, 2011-01-01))))"));
}
@@ -139,32 +139,32 @@ public class DateRangeRulesTest {
// namely 29th February 2012 and 2016.
//
// Currently there are redundant conditions, e.g.
- // "AND(>=($8, 2011-01-01), <($8, 2020-01-01))". We should remove them by
+ // "AND(>=($9, 2011-01-01), <($9, 2020-01-01))". We should remove them by
// folding intervals.
checkDateRange(f,
f.and(f.gt(f.exYear, f.literal(2010)), f.lt(f.exYear, f.literal(2020)),
f.eq(f.exMonth, f.literal(2)), f.eq(f.exDay, f.literal(29))),
- is("AND(>=($8, 2011-01-01),"
- + " AND(>=($8, 2011-01-01), <($8, 2020-01-01)),"
- + " OR(AND(>=($8, 2011-02-01), <($8, 2011-03-01)),"
- + " AND(>=($8, 2012-02-01), <($8, 2012-03-01)),"
- + " AND(>=($8, 2013-02-01), <($8, 2013-03-01)),"
- + " AND(>=($8, 2014-02-01), <($8, 2014-03-01)),"
- + " AND(>=($8, 2015-02-01), <($8, 2015-03-01)),"
- + " AND(>=($8, 2016-02-01), <($8, 2016-03-01)),"
- + " AND(>=($8, 2017-02-01), <($8, 2017-03-01)),"
- + " AND(>=($8, 2018-02-01), <($8, 2018-03-01)),"
- + " AND(>=($8, 2019-02-01), <($8, 2019-03-01))),"
- + " OR(AND(>=($8, 2012-02-29), <($8, 2012-03-01)),"
- + " AND(>=($8, 2016-02-29), <($8, 2016-03-01))))"));
+ is("AND(>=($9, 2011-01-01),"
+ + " AND(>=($9, 2011-01-01), <($9, 2020-01-01)),"
+ + " OR(AND(>=($9, 2011-02-01), <($9, 2011-03-01)),"
+ + " AND(>=($9, 2012-02-01), <($9, 2012-03-01)),"
+ + " AND(>=($9, 2013-02-01), <($9, 2013-03-01)),"
+ + " AND(>=($9, 2014-02-01), <($9, 2014-03-01)),"
+ + " AND(>=($9, 2015-02-01), <($9, 2015-03-01)),"
+ + " AND(>=($9, 2016-02-01), <($9, 2016-03-01)),"
+ + " AND(>=($9, 2017-02-01), <($9, 2017-03-01)),"
+ + " AND(>=($9, 2018-02-01), <($9, 2018-03-01)),"
+ + " AND(>=($9, 2019-02-01), <($9, 2019-03-01))),"
+ + " OR(AND(>=($9, 2012-02-29), <($9, 2012-03-01)),"
+ + " AND(>=($9, 2016-02-29), <($9, 2016-03-01))))"));
}
@Test public void testExtractYearMonthDayFromTimestampColumn() {
final Fixture2 f = new Fixture2();
checkDateRange(f,
- f.and(f.gt(f.exYearTs, f.literal(2010)),
- f.lt(f.exYearTs, f.literal(2020)),
- f.eq(f.exMonthTs, f.literal(2)), f.eq(f.exDayTs, f.literal(29))),
+ f.and(f.gt(f.exYear, f.literal(2010)),
+ f.lt(f.exYear, f.literal(2020)),
+ f.eq(f.exMonth, f.literal(2)), f.eq(f.exDay, f.literal(29))),
is("AND(>=($9, 2011-01-01),"
+ " AND(>=($9, 2011-01-01), <($9, 2020-01-01)),"
+ " OR(AND(>=($9, 2011-02-01), <($9, 2011-03-01)),"
@@ -212,26 +212,14 @@ public class DateRangeRulesTest {
private final RexNode exYear;
private final RexNode exMonth;
private final RexNode exDay;
- private final RexNode exYearTs;
- private final RexNode exMonthTs;
- private final RexNode exDayTs;
Fixture2() {
- exYear = rexBuilder.makeCall(intRelDataType,
- SqlStdOperatorTable.EXTRACT_DATE,
- ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.YEAR), dt));
- exMonth = rexBuilder.makeCall(intRelDataType,
- SqlStdOperatorTable.EXTRACT_DATE,
- ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.MONTH), dt));
- exDay = rexBuilder.makeCall(intRelDataType,
- SqlStdOperatorTable.EXTRACT_DATE,
- ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.DAY), dt));
- exYearTs = rexBuilder.makeCall(SqlStdOperatorTable.EXTRACT,
+ exYear = rexBuilder.makeCall(SqlStdOperatorTable.EXTRACT,
ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.YEAR), ts));
- exMonthTs = rexBuilder.makeCall(intRelDataType,
+ exMonth = rexBuilder.makeCall(intRelDataType,
SqlStdOperatorTable.EXTRACT,
ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.MONTH), ts));
- exDayTs = rexBuilder.makeCall(intRelDataType,
+ exDay = rexBuilder.makeCall(intRelDataType,
SqlStdOperatorTable.EXTRACT,
ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.DAY), ts));
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/796a28f9/core/src/test/java/org/apache/calcite/test/JdbcTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
index 2282037..7d722cb 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
@@ -1516,6 +1516,30 @@ public class JdbcTest {
});
}
+ @Test public void testExtractMonthFromTimestamp() {
+ CalciteAssert.that()
+ .with(CalciteAssert.Config.JDBC_FOODMART)
+ .query("select extract(month from \"birth_date\") as c \n"
+ + "from \"foodmart\".\"employee\" where \"employee_id\"=1")
+ .returns("C=8\n");
+ }
+
+ @Test public void testExtractYearFromTimestamp() {
+ CalciteAssert.that()
+ .with(CalciteAssert.Config.JDBC_FOODMART)
+ .query("select extract(year from \"birth_date\") as c \n"
+ + "from \"foodmart\".\"employee\" where \"employee_id\"=1")
+ .returns("C=1961\n");
+ }
+
+ @Test public void testExtractFromInterval() {
+ CalciteAssert.that()
+ .with(CalciteAssert.Config.JDBC_FOODMART)
+ .query("select extract(month from interval '2-3' year to month) as c \n"
+ + "from \"foodmart\".\"employee\" where \"employee_id\"=1")
+ .returns("C=3\n");
+ }
+
@Test public void testFloorDate() {
CalciteAssert.that()
.with(CalciteAssert.Config.JDBC_FOODMART)
http://git-wip-us.apache.org/repos/asf/calcite/blob/796a28f9/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
index 95c47fc..570c7a0 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -8575,7 +8575,6 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
+ "UNION ALL left\n"
+ "\n"
+ "$throw -\n"
- + "EXTRACT_DATE -\n"
+ "FILTER left\n"
+ "Reinterpret -\n"
+ "TABLE pre\n"
http://git-wip-us.apache.org/repos/asf/calcite/blob/796a28f9/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
index f575271..ecf1e46 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -18,11 +18,9 @@ limitations under the License.
<Root>
<TestCase name="testReduceNot">
<Resource name="sql">
- <![CDATA[select sal
-from emp
-where case when (sal = 1000) then
-(case when sal = 1000 then null else 1 end is null) else
-(case when sal = 2000 then null else 1 end is null) end is true]]>
+ <![CDATA[select *
+from (select (case when sal > 1000 then null else false end) as caseCol from emp)
+where NOT(caseCol)]]>
</Resource>
<Resource name="planAfter">
<![CDATA[
@@ -656,7 +654,7 @@ LogicalAggregate(group=[{0}], EXPR$1=[$SUM0($2)], EXPR$2=[SUM($1)])
</TestCase>
<TestCase name="testDistinctNonDistinctTwoAggregatesWithGrouping">
<Resource name="sql">
- <![CDATA[SELECT deptno, sum(comm), min(comm), SUM(DISTINCT sal)
+ <![CDATA[SELECT deptno, SUM(comm), MIN(comm), SUM(DISTINCT sal)
FROM emp
GROUP BY deptno]]>
</Resource>
@@ -678,7 +676,7 @@ LogicalAggregate(group=[{0}], EXPR$1=[SUM($2)], EXPR$2=[MIN($3)], EXPR$3=[SUM($1
</TestCase>
<TestCase name="testDistinctWithGrouping">
<Resource name="sql">
- <![CDATA[SELECT sal, sum(comm), min(comm), SUM(DISTINCT sal)
+ <![CDATA[SELECT sal, SUM(comm), MIN(comm), SUM(DISTINCT sal)
FROM emp
GROUP BY sal]]>
</Resource>
@@ -2331,14 +2329,14 @@ where extract(year from birthdate) = 2014and extract(month from birthdate) = 4]]
<Resource name="planBefore">
<![CDATA[
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], BIRTHDATE=[$9])
- LogicalFilter(condition=[AND(=(EXTRACT_DATE(FLAG(YEAR), Reinterpret($9)), 2014), =(EXTRACT_DATE(FLAG(MONTH), Reinterpret($9)), 4))])
+ LogicalFilter(condition=[AND(=(EXTRACT(FLAG(YEAR), $9), 2014), =(EXTRACT(FLAG(MONTH), $9), 4))])
LogicalTableScan(table=[[CATALOG, SALES, EMP_B]])
]]>
</Resource>
<Resource name="planAfter">
<![CDATA[
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], BIRTHDATE=[$9])
- LogicalFilter(condition=[AND(>=(Reinterpret($9), 2014-01-01), <(Reinterpret($9), 2015-01-01), >=(Reinterpret($9), 2014-04-01), <(Reinterpret($9), 2014-05-01))])
+ LogicalFilter(condition=[AND(>=($9, 2014-04-01), <($9, 2014-05-01))])
LogicalTableScan(table=[[CATALOG, SALES, EMP_B]])
]]>
</Resource>
@@ -2352,14 +2350,14 @@ where extract(year from birthdate) = 2014]]>
<Resource name="planBefore">
<![CDATA[
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], BIRTHDATE=[$9])
- LogicalFilter(condition=[=(EXTRACT_DATE(FLAG(YEAR), Reinterpret($9)), 2014)])
+ LogicalFilter(condition=[=(EXTRACT(FLAG(YEAR), $9), 2014)])
LogicalTableScan(table=[[CATALOG, SALES, EMP_B]])
]]>
</Resource>
<Resource name="planAfter">
<![CDATA[
LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], BIRTHDATE=[$9])
- LogicalFilter(condition=[AND(>=(Reinterpret($9), 2014-01-01), <(Reinterpret($9), 2015-01-01))])
+ LogicalFilter(condition=[AND(>=($9, 2014-01-01), <($9, 2015-01-01))])
LogicalTableScan(table=[[CATALOG, SALES, EMP_B]])
]]>
</Resource>
http://git-wip-us.apache.org/repos/asf/calcite/blob/796a28f9/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
----------------------------------------------------------------------
diff --git a/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java b/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
index 1a0d3d3..c167e06 100644
--- a/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
+++ b/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
@@ -1378,10 +1378,9 @@ public class DruidAdapterIT {
+ "where extract(year from \"timestamp\") = 1997\n"
+ "and extract(month from \"timestamp\") in (4, 6)\n";
final String explain = "DruidQuery(table=[[foodmart, foodmart]], "
- + "intervals=[[1900-01-09T00:00:00.000/2992-01-10T00:00:00.000]], filter=[AND(="
- + "(EXTRACT_DATE(FLAG(YEAR), /INT(CAST(Reinterpret($0)):TIMESTAMP(0), 86400000)), 1997), OR(=(EXTRACT_DATE"
- + "(FLAG(MONTH), /INT(CAST(Reinterpret($0)):TIMESTAMP(0), 86400000)), 4), =(EXTRACT_DATE(FLAG(MONTH), "
- + "/INT(CAST(Reinterpret($0)):TIMESTAMP(0), 86400000)), 6)))], groups=[{}], aggs=[[COUNT()]])";
+ + "intervals=[[1900-01-09T00:00:00.000/2992-01-10T00:00:00.000]], "
+ + "filter=[AND(=(EXTRACT(FLAG(YEAR), $0), 1997), OR(=(EXTRACT(FLAG(MONTH), $0), 4), "
+ + "=(EXTRACT(FLAG(MONTH), $0), 6)))], groups=[{}], aggs=[[COUNT()]])";
sql(sql)
.explainContains(explain)
.returnsUnordered("C=13500");
@@ -1586,10 +1585,9 @@ public class DruidAdapterIT {
+ "'timeZone':'UTC','locale':'en-US'}}"))
.explainContains("PLAN=EnumerableInterpreter\n"
+ " DruidQuery(table=[[foodmart, foodmart]], "
- + "intervals=[[1997-01-01T00:00:00.001/1997-01-20T00:00:00.000]], filter=[=($1, 1016)"
- + "], projects=[[EXTRACT_DATE(FLAG(DAY), /INT(CAST(Reinterpret($0)):TIMESTAMP(0), 86400000)), "
- + "EXTRACT_DATE(FLAG(MONTH), /INT(CAST(Reinterpret($0)):TIMESTAMP(0), 86400000)), EXTRACT_DATE(FLAG"
- + "(YEAR), /INT(CAST(Reinterpret($0)):TIMESTAMP(0), 86400000)), $1]], groups=[{0, 1, 2, 3}], aggs=[[]])\n")
+ + "intervals=[[1997-01-01T00:00:00.001/1997-01-20T00:00:00.000]], "
+ + "filter=[=($1, 1016)], projects=[[EXTRACT(FLAG(DAY), $0), EXTRACT(FLAG(MONTH), $0), "
+ + "EXTRACT(FLAG(YEAR), $0), $1]], groups=[{0, 1, 2, 3}], aggs=[[]])\n")
.returnsUnordered("day=2; month=1; year=1997; product_id=1016",
"day=10; month=1; year=1997; product_id=1016",
"day=13; month=1; year=1997; product_id=1016",
@@ -1620,10 +1618,9 @@ public class DruidAdapterIT {
+ "'timeZone':'UTC','locale':'en-US'}}"))
.explainContains("PLAN=EnumerableInterpreter\n"
+ " DruidQuery(table=[[foodmart, foodmart]], "
- + "intervals=[[1997-01-01T00:00:00.001/1997-01-20T00:00:00.000]], filter=[=($1, 1016)"
- + "], projects=[[EXTRACT_DATE(FLAG(DAY), /INT(CAST(Reinterpret($0)):TIMESTAMP(0), 86400000)), "
- + "EXTRACT_DATE(FLAG(MONTH), /INT(CAST(Reinterpret($0)):TIMESTAMP(0), 86400000)), EXTRACT_DATE(FLAG"
- + "(YEAR), /INT(CAST(Reinterpret($0)):TIMESTAMP(0), 86400000)), $1]], groups=[{0, 1, 2, 3}], aggs=[[]])\n")
+ + "intervals=[[1997-01-01T00:00:00.001/1997-01-20T00:00:00.000]], "
+ + "filter=[=($1, 1016)], projects=[[EXTRACT(FLAG(DAY), $0), EXTRACT(FLAG(MONTH), $0), "
+ + "EXTRACT(FLAG(YEAR), $0), $1]], groups=[{0, 1, 2, 3}], aggs=[[]])\n")
.returnsUnordered("EXPR$0=2; EXPR$1=1; EXPR$2=1997; product_id=1016",
"EXPR$0=10; EXPR$1=1; EXPR$2=1997; product_id=1016",
"EXPR$0=13; EXPR$1=1; EXPR$2=1997; product_id=1016",
@@ -1647,8 +1644,8 @@ public class DruidAdapterIT {
+ "'timeZone':'UTC','locale':'en-US'}}"))
.explainContains("PLAN=EnumerableInterpreter\n"
+ " DruidQuery(table=[[foodmart, foodmart]], "
- + "intervals=[[1997-01-01T00:00:00.001/1997-01-20T00:00:00.000]], filter=[=($1, 1016)], "
- + "projects=[[EXTRACT_DATE(FLAG(DAY), /INT(CAST(Reinterpret($0)):TIMESTAMP(0), 86400000)), $1]], "
+ + "intervals=[[1997-01-01T00:00:00.001/1997-01-20T00:00:00.000]], "
+ + "filter=[=($1, 1016)], projects=[[EXTRACT(FLAG(DAY), $0), $1]], "
+ "groups=[{0, 1}], aggs=[[]])\n")
.returnsUnordered("EXPR$0=2; dayOfMonth=1016", "EXPR$0=10; dayOfMonth=1016",
"EXPR$0=13; dayOfMonth=1016", "EXPR$0=16; dayOfMonth=1016");
@@ -1675,10 +1672,10 @@ public class DruidAdapterIT {
sql(sql)
.explainContains("PLAN=EnumerableInterpreter\n"
+ " DruidQuery(table=[[foodmart, foodmart]], "
- + "intervals=[[1900-01-09T00:00:00.000/2992-01-10T00:00:00.000]], filter=[AND(>=(CAST"
- + "($11):BIGINT, 8), <=(CAST($11):BIGINT, 10), <(CAST($10):BIGINT, 15), =(EXTRACT_DATE"
- + "(FLAG(YEAR), /INT(CAST(Reinterpret($0)):TIMESTAMP(0), 86400000)), 1997))], groups=[{}], "
- + "aggs=[[SUM($90)]])")
+ + "intervals=[[1900-01-09T00:00:00.000/2992-01-10T00:00:00.000]], "
+ + "filter=[AND(>=(CAST($11):BIGINT, 8), <=(CAST($11):BIGINT, 10), "
+ + "<(CAST($10):BIGINT, 15), =(EXTRACT(FLAG(YEAR), $0), 1997))], groups=[{}], "
+ + "aggs=[[SUM($90)]])\n")
.queryContains(druidChecker(druidQuery))
.returnsUnordered("EXPR$0=75364.09998679161");
}
@@ -1824,10 +1821,10 @@ public class DruidAdapterIT {
+ "'intervals':['1900-01-09T00:00:00.000/2992-01-10T00:00:00.000']}"))
.explainContains("PLAN=EnumerableInterpreter\n"
+ " DruidQuery(table=[[foodmart, foodmart]], "
- + "intervals=[[1900-01-09T00:00:00.000/2992-01-10T00:00:00.000]], filter=[>=(CAST($1)"
- + ":BIGINT, 1558)], projects=[[EXTRACT_DATE(FLAG(MONTH), /INT(CAST(Reinterpret($0)):TIMESTAMP(0), "
- + "86400000)), $1, $89]], groups=[{0, 1}], aggs=[[SUM($2)]], sort0=[0], sort1=[2], "
- + "sort2=[1], dir0=[ASC], dir1=[ASC], dir2=[ASC])");
+ + "intervals=[[1900-01-09T00:00:00.000/2992-01-10T00:00:00.000]], "
+ + "filter=[>=(CAST($1):BIGINT, 1558)], projects=[[EXTRACT(FLAG(MONTH), $0), $1, $89]], "
+ + "groups=[{0, 1}], aggs=[[SUM($2)]], sort0=[0], sort1=[2], sort2=[1], "
+ + "dir0=[ASC], dir1=[ASC], dir2=[ASC])");
}
@@ -1870,10 +1867,10 @@ public class DruidAdapterIT {
+ " by y DESC, m ASC, s DESC, \"product_id\" LIMIT 3";
final String expectedPlan = "PLAN=EnumerableInterpreter\n"
+ " DruidQuery(table=[[foodmart, foodmart]], "
- + "intervals=[[1900-01-09T00:00:00.000/2992-01-10T00:00:00.000]], filter=[>=(CAST($1)"
- + ":BIGINT, 1558)], projects=[[EXTRACT_DATE(FLAG(YEAR), /INT(CAST(Reinterpret($0)):TIMESTAMP(0), 86400000)),"
- + " EXTRACT_DATE(FLAG(MONTH), /INT(CAST(Reinterpret($0)):TIMESTAMP(0), 86400000)), $1, $89]], groups=[{0, 1,"
- + " 2}], aggs=[[SUM($3)]], sort0=[0], sort1=[1], sort2=[3], sort3=[2], dir0=[DESC], "
+ + "intervals=[[1900-01-09T00:00:00.000/2992-01-10T00:00:00.000]], "
+ + "filter=[>=(CAST($1):BIGINT, 1558)], projects=[[EXTRACT(FLAG(YEAR), $0), "
+ + "EXTRACT(FLAG(MONTH), $0), $1, $89]], groups=[{0, 1, 2}], aggs=[[SUM($3)]], sort0=[0], "
+ + "sort1=[1], sort2=[3], sort3=[2], dir0=[DESC], "
+ "dir1=[ASC], dir2=[DESC], dir3=[ASC], fetch=[3])";
final String expectedDruidQuery = "{'queryType':'groupBy','dataSource':'foodmart',"
+ "'granularity':'all','dimensions':[{'type':'extraction',"
@@ -1906,11 +1903,10 @@ public class DruidAdapterIT {
+ " by s DESC, m DESC, \"product_id\" LIMIT 3";
final String expectedPlan = "PLAN=EnumerableInterpreter\n"
+ " DruidQuery(table=[[foodmart, foodmart]], "
- + "intervals=[[1900-01-09T00:00:00.000/2992-01-10T00:00:00.000]], filter=[>=(CAST($1)"
- + ":BIGINT, 1558)], projects=[[EXTRACT_DATE(FLAG(YEAR), /INT(CAST(Reinterpret($0)):TIMESTAMP(0), 86400000)),"
- + " EXTRACT_DATE(FLAG(MONTH), /INT(CAST(Reinterpret($0)):TIMESTAMP(0), 86400000)), $1, $89]], groups=[{0, 1,"
- + " 2}], aggs=[[SUM($3)]], sort0=[3], sort1=[1], sort2=[2], dir0=[DESC], dir1=[DESC], "
- + "dir2=[ASC], fetch=[3])";
+ + "intervals=[[1900-01-09T00:00:00.000/2992-01-10T00:00:00.000]], "
+ + "filter=[>=(CAST($1):BIGINT, 1558)], projects=[[EXTRACT(FLAG(YEAR), $0), "
+ + "EXTRACT(FLAG(MONTH), $0), $1, $89]], groups=[{0, 1, 2}], aggs=[[SUM($3)]], "
+ + "sort0=[3], sort1=[1], sort2=[2], dir0=[DESC], dir1=[DESC], dir2=[ASC], fetch=[3])";
final String expectedDruidQuery = "{'queryType':'groupBy','dataSource':'foodmart',"
+ "'granularity':'all','dimensions':[{'type':'extraction',"
+ "'dimension':'__time','outputName':'extract_year',"
@@ -2040,10 +2036,10 @@ public class DruidAdapterIT {
+ "\"product_id\" = 1558 group by extract(CENTURY from \"timestamp\")";
final String plan = "PLAN=EnumerableInterpreter\n"
+ " BindableAggregate(group=[{0}])\n"
- + " BindableProject(EXPR$0=[EXTRACT_DATE(FLAG(CENTURY), /INT(CAST(Reinterpret($0)):TIMESTAMP(0), 86400000))])\n"
+ + " BindableProject(EXPR$0=[EXTRACT(FLAG(CENTURY), $0)])\n"
+ " DruidQuery(table=[[foodmart, foodmart]], "
- + "intervals=[[1900-01-09T00:00:00.000/2992-01-10T00:00:00.000]], filter=[=($1, 1558)], "
- + "projects=[[$0]])";
+ + "intervals=[[1900-01-09T00:00:00.000/2992-01-10T00:00:00.000]], "
+ + "filter=[=($1, 1558)], projects=[[$0]])\n";
sql(sql).explainContains(plan).queryContains(druidChecker("'queryType':'select'"))
.returnsUnordered("EXPR$0=20");
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/796a28f9/druid/src/test/java/org/apache/calcite/test/DruidDateRangeRulesTest.java
----------------------------------------------------------------------
diff --git a/druid/src/test/java/org/apache/calcite/test/DruidDateRangeRulesTest.java b/druid/src/test/java/org/apache/calcite/test/DruidDateRangeRulesTest.java
index 0e1948d..f993a53 100644
--- a/druid/src/test/java/org/apache/calcite/test/DruidDateRangeRulesTest.java
+++ b/druid/src/test/java/org/apache/calcite/test/DruidDateRangeRulesTest.java
@@ -112,9 +112,9 @@ public class DruidDateRangeRulesTest {
// OR(AND(>=($9, 2012-02-29), <($9, 2012-03-01)),"
// AND(>=($9, 2016-02-29), <($9, 2016-03-01))))
checkDateRange(f,
- f.and(f.gt(f.exYearTs, f.literal(2010)),
- f.lt(f.exYearTs, f.literal(2020)),
- f.eq(f.exMonthTs, f.literal(2)), f.eq(f.exDayTs, f.literal(29))),
+ f.and(f.gt(f.exYear, f.literal(2010)),
+ f.lt(f.exYear, f.literal(2020)),
+ f.eq(f.exMonth, f.literal(2)), f.eq(f.exDay, f.literal(29))),
is("[2012-02-29T00:00:00.000/2012-03-01T00:00:00.000, "
+ "2016-02-29T00:00:00.000/2016-03-01T00:00:00.000]"));
}
@@ -190,26 +190,14 @@ public class DruidDateRangeRulesTest {
private final RexNode exYear;
private final RexNode exMonth;
private final RexNode exDay;
- private final RexNode exYearTs;
- private final RexNode exMonthTs;
- private final RexNode exDayTs;
Fixture2() {
- exYear = rexBuilder.makeCall(intRelDataType,
- SqlStdOperatorTable.EXTRACT_DATE,
- ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.YEAR), dt));
- exMonth = rexBuilder.makeCall(intRelDataType,
- SqlStdOperatorTable.EXTRACT_DATE,
- ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.MONTH), dt));
- exDay = rexBuilder.makeCall(intRelDataType,
- SqlStdOperatorTable.EXTRACT_DATE,
- ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.DAY), dt));
- exYearTs = rexBuilder.makeCall(SqlStdOperatorTable.EXTRACT,
+ exYear = rexBuilder.makeCall(SqlStdOperatorTable.EXTRACT,
ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.YEAR), ts));
- exMonthTs = rexBuilder.makeCall(intRelDataType,
+ exMonth = rexBuilder.makeCall(intRelDataType,
SqlStdOperatorTable.EXTRACT,
ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.MONTH), ts));
- exDayTs = rexBuilder.makeCall(intRelDataType,
+ exDay = rexBuilder.makeCall(intRelDataType,
SqlStdOperatorTable.EXTRACT,
ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.DAY), ts));
}