This is an automated email from the ASF dual-hosted git repository.
zabetak pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new 4f79aa875c [CALCITE-7240] Handle SEARCH in DateRangeRules
4f79aa875c is described below
commit 4f79aa875c4ccf6e50bbd6475b716ce9cd529251
Author: Stamatis Zampetakis <[email protected]>
AuthorDate: Wed Oct 22 16:53:05 2025 +0200
[CALCITE-7240] Handle SEARCH in DateRangeRules
1. Expand SEARCH in replaceTimeUnits since ExtractShuttle is made to work
only with simple operators
2. Correct invalid return datatype in DateRangeRulesTest.Fixture2 function
calls by relying on the operator type derivation logic.
---
.../apache/calcite/rel/rules/DateRangeRules.java | 1 +
.../calcite/rel/rules/DateRangeRulesTest.java | 60 +++++++++++++++++-----
.../test/RexImplicationCheckerFixtures.java | 4 ++
3 files changed, 51 insertions(+), 14 deletions(-)
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 4af20b0053..ae0d62e0fc 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
@@ -149,6 +149,7 @@ static ImmutableSortedSet<TimeUnitRange>
extractTimeUnits(RexNode e) {
@VisibleForTesting
public static RexNode replaceTimeUnits(RexBuilder rexBuilder, RexNode e,
String timeZone) {
+ e = RexUtil.expandSearch(rexBuilder, null, e);
ImmutableSortedSet<TimeUnitRange> timeUnits = extractTimeUnits(e);
if (!timeUnits.contains(TimeUnitRange.YEAR)) {
// Case when we have FLOOR or CEIL but no extract on YEAR.
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 de95a70c19..159d7643c9 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
@@ -406,6 +406,12 @@ class DateRangeRulesTest {
+ " <($8, 2011-06-01)))"));
}
+ @Test void testExtractBetweenRewrite() {
+ final Fixture2 f = new Fixture2();
+ checkDateRange(f, f.between(f.exYearD, f.literal(2010), f.literal(2015)),
+ is("AND(>=($8, 2010-01-01), AND(>=($8, 2010-01-01), <($8,
2016-01-01)))"));
+ }
+
@Test void testFloorEqRewrite() {
final Calendar c = Util.calendar();
c.clear();
@@ -514,6 +520,19 @@ class DateRangeRulesTest {
is(">=($9, 2010-01-01 00:00:00)"));
}
+ @Test void testFloorBetweenRewrite() {
+ final Calendar c = Util.calendar();
+ final Fixture2 f = new Fixture2();
+ c.clear();
+ c.set(2010, Calendar.FEBRUARY, 10, 11, 12, 05);
+ RexNode ts2010_02_10 =
f.timestampLiteral(TimestampString.fromCalendarFields(c));
+ c.clear();
+ c.set(2015, Calendar.OCTOBER, 12, 10, 12, 05);
+ RexNode ts2015_10_12 =
f.timestampLiteral(TimestampString.fromCalendarFields(c));
+ checkDateRange(f, f.between(f.floorYear, ts2010_02_10, ts2015_10_12),
+ is("AND(>=($9, 2011-01-01 00:00:00), <($9, 2016-01-01 00:00:00))"));
+ }
+
@Test void testFloorExtractBothRewrite() {
final Calendar c = Util.calendar();
c.clear();
@@ -656,6 +675,19 @@ class DateRangeRulesTest {
is(">($9, 2009-01-01 00:00:00)"));
}
+ @Test void testCeilBetweenRewrite() {
+ final Calendar c = Util.calendar();
+ final Fixture2 f = new Fixture2();
+ c.clear();
+ c.set(2010, Calendar.FEBRUARY, 10, 11, 12, 05);
+ RexNode ts2010_02_10 =
f.timestampLiteral(TimestampString.fromCalendarFields(c));
+ c.clear();
+ c.set(2015, Calendar.OCTOBER, 12, 10, 12, 05);
+ RexNode ts2015_10_12 =
f.timestampLiteral(TimestampString.fromCalendarFields(c));
+ checkDateRange(f, f.between(f.ceilYear, ts2010_02_10, ts2015_10_12),
+ is("AND(>($9, 2010-01-01 00:00:00), <=($9, 2015-01-01 00:00:00))"));
+ }
+
@Test void testFloorRewriteWithTimezone() {
final Calendar c = Util.calendar();
c.clear();
@@ -728,51 +760,51 @@ private static class Fixture2 extends Fixture {
rexBuilder.makeCall(SqlStdOperatorTable.EXTRACT,
ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.YEAR), ts));
exMonthTs =
- rexBuilder.makeCall(intRelDataType, SqlStdOperatorTable.EXTRACT,
+ rexBuilder.makeCall(SqlStdOperatorTable.EXTRACT,
ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.MONTH), ts));
exDayTs =
- rexBuilder.makeCall(intRelDataType, SqlStdOperatorTable.EXTRACT,
+ rexBuilder.makeCall(SqlStdOperatorTable.EXTRACT,
ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.DAY), ts));
exYearD =
rexBuilder.makeCall(SqlStdOperatorTable.EXTRACT,
ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.YEAR), d));
exMonthD =
- rexBuilder.makeCall(intRelDataType, SqlStdOperatorTable.EXTRACT,
+ rexBuilder.makeCall(SqlStdOperatorTable.EXTRACT,
ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.MONTH), d));
exDayD =
- rexBuilder.makeCall(intRelDataType, SqlStdOperatorTable.EXTRACT,
+ rexBuilder.makeCall(SqlStdOperatorTable.EXTRACT,
ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.DAY), d));
floorYear =
- rexBuilder.makeCall(intRelDataType, SqlStdOperatorTable.FLOOR,
+ rexBuilder.makeCall(SqlStdOperatorTable.FLOOR,
ImmutableList.of(ts, rexBuilder.makeFlag(TimeUnitRange.YEAR)));
floorMonth =
- rexBuilder.makeCall(intRelDataType, SqlStdOperatorTable.FLOOR,
+ rexBuilder.makeCall(SqlStdOperatorTable.FLOOR,
ImmutableList.of(ts, rexBuilder.makeFlag(TimeUnitRange.MONTH)));
floorDay =
- rexBuilder.makeCall(intRelDataType, SqlStdOperatorTable.FLOOR,
+ rexBuilder.makeCall(SqlStdOperatorTable.FLOOR,
ImmutableList.of(ts, rexBuilder.makeFlag(TimeUnitRange.DAY)));
floorHour =
- rexBuilder.makeCall(intRelDataType, SqlStdOperatorTable.FLOOR,
+ rexBuilder.makeCall(SqlStdOperatorTable.FLOOR,
ImmutableList.of(ts, rexBuilder.makeFlag(TimeUnitRange.HOUR)));
floorMinute =
- rexBuilder.makeCall(intRelDataType, SqlStdOperatorTable.FLOOR,
+ rexBuilder.makeCall(SqlStdOperatorTable.FLOOR,
ImmutableList.of(ts, rexBuilder.makeFlag(TimeUnitRange.MINUTE)));
ceilYear =
- rexBuilder.makeCall(intRelDataType, SqlStdOperatorTable.CEIL,
+ rexBuilder.makeCall(SqlStdOperatorTable.CEIL,
ImmutableList.of(ts, rexBuilder.makeFlag(TimeUnitRange.YEAR)));
ceilMonth =
- rexBuilder.makeCall(intRelDataType, SqlStdOperatorTable.CEIL,
+ rexBuilder.makeCall(SqlStdOperatorTable.CEIL,
ImmutableList.of(ts, rexBuilder.makeFlag(TimeUnitRange.MONTH)));
ceilDay =
- rexBuilder.makeCall(intRelDataType, SqlStdOperatorTable.CEIL,
+ rexBuilder.makeCall(SqlStdOperatorTable.CEIL,
ImmutableList.of(ts, rexBuilder.makeFlag(TimeUnitRange.DAY)));
ceilHour =
- rexBuilder.makeCall(intRelDataType, SqlStdOperatorTable.CEIL,
+ rexBuilder.makeCall(SqlStdOperatorTable.CEIL,
ImmutableList.of(ts, rexBuilder.makeFlag(TimeUnitRange.HOUR)));
ceilMinute =
- rexBuilder.makeCall(intRelDataType, SqlStdOperatorTable.CEIL,
+ rexBuilder.makeCall(SqlStdOperatorTable.CEIL,
ImmutableList.of(ts, rexBuilder.makeFlag(TimeUnitRange.MINUTE)));
}
}
diff --git
a/testkit/src/main/java/org/apache/calcite/test/RexImplicationCheckerFixtures.java
b/testkit/src/main/java/org/apache/calcite/test/RexImplicationCheckerFixtures.java
index ed6d468a39..8770ed2240 100644
---
a/testkit/src/main/java/org/apache/calcite/test/RexImplicationCheckerFixtures.java
+++
b/testkit/src/main/java/org/apache/calcite/test/RexImplicationCheckerFixtures.java
@@ -178,6 +178,10 @@ public RexNode le(RexNode node1, RexNode node2) {
node2);
}
+ public RexNode between(RexNode node, RexNode lower, RexNode upper) {
+ return rexBuilder.makeBetween(node, lower, upper);
+ }
+
public RexNode notNull(RexNode node1) {
return rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, node1);
}