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 2017/02/23 16:50:55 UTC
[6/6] calcite git commit: [CALCITE-1601] DateRangeRules loses OR
filters
[CALCITE-1601] DateRangeRules loses OR filters
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/095acb10
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/095acb10
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/095acb10
Branch: refs/heads/master
Commit: 095acb1004c4432b6eb11390f61227ee58dd78db
Parents: ee289e4
Author: Julian Hyde <jh...@apache.org>
Authored: Tue Feb 21 14:13:19 2017 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Wed Feb 22 22:17:37 2017 -0800
----------------------------------------------------------------------
.../calcite/rel/rules/DateRangeRules.java | 41 +++++++++++++++++++-
.../calcite/rel/rules/DateRangeRulesTest.java | 24 ++++++++++++
2 files changed, 64 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/095acb10/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 9fc71b8..a052140 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
@@ -39,6 +39,7 @@ import org.apache.calcite.util.Bug;
import com.google.common.base.Predicate;
import com.google.common.collect.BoundType;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableRangeSet;
import com.google.common.collect.ImmutableSet;
@@ -47,8 +48,10 @@ import com.google.common.collect.RangeSet;
import com.google.common.collect.TreeRangeSet;
import java.math.BigDecimal;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.Deque;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
@@ -189,6 +192,7 @@ public abstract class DateRangeRules {
private final RexBuilder rexBuilder;
private final TimeUnitRange timeUnit;
private final Map<String, RangeSet<Calendar>> operandRanges;
+ private final Deque<RexCall> calls = new ArrayDeque<>();
public ExtractShuttle(RexBuilder rexBuilder, TimeUnitRange timeUnit,
Map<String, RangeSet<Calendar>> operandRanges) {
@@ -222,8 +226,43 @@ public abstract class DateRangeRules {
(RexLiteral) op1);
}
}
+ default:
+ calls.push(call);
+ try {
+ return super.visitCall(call);
+ } finally {
+ calls.pop();
+ }
+ }
+ }
+
+ @Override protected List<RexNode> visitList(List<? extends RexNode> exprs,
+ boolean[] update) {
+ if (exprs.isEmpty()) {
+ return ImmutableList.of(); // a bit more efficient
+ }
+ switch (calls.peek().getKind()) {
+ case AND:
+ return super.visitList(exprs, update);
+ default:
+ final Map<String, RangeSet<Calendar>> save =
+ ImmutableMap.copyOf(operandRanges);
+ final ImmutableList.Builder<RexNode> clonedOperands =
+ ImmutableList.builder();
+ for (RexNode operand : exprs) {
+ RexNode clonedOperand = operand.accept(this);
+ if ((clonedOperand != operand) && (update != null)) {
+ update[0] = true;
+ }
+ clonedOperands.add(clonedOperand);
+
+ // Restore the state. For an operator such as "OR", an argument
+ // cannot inherit the previous argument's state.
+ operandRanges.clear();
+ operandRanges.putAll(save);
+ }
+ return clonedOperands.build();
}
- return super.visitCall(call);
}
boolean isExtractCall(RexNode e) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/095acb10/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 6ef898e..63a84f1 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
@@ -95,6 +95,30 @@ public class DateRangeRulesTest {
+ " >=($8, 2014-06-01), <($8, 2014-07-01))"));
}
+ /** Test case for
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-1601">[CALCITE-1601]
+ * DateRangeRules loses OR filters</a>. */
+ @Test public void testExtractYearAndMonthFromDateColumn2() {
+ final Fixture2 f = new Fixture2();
+ final String s1 = "AND("
+ + "AND(>=($8, 2000-01-01), <($8, 2001-01-01)),"
+ + " OR("
+ + "AND(>=($8, 2000-02-01), <($8, 2000-03-01)), "
+ + "AND(>=($8, 2000-03-01), <($8, 2000-04-01)), "
+ + "AND(>=($8, 2000-05-01), <($8, 2000-06-01))))";
+ final String s2 = "AND(>=($8, 2000-01-01), <($8, 2001-01-01),"
+ + " OR("
+ + "AND(>=($8, 2000-02-01), <($8, 2000-03-01)), "
+ + "AND(>=($8, 2000-03-01), <($8, 2000-04-01)), "
+ + "AND(>=($8, 2000-05-01), <($8, 2000-06-01))))";
+ final RexNode e =
+ f.and(f.eq(f.exYear, f.literal(2000)),
+ f.or(f.eq(f.exMonth, f.literal(2)),
+ f.eq(f.exMonth, f.literal(3)),
+ f.eq(f.exMonth, f.literal(5))));
+ checkDateRange(f, e, is(s1), is(s2));
+ }
+
@Test public void testExtractYearAndDayFromDateColumn() {
final Fixture2 f = new Fixture2();
checkDateRange(f,