diff --git a/core/src/main/java/org/apache/calcite/rex/RexInterpreter.java b/core/src/main/java/org/apache/calcite/rex/RexInterpreter.java index 549efa5387f..4922c2ab73d 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexInterpreter.java +++ b/core/src/main/java/org/apache/calcite/rex/RexInterpreter.java @@ -379,6 +379,7 @@ private static Comparable ceil(RexCall call, List values) { switch (unit) { case YEAR: case MONTH: + case WEEK: switch (call.getKind()) { case FLOOR: return DateTimeUtils.unixTimestampFloor(unit, v); @@ -403,7 +404,7 @@ private static TimeUnitRange subUnit(TimeUnitRange unit) { case QUARTER: return TimeUnitRange.MONTH; default: - return TimeUnitRange.DAY; + return unit; } } diff --git a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java index 3b0b04043b5..1ecb15d62b0 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java +++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java @@ -2652,6 +2652,7 @@ private static boolean canRollUp(TimeUnit outer, TimeUnit inner) { switch (outer) { case YEAR: case MONTH: + case WEEK: case DAY: case HOUR: case MINUTE: @@ -2662,6 +2663,7 @@ private static boolean canRollUp(TimeUnit outer, TimeUnit inner) { case YEAR: case QUARTER: case MONTH: + case WEEK: case DAY: case HOUR: case MINUTE: @@ -2671,6 +2673,12 @@ private static boolean canRollUp(TimeUnit outer, TimeUnit inner) { if (inner == TimeUnit.QUARTER) { return outer == TimeUnit.YEAR; } + if (outer == TimeUnit.WEEK && inner != TimeUnit.YEAR && inner != TimeUnit.MONTH) { + return true; + } + if (inner == TimeUnit.WEEK && outer != TimeUnit.YEAR && outer != TimeUnit.MONTH) { + return false; + } return outer.ordinal() <= inner.ordinal(); default: break; 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 042dcae1f0a..0b550e5b958 100644 --- a/core/src/test/java/org/apache/calcite/test/RexImplicationCheckerTest.java +++ b/core/src/test/java/org/apache/calcite/test/RexImplicationCheckerTest.java @@ -483,13 +483,18 @@ public class RexImplicationCheckerTest { hasToString("TRIM('BOTH', 'a', '1111':VARCHAR)")); } - /** Test case for simplifier of ceil/floor. */ + /** Test case for + * [CALCITE-2178] + * Extend expression simplifier to work on datetime CEIL/FLOOR functions, + * [CALCITE-7304] + * Floor/Ceil can not simplify with WEEK TimeUnit. */ @Test void testSimplifyCeilFloor() { // We can add more time units here once they are supported in // RexInterpreter, e.g., TimeUnitRange.HOUR, TimeUnitRange.MINUTE, // TimeUnitRange.SECOND. final ImmutableList timeUnitRanges = - ImmutableList.of(TimeUnitRange.YEAR, TimeUnitRange.MONTH); + ImmutableList.of(TimeUnitRange.YEAR, TimeUnitRange.MONTH, TimeUnitRange.WEEK, + TimeUnitRange.HOUR, TimeUnitRange.MINUTE, TimeUnitRange.SECOND); final Fixture f = new Fixture(); final RexNode literalTs =