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/02/23 23:34:41 UTC

incubator-calcite git commit: Refactor TableScanNode.create method

Repository: incubator-calcite
Updated Branches:
  refs/heads/master bd0b60617 -> 96cac4796


Refactor TableScanNode.create method


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

Branch: refs/heads/master
Commit: 96cac479615421628dfca3461d2b36e461c2bb16
Parents: bd0b606
Author: Julian Hyde <jh...@apache.org>
Authored: Sun Feb 22 10:56:33 2015 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Feb 23 14:33:59 2015 -0800

----------------------------------------------------------------------
 .../calcite/interpreter/TableScanNode.java      | 240 +++++++++++--------
 1 file changed, 138 insertions(+), 102 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/96cac479/core/src/main/java/org/apache/calcite/interpreter/TableScanNode.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/interpreter/TableScanNode.java b/core/src/main/java/org/apache/calcite/interpreter/TableScanNode.java
index 8f86bec..2b1865f 100644
--- a/core/src/main/java/org/apache/calcite/interpreter/TableScanNode.java
+++ b/core/src/main/java/org/apache/calcite/interpreter/TableScanNode.java
@@ -86,136 +86,172 @@ public class TableScanNode implements Node {
    * any filters and projects that cannot be implemented by the table. */
   static TableScanNode create(Interpreter interpreter, TableScan rel,
       ImmutableList<RexNode> filters, ImmutableIntList projects) {
-    final DataContext root = interpreter.getDataContext();
     final RelOptTable relOptTable = rel.getTable();
     final ProjectableFilterableTable pfTable =
         relOptTable.unwrap(ProjectableFilterableTable.class);
     if (pfTable != null) {
-      final ImmutableIntList originalProjects = projects;
-      for (;;) {
-        final List<RexNode> mutableFilters = Lists.newArrayList(filters);
-        final int[] projectInts;
-        if (projects == null
-            || projects.equals(TableScan.identity(relOptTable))) {
-          projectInts = null;
-        } else {
-          projectInts = projects.toIntArray();
-        }
-        final Enumerable<Object[]> enumerable1 =
-            pfTable.scan(root, mutableFilters, projectInts);
-        for (RexNode filter : mutableFilters) {
-          if (!filters.contains(filter)) {
-            throw RESOURCE.filterableTableInventedFilter(filter.toString())
-                .ex();
-          }
-        }
-        final ImmutableBitSet usedFields =
-            RelOptUtil.InputFinder.bits(mutableFilters, null);
-        if (projects != null) {
-          int changeCount = 0;
-          for (int usedField : usedFields) {
-            if (!projects.contains(usedField)) {
-              // A field that is not projected is used in a filter that the
-              // table rejected. We won't be able to apply the filter later.
-              // Try again without any projects.
-              projects =
-                  ImmutableIntList.copyOf(
-                      Iterables.concat(projects, ImmutableList.of(usedField)));
-              ++changeCount;
-            }
-          }
-          if (changeCount > 0) {
-            continue;
-          }
-        }
-        final Enumerable<Row> rowEnumerable = Enumerables.toRow(enumerable1);
-        final ImmutableIntList rejectedProjects;
-        if (Objects.equal(projects, originalProjects)) {
-          rejectedProjects = null;
-        } else {
-          // We projected extra columns because they were needed in filters. Now
-          // project the leading columns.
-          rejectedProjects = ImmutableIntList.identity(originalProjects.size());
-        }
-        return create2(interpreter, rel, rowEnumerable,
-            projects, mutableFilters, rejectedProjects);
-      }
+      return createProjectableFilterable(interpreter, rel, filters, projects,
+          pfTable);
     }
     final FilterableTable filterableTable =
         relOptTable.unwrap(FilterableTable.class);
     if (filterableTable != null) {
-      final List<RexNode> mutableFilters = Lists.newArrayList(filters);
-      final Enumerable<Object[]> enumerable =
-          filterableTable.scan(root, mutableFilters);
-      for (RexNode filter : mutableFilters) {
-        if (!filters.contains(filter)) {
-          throw RESOURCE.filterableTableInventedFilter(filter.toString()).ex();
-        }
-      }
-      final Enumerable<Row> rowEnumerable = Enumerables.toRow(enumerable);
-      return create2(interpreter, rel, rowEnumerable, null, mutableFilters,
-          projects);
+      return createFilterable(interpreter, rel, filters, projects,
+          filterableTable);
     }
     final ScannableTable scannableTable =
         relOptTable.unwrap(ScannableTable.class);
     if (scannableTable != null) {
-      final Enumerable<Row> rowEnumerable =
-          Enumerables.toRow(scannableTable.scan(root));
-      return create2(interpreter, rel, rowEnumerable, null, filters, projects);
+      return createScannable(interpreter, rel, filters, projects,
+          scannableTable);
     }
     //noinspection unchecked
     final Enumerable<Row> enumerable = relOptTable.unwrap(Enumerable.class);
     if (enumerable != null) {
-      return create2(interpreter, rel, enumerable, null, filters, projects);
+      return createEnumerable(interpreter, rel, enumerable, null, filters,
+          projects);
     }
     final QueryableTable queryableTable =
         relOptTable.unwrap(QueryableTable.class);
     if (queryableTable != null) {
-      final Type elementType = queryableTable.getElementType();
-      SchemaPlus schema = root.getRootSchema();
-      for (String name : Util.skipLast(relOptTable.getQualifiedName())) {
-        schema = schema.getSubSchema(name);
-      }
-      final Enumerable<Row> rowEnumerable;
-      if (elementType instanceof Class) {
-        //noinspection unchecked
-        final Queryable<Object> queryable = Schemas.queryable(root,
-            (Class) elementType, relOptTable.getQualifiedName());
-        ImmutableList.Builder<Field> fieldBuilder = ImmutableList.builder();
-        Class type = (Class) elementType;
-        for (Field field : type.getFields()) {
-          if (Modifier.isPublic(field.getModifiers())
-              && !Modifier.isStatic(field.getModifiers())) {
-            fieldBuilder.add(field);
-          }
+      return createQueryable(interpreter, rel, filters, projects,
+          queryableTable);
+    }
+    throw new AssertionError("cannot convert table " + relOptTable
+        + " to enumerable");
+  }
+
+  private static TableScanNode createScannable(Interpreter interpreter,
+      TableScan rel, ImmutableList<RexNode> filters, ImmutableIntList projects,
+      ScannableTable scannableTable) {
+    final Enumerable<Row> rowEnumerable =
+        Enumerables.toRow(scannableTable.scan(interpreter.getDataContext()));
+    return createEnumerable(interpreter, rel, rowEnumerable, null, filters,
+        projects);
+  }
+
+  private static TableScanNode createQueryable(Interpreter interpreter,
+      TableScan rel, ImmutableList<RexNode> filters, ImmutableIntList projects,
+      QueryableTable queryableTable) {
+    final DataContext root = interpreter.getDataContext();
+    final RelOptTable relOptTable = rel.getTable();
+    final Type elementType = queryableTable.getElementType();
+    SchemaPlus schema = root.getRootSchema();
+    for (String name : Util.skipLast(relOptTable.getQualifiedName())) {
+      schema = schema.getSubSchema(name);
+    }
+    final Enumerable<Row> rowEnumerable;
+    if (elementType instanceof Class) {
+      //noinspection unchecked
+      final Queryable<Object> queryable = Schemas.queryable(root,
+          (Class) elementType,
+          relOptTable.getQualifiedName());
+      ImmutableList.Builder<Field> fieldBuilder = ImmutableList.builder();
+      Class type = (Class) elementType;
+      for (Field field : type.getFields()) {
+        if (Modifier.isPublic(field.getModifiers())
+            && !Modifier.isStatic(field.getModifiers())) {
+          fieldBuilder.add(field);
         }
-        final List<Field> fields = fieldBuilder.build();
-        rowEnumerable = queryable.select(
-            new Function1<Object, Row>() {
-              public Row apply(Object o) {
-                final Object[] values = new Object[fields.size()];
-                for (int i = 0; i < fields.size(); i++) {
-                  Field field = fields.get(i);
-                  try {
-                    values[i] = field.get(o);
-                  } catch (IllegalAccessException e) {
-                    throw new RuntimeException(e);
-                  }
+      }
+      final List<Field> fields = fieldBuilder.build();
+      rowEnumerable = queryable.select(
+          new Function1<Object, Row>() {
+            public Row apply(Object o) {
+              final Object[] values = new Object[fields.size()];
+              for (int i = 0; i < fields.size(); i++) {
+                Field field = fields.get(i);
+                try {
+                  values[i] = field.get(o);
+                } catch (IllegalAccessException e) {
+                  throw new RuntimeException(e);
                 }
-                return new Row(values);
               }
-            });
+              return new Row(values);
+            }
+          });
+    } else {
+      rowEnumerable =
+          Schemas.queryable(root, Row.class, relOptTable.getQualifiedName());
+    }
+    return createEnumerable(interpreter, rel, rowEnumerable, null, filters,
+        projects);
+  }
+
+  private static TableScanNode createFilterable(Interpreter interpreter,
+      TableScan rel, ImmutableList<RexNode> filters, ImmutableIntList projects,
+      FilterableTable filterableTable) {
+    final DataContext root = interpreter.getDataContext();
+    final List<RexNode> mutableFilters = Lists.newArrayList(filters);
+    final Enumerable<Object[]> enumerable =
+        filterableTable.scan(root, mutableFilters);
+    for (RexNode filter : mutableFilters) {
+      if (!filters.contains(filter)) {
+        throw RESOURCE.filterableTableInventedFilter(filter.toString()).ex();
+      }
+    }
+    final Enumerable<Row> rowEnumerable = Enumerables.toRow(enumerable);
+    return createEnumerable(interpreter, rel, rowEnumerable, null,
+        mutableFilters, projects);
+  }
+
+  private static TableScanNode createProjectableFilterable(
+      Interpreter interpreter, TableScan rel, ImmutableList<RexNode> filters,
+      ImmutableIntList projects, ProjectableFilterableTable pfTable) {
+    final DataContext root = interpreter.getDataContext();
+    final ImmutableIntList originalProjects = projects;
+    for (;;) {
+      final List<RexNode> mutableFilters = Lists.newArrayList(filters);
+      final int[] projectInts;
+      if (projects == null
+          || projects.equals(TableScan.identity(rel.getTable()))) {
+        projectInts = null;
       } else {
-        rowEnumerable =
-            Schemas.queryable(root, Row.class, relOptTable.getQualifiedName());
+        projectInts = projects.toIntArray();
       }
-      return create2(interpreter, rel, rowEnumerable, null, filters, projects);
+      final Enumerable<Object[]> enumerable1 =
+          pfTable.scan(root, mutableFilters, projectInts);
+      for (RexNode filter : mutableFilters) {
+        if (!filters.contains(filter)) {
+          throw RESOURCE.filterableTableInventedFilter(filter.toString())
+              .ex();
+        }
+      }
+      final ImmutableBitSet usedFields =
+          RelOptUtil.InputFinder.bits(mutableFilters, null);
+      if (projects != null) {
+        int changeCount = 0;
+        for (int usedField : usedFields) {
+          if (!projects.contains(usedField)) {
+            // A field that is not projected is used in a filter that the
+            // table rejected. We won't be able to apply the filter later.
+            // Try again without any projects.
+            projects =
+                ImmutableIntList.copyOf(
+                    Iterables.concat(projects, ImmutableList.of(usedField)));
+            ++changeCount;
+          }
+        }
+        if (changeCount > 0) {
+          continue;
+        }
+      }
+      final Enumerable<Row> rowEnumerable = Enumerables.toRow(enumerable1);
+      final ImmutableIntList rejectedProjects;
+      if (Objects.equal(projects, originalProjects)) {
+        rejectedProjects = null;
+      } else {
+        // We projected extra columns because they were needed in filters. Now
+        // project the leading columns.
+        rejectedProjects = ImmutableIntList.identity(originalProjects.size());
+      }
+      return createEnumerable(interpreter, rel, rowEnumerable, projects,
+          mutableFilters, rejectedProjects);
     }
-    throw new AssertionError("cannot convert table " + relOptTable
-        + " to enumerable");
   }
 
-  private static TableScanNode create2(Interpreter interpreter, TableScan rel,
+  private static TableScanNode createEnumerable(
+      Interpreter interpreter, TableScan rel,
       Enumerable<Row> enumerable, final ImmutableIntList acceptedProjects,
       List<RexNode> rejectedFilters, final ImmutableIntList rejectedProjects) {
     if (!rejectedFilters.isEmpty()) {