/** 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; }
/** 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; }
@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)")); }
@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)")); }