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 2015/01/22 22:23:52 UTC

incubator-calcite git commit: [CALCITE-458] ArrayIndexOutOfBoundsException when using just a single column in interpreter

Repository: incubator-calcite
Updated Branches:
  refs/heads/master 66cfb120f -> 7c3c711f0


[CALCITE-458] ArrayIndexOutOfBoundsException when using just a single column in interpreter


Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/7c3c711f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/7c3c711f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/7c3c711f

Branch: refs/heads/master
Commit: 7c3c711f0b3b63a5c9873692db95f095cfe830e5
Parents: 66cfb12
Author: Julian Hyde <jh...@apache.org>
Authored: Thu Jan 22 12:15:25 2015 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jan 22 12:15:25 2015 -0800

----------------------------------------------------------------------
 .../org/apache/calcite/interpreter/Nodes.java   | 15 +++++++---
 .../java/org/apache/calcite/rex/RexUtil.java    | 14 +++++++++
 .../apache/calcite/test/ScannableTableTest.java | 31 ++++++++++++++++++--
 3 files changed, 53 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7c3c711f/core/src/main/java/org/apache/calcite/interpreter/Nodes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/interpreter/Nodes.java b/core/src/main/java/org/apache/calcite/interpreter/Nodes.java
index 1e067bb..bcb5f6f 100644
--- a/core/src/main/java/org/apache/calcite/interpreter/Nodes.java
+++ b/core/src/main/java/org/apache/calcite/interpreter/Nodes.java
@@ -33,6 +33,7 @@ import org.apache.calcite.rel.core.Values;
 import org.apache.calcite.rel.core.Window;
 import org.apache.calcite.rel.rules.FilterTableRule;
 import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexUtil;
 import org.apache.calcite.schema.FilterableTable;
 import org.apache.calcite.schema.ProjectableFilterableTable;
 import org.apache.calcite.util.ImmutableIntList;
@@ -78,10 +79,16 @@ public class Nodes {
           final FilterTableRule.FilterSplit filterSplit =
               FilterTableRule.FilterSplit.of(projectableFilterableTable,
                   condition, interpreter.getDataContext());
-          rel = new FilterScan(project.getCluster(), project.getTraitSet(),
-              table, filterSplit.acceptedFilters,
-              ImmutableIntList.copyOf(Mappings.asList(mapping.inverse())));
-          rel = RelOptUtil.createFilter(rel, filterSplit.rejectedFilters);
+          if (filterSplit.rejectedFilters.isEmpty()) {
+            // Only push down projects & filters if there are no rejected
+            // filters. The rejected filter might need columns that are not
+            // projected. See CALCITE-445.
+            rel = new FilterScan(project.getCluster(), project.getTraitSet(),
+                table, filterSplit.acceptedFilters,
+                ImmutableIntList.copyOf(Mappings.asList(mapping.inverse())));
+            rel = RelOptUtil.createFilter(rel,
+                RexUtil.apply(mapping, filterSplit.rejectedFilters));
+          }
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7c3c711f/core/src/main/java/org/apache/calcite/rex/RexUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexUtil.java b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
index d88552a..e70205c 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexUtil.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
@@ -835,6 +835,20 @@ public class RexUtil {
   }
 
   /**
+   * Applies a mapping to an iterable over expressions.
+   */
+  public static Iterable<RexNode> apply(Mappings.TargetMapping mapping,
+      Iterable<? extends RexNode> nodes) {
+    final RexPermuteInputsShuttle shuttle = RexPermuteInputsShuttle.of(mapping);
+    return Iterables.transform(nodes,
+        new Function<RexNode, RexNode>() {
+          public RexNode apply(RexNode input) {
+            return input.accept(shuttle);
+          }
+        });
+  }
+
+  /**
    * Applies a shuttle to an array of expressions. Creates a copy first.
    *
    * @param shuttle Shuttle

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/7c3c711f/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java b/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
index d9ba8ac..8637dc0 100644
--- a/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
+++ b/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
@@ -218,13 +218,12 @@ public class ScannableTableTest {
     final Statement statement = connection.createStatement();
     ResultSet resultSet = statement.executeQuery(
         "select \"k\" from \"s\".\"beatles2\" where \"i\" = 4");
-    assertThat(CalciteAssert.toString(resultSet),
-        equalTo(Bug.CALCITE_445_FIXED ? "k=1940\nk=1942\n" : ""));
+    assertThat(CalciteAssert.toString(resultSet), equalTo("k=1940\nk=1942\n"));
     resultSet.close();
     assertThat(buf.toString(),
         equalTo(Bug.CALCITE_445_FIXED
                 ? "returnCount=4, projects=[0, 2]"
-                : "returnCount=4, projects=[2]"));
+                : "returnCount=4"));
     buf.setLength(0);
   }
 
@@ -247,6 +246,32 @@ public class ScannableTableTest {
     return null;
   }
 
+  /** Test case for
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-458">[CALCITE-458]
+   * ArrayIndexOutOfBoundsException when using just a single column in
+   * interpreter</a>. */
+  @Test public void testPFTableRefusesFilterSingleColumn() throws Exception {
+    Connection connection =
+        DriverManager.getConnection("jdbc:calcite:");
+    CalciteConnection calciteConnection =
+        connection.unwrap(CalciteConnection.class);
+    SchemaPlus rootSchema = calciteConnection.getRootSchema();
+    SchemaPlus schema = rootSchema.add("s", new AbstractSchema());
+    final StringBuilder buf = new StringBuilder();
+    schema.add("beatles2", new BeatlesProjectableFilterableTable(buf, false));
+
+    // Now with an "uncooperative" filterable table that refuses to accept
+    // filters.
+    final Statement statement = connection.createStatement();
+    ResultSet resultSet = statement.executeQuery(
+        "select \"k\" from \"s\".\"beatles2\" where \"k\" > 1941");
+    assertThat(buf.toString(),
+        equalTo(Bug.CALCITE_445_FIXED
+                ? "returnCount=4, projects=[2]"
+                : "returnCount=4"));
+    assertThat(CalciteAssert.toString(resultSet), equalTo("k=1942\nk=1943\n"));
+  }
+
   /** Table that returns one column via the {@link ScannableTable} interface. */
   public static class SimpleTable implements ScannableTable {
     public RelDataType getRowType(RelDataTypeFactory typeFactory) {