private void checkDateRange(Fixture f, RexNode e, Matcher<String> intervalMatcher) { e = DateRangeRules.replaceTimeUnits(f.rexBuilder, e, "UTC"); final RexNode e2 = f.simplify.simplify(e); List<Interval> intervals = DruidDateTimeUtils.createInterval(e2); if (intervals == null) { throw new AssertionError("null interval"); } assertThat(intervals.toString(), intervalMatcher); }
/** Replaces calls to EXTRACT, FLOOR and CEIL in an expression. */ @VisibleForTesting 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. // Add YEAR as TimeUnit so that FLOOR gets replaced in first iteration // with timeUnit YEAR. timeUnits = ImmutableSortedSet.<TimeUnitRange>naturalOrder() .addAll(timeUnits).add(TimeUnitRange.YEAR).build(); } final Map<String, RangeSet<Calendar>> operandRanges = new HashMap<>(); for (TimeUnitRange timeUnit : timeUnits) { e = e.accept( new ExtractShuttle(rexBuilder, timeUnit, operandRanges, timeUnits, timeZone)); } return e; }
private void checkDateRangeNoSimplify(Fixture f, RexNode e, Matcher<String> intervalMatcher) { e = DateRangeRules.replaceTimeUnits(f.rexBuilder, e, "UTC"); final List<Interval> intervals = DruidDateTimeUtils.createInterval(e); assertThat(intervals, notNullValue()); assertThat(intervals.toString(), intervalMatcher); }
/** Replaces calls to EXTRACT, FLOOR and CEIL in an expression. */ @VisibleForTesting 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. // Add YEAR as TimeUnit so that FLOOR gets replaced in first iteration // with timeUnit YEAR. timeUnits = ImmutableSortedSet.<TimeUnitRange>naturalOrder() .addAll(timeUnits).add(TimeUnitRange.YEAR).build(); } final Map<RexNode, RangeSet<Calendar>> operandRanges = new HashMap<>(); for (TimeUnitRange timeUnit : timeUnits) { e = e.accept( new ExtractShuttle(rexBuilder, timeUnit, operandRanges, timeUnits, timeZone)); } return 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); }
@Test public void testExtractYearFromDateColumn() { final Fixture2 f = new Fixture2(); final RexNode e = f.eq(f.literal(2014), f.exYearD); assertThat(DateRangeRules.extractTimeUnits(e), is(set(TimeUnitRange.YEAR))); assertThat(DateRangeRules.extractTimeUnits(f.dec), is(set())); 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, f.eq(f.exYearD, f.literal(2014)), is("AND(>=($8, 2014-01-01), <($8, 2015-01-01))")); checkDateRange(f, f.ge(f.exYearD, f.literal(2014)), is(">=($8, 2014-01-01)")); checkDateRange(f, f.gt(f.exYearD, f.literal(2014)), is(">=($8, 2015-01-01)")); checkDateRange(f, f.lt(f.exYearD, f.literal(2014)), is("<($8, 2014-01-01)")); checkDateRange(f, f.le(f.exYearD, f.literal(2014)), is("<($8, 2015-01-01)")); checkDateRange(f, f.ne(f.exYearD, f.literal(2014)), is("<>(EXTRACT(FLAG(YEAR), $8), 2014)")); }
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); }
@Test public void testExtractYearFromDateColumn() { final Fixture2 f = new Fixture2(); final RexNode e = f.eq(f.literal(2014), f.exYearD); assertThat(DateRangeRules.extractTimeUnits(e), is(set(TimeUnitRange.YEAR))); assertThat(DateRangeRules.extractTimeUnits(f.dec), is(set())); 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, f.eq(f.exYearD, f.literal(2014)), is("AND(>=($8, 2014-01-01), <($8, 2015-01-01))")); checkDateRange(f, f.ge(f.exYearD, f.literal(2014)), is(">=($8, 2014-01-01)")); checkDateRange(f, f.gt(f.exYearD, f.literal(2014)), is(">=($8, 2015-01-01)")); checkDateRange(f, f.lt(f.exYearD, f.literal(2014)), is("<($8, 2014-01-01)")); checkDateRange(f, f.le(f.exYearD, f.literal(2014)), is("<($8, 2015-01-01)")); checkDateRange(f, f.ne(f.exYearD, f.literal(2014)), is("<>(EXTRACT(FLAG(YEAR), $8), 2014)")); }
@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(), timeZone); if (condition.equals(filter.getCondition())) { return; } final RelBuilder relBuilder = relBuilderFactory.create(filter.getCluster(), null); relBuilder.push(filter.getInput()) .filter(condition); call.transformTo(relBuilder.build()); } }
@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(), timeZone); if (RexUtil.eq(condition, filter.getCondition())) { return; } final RelBuilder relBuilder = relBuilderFactory.create(filter.getCluster(), null); relBuilder.push(filter.getInput()) .filter(condition); call.transformTo(relBuilder.build()); } }