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 2018/02/05 19:34:08 UTC
calcite git commit: [CALCITE-2156] In DateRangeRules,
compute FLOOR and CEIL of TIMESTAMP WITH LOCAL TIMEZONE in local time
zone
Repository: calcite
Updated Branches:
refs/heads/master e25e74977 -> 96d620be8
[CALCITE-2156] In DateRangeRules, compute FLOOR and CEIL of TIMESTAMP WITH LOCAL TIMEZONE in local time zone
Close apache/calcite#617
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/96d620be
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/96d620be
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/96d620be
Branch: refs/heads/master
Commit: 96d620be8054d83aca97d62780cb38cea928a655
Parents: e25e749
Author: Nishant <ni...@gmail.com>
Authored: Tue Jan 30 02:00:05 2018 +0530
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Feb 5 10:36:17 2018 -0800
----------------------------------------------------------------------
.../calcite/rel/rules/DateRangeRules.java | 56 +++++++++++++++++---
.../calcite/rel/rules/DateRangeRulesTest.java | 42 +++++++++++++--
.../apache/calcite/test/MockRelOptPlanner.java | 5 +-
.../apache/calcite/test/RelOptRulesTest.java | 18 +++++--
.../org/apache/calcite/test/RelOptTestBase.java | 9 ++++
.../calcite/test/RexImplicationCheckerTest.java | 5 ++
.../apache/calcite/test/SqlToRelTestBase.java | 37 +++++++++----
.../org/apache/calcite/test/DruidAdapterIT.java | 19 +++++++
.../calcite/test/DruidDateRangeRulesTest.java | 4 +-
9 files changed, 162 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/96d620be/core/src/main/java/org/apache/calcite/rel/rules/DateRangeRules.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/DateRangeRules.java b/core/src/main/java/org/apache/calcite/rel/rules/DateRangeRules.java
index 051ff7b..fac9f02 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/DateRangeRules.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/DateRangeRules.java
@@ -16,7 +16,9 @@
*/
package org.apache.calcite.rel.rules;
+import org.apache.calcite.avatica.util.DateTimeUtils;
import org.apache.calcite.avatica.util.TimeUnitRange;
+import org.apache.calcite.config.CalciteConnectionConfig;
import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.rel.core.Filter;
@@ -29,6 +31,7 @@ import org.apache.calcite.rex.RexShuttle;
import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.rex.RexVisitorImpl;
import org.apache.calcite.runtime.PredicateImpl;
+import org.apache.calcite.runtime.SqlFunctions;
import org.apache.calcite.sql.SqlBinaryOperator;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
@@ -37,6 +40,7 @@ import org.apache.calcite.tools.RelBuilderFactory;
import org.apache.calcite.util.Bug;
import org.apache.calcite.util.DateString;
import org.apache.calcite.util.TimestampString;
+import org.apache.calcite.util.TimestampWithTimeZoneString;
import org.apache.calcite.util.Util;
import com.google.common.annotations.VisibleForTesting;
@@ -61,6 +65,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TimeZone;
/**
* Collection of planner rules that convert
@@ -145,7 +150,8 @@ public abstract class DateRangeRules {
/** Replaces calls to EXTRACT, FLOOR and CEIL in an expression. */
@VisibleForTesting
- public static RexNode replaceTimeUnits(RexBuilder rexBuilder, RexNode e) {
+ public static RexNode replaceTimeUnits(RexBuilder rexBuilder, RexNode e,
+ String timeZone) {
ImmutableSortedSet<TimeUnitRange> timeUnits = extractTimeUnits(e);
if (!timeUnits.contains(TimeUnitRange.YEAR)) {
// Case when we have FLOOR or CEIL but no extract on YEAR.
@@ -157,7 +163,8 @@ public abstract class DateRangeRules {
final Map<String, RangeSet<Calendar>> operandRanges = new HashMap<>();
for (TimeUnitRange timeUnit : timeUnits) {
e = e.accept(
- new ExtractShuttle(rexBuilder, timeUnit, operandRanges, timeUnits));
+ new ExtractShuttle(rexBuilder, timeUnit, operandRanges, timeUnits,
+ timeZone));
}
return e;
}
@@ -174,8 +181,10 @@ public abstract class DateRangeRules {
@Override public void onMatch(RelOptRuleCall call) {
final Filter filter = call.rel(0);
final RexBuilder rexBuilder = filter.getCluster().getRexBuilder();
+ final String timeZone = filter.getCluster().getPlanner().getContext()
+ .unwrap(CalciteConnectionConfig.class).timeZone();
final RexNode condition =
- replaceTimeUnits(rexBuilder, filter.getCondition());
+ replaceTimeUnits(rexBuilder, filter.getCondition(), timeZone);
if (RexUtil.eq(condition, filter.getCondition())) {
return;
}
@@ -238,17 +247,19 @@ public abstract class DateRangeRules {
private final Map<String, RangeSet<Calendar>> operandRanges;
private final Deque<RexCall> calls = new ArrayDeque<>();
private final ImmutableSortedSet<TimeUnitRange> timeUnitRanges;
+ private final String timeZone;
@VisibleForTesting
ExtractShuttle(RexBuilder rexBuilder, TimeUnitRange timeUnit,
Map<String, RangeSet<Calendar>> operandRanges,
- ImmutableSortedSet<TimeUnitRange> timeUnitRanges) {
+ ImmutableSortedSet<TimeUnitRange> timeUnitRanges, String timeZone) {
this.rexBuilder = Preconditions.checkNotNull(rexBuilder);
this.timeUnit = Preconditions.checkNotNull(timeUnit);
Bug.upgrade("Change type to Map<RexNode, RangeSet<Calendar>> when"
+ " [CALCITE-1367] is fixed");
this.operandRanges = Preconditions.checkNotNull(operandRanges);
this.timeUnitRanges = Preconditions.checkNotNull(timeUnitRanges);
+ this.timeZone = timeZone;
}
@Override public RexNode visitCall(RexCall call) {
@@ -365,7 +376,7 @@ public abstract class DateRangeRules {
for (TimeUnitRange timeUnit : timeUnitRanges) {
clonedOperand = clonedOperand.accept(
new ExtractShuttle(rexBuilder, timeUnit, operandRanges,
- timeUnitRanges));
+ timeUnitRanges, timeZone));
}
if ((clonedOperand != operand) && (update != null)) {
update[0] = true;
@@ -507,11 +518,22 @@ public abstract class DateRangeRules {
private RexLiteral dateTimeLiteral(RexBuilder rexBuilder, Calendar calendar,
RexNode operand) {
+ final TimestampString ts;
+ final int p;
switch (operand.getType().getSqlTypeName()) {
case TIMESTAMP:
+ ts = TimestampString.fromCalendarFields(calendar);
+ p = operand.getType().getPrecision();
+ return rexBuilder.makeTimestampLiteral(ts, p);
case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
- final TimestampString ts = TimestampString.fromCalendarFields(calendar);
- return rexBuilder.makeTimestampLiteral(ts, operand.getType().getPrecision());
+ ts = TimestampString.fromCalendarFields(calendar);
+ final TimeZone tz = TimeZone.getTimeZone(this.timeZone);
+ final TimestampString localTs =
+ new TimestampWithTimeZoneString(ts, tz)
+ .withTimeZone(DateTimeUtils.UTC_ZONE)
+ .getLocalTimestampString();
+ p = operand.getType().getPrecision();
+ return rexBuilder.makeTimestampWithLocalTimeZoneLiteral(localTs, p);
case DATE:
final DateString d = DateString.fromCalendarFields(calendar);
return rexBuilder.makeDateLiteral(d);
@@ -558,7 +580,7 @@ public abstract class DateRangeRules {
rangeSet = ImmutableRangeSet.<Calendar>of().complement();
}
final RangeSet<Calendar> s2 = TreeRangeSet.create();
- final Calendar c = timeLiteral.getValueAs(Calendar.class);
+ final Calendar c = timestampValue(timeLiteral);
final Range<Calendar> range = floor
? floorRange(timeUnit, comparison, c)
: ceilRange(timeUnit, comparison, c);
@@ -572,6 +594,24 @@ public abstract class DateRangeRules {
return toRex(operand, range);
}
+ private Calendar timestampValue(RexLiteral timeLiteral) {
+ switch (timeLiteral.getTypeName()) {
+ case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
+ final TimeZone tz = TimeZone.getTimeZone(this.timeZone);
+ return Util.calendar(
+ SqlFunctions.timestampWithLocalTimeZoneToTimestamp(
+ timeLiteral.getValueAs(Long.class), tz));
+ case TIMESTAMP:
+ return Util.calendar(timeLiteral.getValueAs(Long.class));
+ case DATE:
+ // Cast date to timestamp with local time zone
+ final DateString d = timeLiteral.getValueAs(DateString.class);
+ return Util.calendar(d.getMillisSinceEpoch());
+ default:
+ throw Util.unexpected(timeLiteral.getTypeName());
+ }
+ }
+
private Range<Calendar> floorRange(TimeUnitRange timeUnit, SqlKind comparison,
Calendar c) {
Calendar floor = floor(c, timeUnit);
http://git-wip-us.apache.org/repos/asf/calcite/blob/96d620be/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 f0439ab..01fe9bc 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
@@ -20,6 +20,7 @@ import org.apache.calcite.avatica.util.TimeUnitRange;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.test.RexImplicationCheckerTest.Fixture;
+import org.apache.calcite.util.DateString;
import org.apache.calcite.util.TimestampString;
import org.apache.calcite.util.Util;
@@ -84,6 +85,7 @@ public class DateRangeRulesTest {
final Fixture2 f = new Fixture2();
checkDateRange(f,
f.and(f.eq(f.exYearD, f.literal(2014)), f.eq(f.exMonthD, f.literal(6))),
+ "UTC",
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),"
@@ -111,7 +113,7 @@ public class DateRangeRulesTest {
f.or(f.eq(f.exMonthD, f.literal(2)),
f.eq(f.exMonthD, f.literal(3)),
f.eq(f.exMonthD, f.literal(5))));
- checkDateRange(f, e, is(s1), is(s2));
+ checkDateRange(f, e, "UTC", is(s1), is(s2));
}
@Test public void testExtractYearAndDayFromDateColumn() {
@@ -657,17 +659,47 @@ public class DateRangeRulesTest {
is(">($9, 2009-01-01 00:00:00)"));
}
+ @Test public void testFloorRewriteWithTimezone() {
+ final Calendar c = Util.calendar();
+ c.clear();
+ c.set(2010, Calendar.FEBRUARY, 1, 11, 30, 0);
+ final Fixture2 f = new Fixture2();
+ checkDateRange(f,
+ f.eq(f.floorHour,
+ f.timestampLocalTzLiteral(TimestampString.fromCalendarFields(c))),
+ "IST",
+ is("AND(>=($9, 2010-02-01 17:00:00), <($9, 2010-02-01 18:00:00))"),
+ CoreMatchers.any(String.class));
+
+ c.clear();
+ c.set(2010, Calendar.FEBRUARY, 1, 11, 00, 0);
+ checkDateRange(f,
+ f.eq(f.floorHour,
+ f.timestampLiteral(TimestampString.fromCalendarFields(c))),
+ "IST",
+ is("AND(>=($9, 2010-02-01 11:00:00), <($9, 2010-02-01 12:00:00))"),
+ CoreMatchers.any(String.class));
+
+ c.clear();
+ c.set(2010, Calendar.FEBRUARY, 1, 00, 00, 0);
+ checkDateRange(f,
+ f.eq(f.floorHour, f.dateLiteral(DateString.fromCalendarFields(c))),
+ "IST",
+ is("AND(>=($9, 2010-02-01 00:00:00), <($9, 2010-02-01 01:00:00))"),
+ CoreMatchers.any(String.class));
+ }
+
private static Set<TimeUnitRange> set(TimeUnitRange... es) {
return ImmutableSet.copyOf(es);
}
private void checkDateRange(Fixture f, RexNode e, Matcher<String> matcher) {
- checkDateRange(f, e, matcher, CoreMatchers.any(String.class));
+ checkDateRange(f, e, "UTC", matcher, CoreMatchers.any(String.class));
}
- private void checkDateRange(Fixture f, RexNode e, Matcher<String> matcher,
- Matcher<String> simplifyMatcher) {
- e = DateRangeRules.replaceTimeUnits(f.rexBuilder, e);
+ private void checkDateRange(Fixture f, RexNode e, String timeZone,
+ Matcher<String> matcher, Matcher<String> simplifyMatcher) {
+ e = DateRangeRules.replaceTimeUnits(f.rexBuilder, e, timeZone);
assertThat(e.toString(), matcher);
final RexNode e2 = f.simplify.simplify(e);
assertThat(e2.toString(), simplifyMatcher);
http://git-wip-us.apache.org/repos/asf/calcite/blob/96d620be/core/src/test/java/org/apache/calcite/test/MockRelOptPlanner.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/MockRelOptPlanner.java b/core/src/test/java/org/apache/calcite/test/MockRelOptPlanner.java
index adce9a9..d35c019 100644
--- a/core/src/test/java/org/apache/calcite/test/MockRelOptPlanner.java
+++ b/core/src/test/java/org/apache/calcite/test/MockRelOptPlanner.java
@@ -17,6 +17,7 @@
package org.apache.calcite.test;
import org.apache.calcite.plan.AbstractRelOptPlanner;
+import org.apache.calcite.plan.Context;
import org.apache.calcite.plan.RelOptCostImpl;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelOptRule;
@@ -53,8 +54,8 @@ public class MockRelOptPlanner extends AbstractRelOptPlanner {
//~ Methods ----------------------------------------------------------------
/** Creates MockRelOptPlanner. */
- public MockRelOptPlanner() {
- super(RelOptCostImpl.FACTORY, null);
+ public MockRelOptPlanner(Context context) {
+ super(RelOptCostImpl.FACTORY, context);
setExecutor(new RexExecutorImpl(Schemas.createDataContext(null, null)));
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/96d620be/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index 2873531..2e2a5f6 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -16,6 +16,9 @@
*/
package org.apache.calcite.test;
+import org.apache.calcite.config.CalciteConnectionConfigImpl;
+import org.apache.calcite.plan.Context;
+import org.apache.calcite.plan.Contexts;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelOptUtil;
@@ -119,6 +122,7 @@ import org.junit.Test;
import java.util.Arrays;
import java.util.List;
+import java.util.Properties;
import javax.annotation.Nullable;
@@ -3178,7 +3182,7 @@ public class RelOptRulesTest extends RelOptTestBase {
Tester tester = new TesterImpl(getDiffRepos(), true, true, false, false,
null, null) {
@Override public RelOptPlanner createPlanner() {
- return new MockRelOptPlanner() {
+ return new MockRelOptPlanner(Contexts.empty()) {
@Override public List<RelTraitDef> getRelTraitDefs() {
return ImmutableList.<RelTraitDef>of(RelCollationTraitDef.INSTANCE);
}
@@ -3704,17 +3708,19 @@ public class RelOptRulesTest extends RelOptTestBase {
* Converting predicates on date dimension columns into date ranges</a>,
* specifically a rule that converts {@code EXTRACT(YEAR FROM ...) = constant}
* to a range. */
- @Test public void testExtractYearToRange() throws Exception {
+ @Test public void testExtractYearToRange() {
final String sql = "select *\n"
+ "from sales.emp_b as e\n"
+ "where extract(year from birthdate) = 2014";
HepProgram program = new HepProgramBuilder()
.addRuleInstance(DateRangeRules.FILTER_INSTANCE)
.build();
- sql(sql).with(program).check();
+ final Context context =
+ Contexts.of(new CalciteConnectionConfigImpl(new Properties()));
+ sql(sql).with(program).withContext(context).check();
}
- @Test public void testExtractYearMonthToRange() throws Exception {
+ @Test public void testExtractYearMonthToRange() {
final String sql = "select *\n"
+ "from sales.emp_b as e\n"
+ "where extract(year from birthdate) = 2014"
@@ -3722,7 +3728,9 @@ public class RelOptRulesTest extends RelOptTestBase {
HepProgram program = new HepProgramBuilder()
.addRuleInstance(DateRangeRules.FILTER_INSTANCE)
.build();
- sql(sql).with(program).check();
+ final Context context =
+ Contexts.of(new CalciteConnectionConfigImpl(new Properties()));
+ sql(sql).with(program).withContext(context).check();
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/96d620be/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java b/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java
index 848918e..114463f 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java
@@ -16,6 +16,7 @@
*/
package org.apache.calcite.test;
+import org.apache.calcite.plan.Context;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelOptUtil;
@@ -279,6 +280,14 @@ abstract class RelOptTestBase extends SqlToRelTestBase {
});
}
+ public Sql withContext(final Context context) {
+ return withTransform(
+ new Function<Tester, Tester>() {
+ public Tester apply(Tester tester) {
+ return tester.withContext(context);
+ }
+ });
+ }
public void check() {
check(false);
http://git-wip-us.apache.org/repos/asf/calcite/blob/96d620be/core/src/test/java/org/apache/calcite/test/RexImplicationCheckerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RexImplicationCheckerTest.java b/core/src/test/java/org/apache/calcite/test/RexImplicationCheckerTest.java
index 0a2d74b..296b497 100644
--- a/core/src/test/java/org/apache/calcite/test/RexImplicationCheckerTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RexImplicationCheckerTest.java
@@ -553,6 +553,11 @@ public class RexImplicationCheckerTest {
timestampDataType.getPrecision());
}
+ public RexNode timestampLocalTzLiteral(TimestampString ts) {
+ return rexBuilder.makeTimestampWithLocalTimeZoneLiteral(ts,
+ timestampDataType.getPrecision());
+ }
+
public RexNode timeLiteral(TimeString t) {
return rexBuilder.makeTimeLiteral(t, timeDataType.getPrecision());
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/96d620be/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java b/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
index c8ece76..1b9581d 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
@@ -17,6 +17,8 @@
package org.apache.calcite.test;
import org.apache.calcite.linq4j.tree.Expression;
+import org.apache.calcite.plan.Context;
+import org.apache.calcite.plan.Contexts;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptPlanner;
import org.apache.calcite.plan.RelOptSchema;
@@ -240,6 +242,9 @@ public abstract class SqlToRelTestBase {
Tester withClusterFactory(Function<RelOptCluster, RelOptCluster> function);
boolean isLateDecorrelate();
+
+ /** Returns a tester that uses a given context. */
+ Tester withContext(Context context);
}
//~ Inner Classes ----------------------------------------------------------
@@ -504,6 +509,7 @@ public abstract class SqlToRelTestBase {
private final Function<RelOptCluster, RelOptCluster> clusterFactory;
private RelDataTypeFactory typeFactory;
public final SqlToRelConverter.Config config;
+ private final Context context;
/**
* Creates a TesterImpl.
@@ -526,7 +532,8 @@ public abstract class SqlToRelTestBase {
catalogReaderFactory,
clusterFactory,
SqlToRelConverter.Config.DEFAULT,
- SqlConformanceEnum.DEFAULT);
+ SqlConformanceEnum.DEFAULT,
+ Contexts.empty());
}
protected TesterImpl(DiffRepository diffRepos, boolean enableDecorrelate,
@@ -534,7 +541,8 @@ public abstract class SqlToRelTestBase {
Function<RelDataTypeFactory, Prepare.CatalogReader>
catalogReaderFactory,
Function<RelOptCluster, RelOptCluster> clusterFactory,
- SqlToRelConverter.Config config, SqlConformance conformance) {
+ SqlToRelConverter.Config config, SqlConformance conformance,
+ Context context) {
this.diffRepos = diffRepos;
this.enableDecorrelate = enableDecorrelate;
this.enableTrim = enableTrim;
@@ -544,6 +552,7 @@ public abstract class SqlToRelTestBase {
this.clusterFactory = clusterFactory;
this.config = config;
this.conformance = conformance;
+ this.context = context;
}
public RelRoot convertSqlToRel(String sql) {
@@ -673,7 +682,7 @@ public abstract class SqlToRelTestBase {
}
public RelOptPlanner createPlanner() {
- return new MockRelOptPlanner();
+ return new MockRelOptPlanner(context);
}
public void assertConvertsTo(
@@ -734,7 +743,7 @@ public abstract class SqlToRelTestBase {
? this
: new TesterImpl(diffRepos, enableDecorrelate, enableTrim,
enableExpand, enableLateDecorrelate, catalogReaderFactory,
- clusterFactory, config, conformance);
+ clusterFactory, config, conformance, context);
}
public Tester withLateDecorrelation(boolean enableLateDecorrelate) {
@@ -742,7 +751,7 @@ public abstract class SqlToRelTestBase {
? this
: new TesterImpl(diffRepos, enableDecorrelate, enableTrim,
enableExpand, enableLateDecorrelate, catalogReaderFactory,
- clusterFactory, config, conformance);
+ clusterFactory, config, conformance, context);
}
public TesterImpl withConfig(SqlToRelConverter.Config config) {
@@ -750,7 +759,7 @@ public abstract class SqlToRelTestBase {
? this
: new TesterImpl(diffRepos, enableDecorrelate, enableTrim,
enableExpand, enableLateDecorrelate, catalogReaderFactory,
- clusterFactory, config, conformance);
+ clusterFactory, config, conformance, context);
}
public Tester withTrim(boolean enableTrim) {
@@ -758,7 +767,7 @@ public abstract class SqlToRelTestBase {
? this
: new TesterImpl(diffRepos, enableDecorrelate, enableTrim,
enableExpand, enableLateDecorrelate, catalogReaderFactory,
- clusterFactory, config, conformance);
+ clusterFactory, config, conformance, context);
}
public Tester withExpand(boolean enableExpand) {
@@ -766,27 +775,33 @@ public abstract class SqlToRelTestBase {
? this
: new TesterImpl(diffRepos, enableDecorrelate, enableTrim,
enableExpand, enableLateDecorrelate, catalogReaderFactory,
- clusterFactory, config, conformance);
+ clusterFactory, config, conformance, context);
}
public Tester withConformance(SqlConformance conformance) {
return new TesterImpl(diffRepos, enableDecorrelate, false,
enableExpand, enableLateDecorrelate, catalogReaderFactory,
- clusterFactory, config, conformance);
+ clusterFactory, config, conformance, context);
}
public Tester withCatalogReaderFactory(
Function<RelDataTypeFactory, Prepare.CatalogReader> factory) {
return new TesterImpl(diffRepos, enableDecorrelate, false,
enableExpand, enableLateDecorrelate, factory,
- clusterFactory, config, conformance);
+ clusterFactory, config, conformance, context);
}
public Tester withClusterFactory(
Function<RelOptCluster, RelOptCluster> clusterFactory) {
return new TesterImpl(diffRepos, enableDecorrelate, false,
enableExpand, enableLateDecorrelate, catalogReaderFactory,
- clusterFactory, config, conformance);
+ clusterFactory, config, conformance, context);
+ }
+
+ public Tester withContext(Context context) {
+ return new TesterImpl(diffRepos, enableDecorrelate, false,
+ enableExpand, enableLateDecorrelate, catalogReaderFactory,
+ clusterFactory, config, conformance, context);
}
public boolean isLateDecorrelate() {
http://git-wip-us.apache.org/repos/asf/calcite/blob/96d620be/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 e2cbab8..9d3191c 100644
--- a/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
+++ b/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
@@ -3487,6 +3487,25 @@ public class DruidAdapterIT {
.runs()
.queryContains(druidChecker("{\"queryType\":\"timeseries\""));
}
+
+ @Test public void testFloorToDateRangeWithTimeZone() {
+ final String sql = "Select cast(floor(\"timestamp\" to MONTH) as timestamp) as t from "
+ + "\"foodmart\" where floor(\"timestamp\" to MONTH) >= '1997-05-01 00:00:00 IST' "
+ + "and floor(\"timestamp\" to MONTH) < '1997-05-02 00:00:00 IST' order by t"
+ + " limit 1";
+ final String druidQuery = "{\"queryType\":\"scan\",\"dataSource\":\"foodmart\",\"intervals\":"
+ + "[\"1997-04-30T18:30:00.000Z/1997-05-31T18:30:00.000Z\"],\"columns\":[\"__time\"],"
+ + "\"granularity\":{\"type\":\"all\"},\"resultFormat\":\"compactedList\"}";
+ CalciteAssert.that()
+ .enable(enabled())
+ .with(ImmutableMap.of("model", FOODMART.getPath()))
+ .with(CalciteConnectionProperty.TIME_ZONE.camelName(), "IST")
+ .query(sql)
+ .runs()
+ .queryContains(druidChecker(druidQuery))
+ .returnsOrdered("T=1997-05-01 05:30:00");
+ }
+
}
// End DruidAdapterIT.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/96d620be/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 ceb2d5e..1b20b32 100644
--- a/druid/src/test/java/org/apache/calcite/test/DruidDateRangeRulesTest.java
+++ b/druid/src/test/java/org/apache/calcite/test/DruidDateRangeRulesTest.java
@@ -141,7 +141,7 @@ public class DruidDateRangeRulesTest {
// HiveRexExecutorImpl is used in Hive
private void checkDateRangeNoSimplify(Fixture f, RexNode e,
Matcher<String> intervalMatcher) {
- e = DateRangeRules.replaceTimeUnits(f.rexBuilder, e);
+ e = DateRangeRules.replaceTimeUnits(f.rexBuilder, e, "UTC");
final List<Interval> intervals =
DruidDateTimeUtils.createInterval(e, "UTC");
assertThat(intervals, notNullValue());
@@ -149,7 +149,7 @@ public class DruidDateRangeRulesTest {
}
private void checkDateRange(Fixture f, RexNode e, Matcher<String> intervalMatcher) {
- e = DateRangeRules.replaceTimeUnits(f.rexBuilder, e);
+ e = DateRangeRules.replaceTimeUnits(f.rexBuilder, e, "UTC");
final RexNode e2 = f.simplify.simplify(e);
List<Interval> intervals =
DruidDateTimeUtils.createInterval(e2, "UTC");