You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by mm...@apache.org on 2017/09/05 14:36:49 UTC

[06/16] calcite git commit: [CALCITE-1966] Allow normal views to act as materialization table (Christian Beikov)

[CALCITE-1966] Allow normal views to act as materialization table (Christian Beikov)

Close apache/calcite#527


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

Branch: refs/heads/branch-1.14
Commit: 6d2fc4ecf1f2640b6ccfc0dc890737503dbc0734
Parents: e152592
Author: Christian Beikov <ch...@gmail.com>
Authored: Thu Aug 24 16:21:40 2017 +0200
Committer: Julian Hyde <jh...@apache.org>
Committed: Tue Aug 29 10:14:31 2017 -0700

----------------------------------------------------------------------
 .../materialize/MaterializationService.java     |  6 ++++
 .../calcite/plan/RelOptMaterialization.java     |  6 ++--
 .../calcite/plan/RelOptMaterializations.java    | 13 ++++---
 .../calcite/prepare/CalcitePrepareImpl.java     |  3 +-
 .../org/apache/calcite/prepare/Prepare.java     |  4 ++-
 .../org/apache/calcite/test/CalciteAssert.java  | 25 +++++++++-----
 .../calcite/test/MaterializationTest.java       | 36 +++++++++++++++++---
 .../java/org/apache/calcite/util/Smalls.java    | 11 ++++++
 8 files changed, 80 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/6d2fc4ec/core/src/main/java/org/apache/calcite/materialize/MaterializationService.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/materialize/MaterializationService.java b/core/src/main/java/org/apache/calcite/materialize/MaterializationService.java
index 1b9fd88..3625a02 100644
--- a/core/src/main/java/org/apache/calcite/materialize/MaterializationService.java
+++ b/core/src/main/java/org/apache/calcite/materialize/MaterializationService.java
@@ -118,14 +118,20 @@ public class MaterializationService {
     final CalciteConnection connection =
         CalciteMetaImpl.connect(schema.root(), null);
     CalciteSchema.TableEntry tableEntry;
+    // If the user says the materialization exists, first try to find a table
+    // with the name and if none can be found, lookup a view in the schema
     if (existing) {
       tableEntry = schema.getTable(suggestedTableName, true);
+      if (tableEntry == null) {
+        tableEntry = schema.getTableBasedOnNullaryFunction(suggestedTableName, true);
+      }
     } else {
       tableEntry = null;
     }
     if (tableEntry == null) {
       tableEntry = schema.getTableBySql(viewSql);
     }
+
     RelDataType rowType = null;
     if (tableEntry == null) {
       Table table = tableFactory.createTable(schema, viewSql, viewSchemaPath);

http://git-wip-us.apache.org/repos/asf/calcite/blob/6d2fc4ec/core/src/main/java/org/apache/calcite/plan/RelOptMaterialization.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptMaterialization.java b/core/src/main/java/org/apache/calcite/plan/RelOptMaterialization.java
index b65af48..6e1af24 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptMaterialization.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptMaterialization.java
@@ -56,14 +56,14 @@ public class RelOptMaterialization {
   public final RelNode tableRel;
   public final RelOptTable starRelOptTable;
   public final StarTable starTable;
-  public final RelOptTable table;
+  public final List<String> qualifiedTableName;
   public final RelNode queryRel;
 
   /**
    * Creates a RelOptMaterialization.
    */
   public RelOptMaterialization(RelNode tableRel, RelNode queryRel,
-      RelOptTable starRelOptTable) {
+      RelOptTable starRelOptTable, List<String> qualifiedTableName) {
     this.tableRel =
         RelOptUtil.createCastRel(tableRel, queryRel.getRowType(), false);
     this.starRelOptTable = starRelOptTable;
@@ -73,7 +73,7 @@ public class RelOptMaterialization {
       this.starTable = starRelOptTable.unwrap(StarTable.class);
       assert starTable != null;
     }
-    this.table = tableRel.getTable();
+    this.qualifiedTableName = qualifiedTableName;
     this.queryRel = queryRel;
   }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/6d2fc4ec/core/src/main/java/org/apache/calcite/plan/RelOptMaterializations.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptMaterializations.java b/core/src/main/java/org/apache/calcite/plan/RelOptMaterializations.java
index 1e3a9e9..ce0c033 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptMaterializations.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptMaterializations.java
@@ -138,9 +138,9 @@ public abstract class RelOptMaterializations {
     final Map<List<String>, RelOptMaterialization> qnameMap = new HashMap<>();
     for (RelOptMaterialization materialization : materializations) {
       // If materialization is a tile in a lattice, we will deal with it shortly.
-      if (materialization.table != null
+      if (materialization.qualifiedTableName != null
           && materialization.starTable == null) {
-        final List<String> qname = materialization.table.getQualifiedName();
+        final List<String> qname = materialization.qualifiedTableName;
         qnameMap.put(qname, materialization);
         for (RelOptTable usedTable
             : RelOptUtil.findTables(materialization.queryRel)) {
@@ -167,7 +167,7 @@ public abstract class RelOptMaterializations {
     for (List<String> qname : TopologicalOrderIterator.of(usesGraph)) {
       RelOptMaterialization materialization = qnameMap.get(qname);
       if (materialization != null
-          && usesTable(materialization.table, queryTablesUsed, frozenGraph)) {
+          && usesTable(materialization.qualifiedTableName, queryTablesUsed, frozenGraph)) {
         applicableMaterializations.add(materialization);
       }
     }
@@ -218,13 +218,12 @@ public abstract class RelOptMaterializations {
    * {@code usedTables}.
    */
   private static boolean usesTable(
-      RelOptTable table,
+      List<String> qualifiedName,
       Set<RelOptTable> usedTables,
       Graphs.FrozenGraph<List<String>, DefaultEdge> usesGraph) {
     for (RelOptTable queryTable : usedTables) {
-      if (usesGraph.getShortestPath(
-          queryTable.getQualifiedName(),
-          table.getQualifiedName()) != null) {
+      if (usesGraph.getShortestPath(queryTable.getQualifiedName(), qualifiedName)
+          != null) {
         return true;
       }
     }

http://git-wip-us.apache.org/repos/asf/calcite/blob/6d2fc4ec/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java b/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
index 72fa04b..17b6e3a 100644
--- a/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
+++ b/core/src/main/java/org/apache/calcite/prepare/CalcitePrepareImpl.java
@@ -742,7 +742,8 @@ public class CalcitePrepareImpl implements CalcitePrepare {
           .setQuotedCasing(config.quotedCasing())
           .setUnquotedCasing(config.unquotedCasing())
           .setQuoting(config.quoting())
-          .setConformance(config.conformance());
+          .setConformance(config.conformance())
+          .setCaseSensitive(config.caseSensitive());
       final SqlParserImplFactory parserFactory =
           config.parserFactory(SqlParserImplFactory.class, null);
       if (parserFactory != null) {

http://git-wip-us.apache.org/repos/asf/calcite/blob/6d2fc4ec/core/src/main/java/org/apache/calcite/prepare/Prepare.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/prepare/Prepare.java b/core/src/main/java/org/apache/calcite/prepare/Prepare.java
index 29af1ef..8cb09c3 100644
--- a/core/src/main/java/org/apache/calcite/prepare/Prepare.java
+++ b/core/src/main/java/org/apache/calcite/prepare/Prepare.java
@@ -143,10 +143,12 @@ public abstract class Prepare {
 
     final List<RelOptMaterialization> materializationList = new ArrayList<>();
     for (Materialization materialization : materializations) {
+      List<String> qualifiedTableName = materialization.materializedTable.path();
       materializationList.add(
           new RelOptMaterialization(materialization.tableRel,
               materialization.queryRel,
-              materialization.starRelOptTable));
+              materialization.starRelOptTable,
+              qualifiedTableName));
     }
 
     final List<RelOptLattice> latticeList = new ArrayList<>();

http://git-wip-us.apache.org/repos/asf/calcite/blob/6d2fc4ec/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
index 76a464a..490c7e5 100644
--- a/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
+++ b/core/src/test/java/org/apache/calcite/test/CalciteAssert.java
@@ -925,8 +925,13 @@ public class CalciteAssert {
       return with("model", "inline:" + model);
     }
 
-    /** Adds materializations to the schema. */
     public final AssertThat withMaterializations(String model,
+         final String... materializations) {
+      return withMaterializations(model, false, materializations);
+    }
+
+    /** Adds materializations to the schema. */
+    public final AssertThat withMaterializations(String model, final boolean existing,
         final String... materializations) {
       return withMaterializations(model,
           new Function<JsonBuilder, List<Object>>() {
@@ -937,7 +942,9 @@ public class CalciteAssert {
                 String table = materializations[i++];
                 final Map<String, Object> map = builder.map();
                 map.put("table", table);
-                map.put("view", table + "v");
+                if (!existing) {
+                  map.put("view", table + "v");
+                }
                 String sql = materializations[i];
                 final String sql2 = sql.replaceAll("`", "\"");
                 map.put("sql", sql2);
@@ -957,15 +964,17 @@ public class CalciteAssert {
           "materializations: " + builder.toJsonString(list);
       final String model2;
       if (model.contains("defaultSchema: 'foodmart'")) {
-        model2 = model.replace("]",
-            ", { name: 'mat', "
+        int endIndex = model.lastIndexOf(']');
+        model2 = model.substring(0, endIndex)
+            + ", \n{ name: 'mat', "
             + buf
             + "}\n"
-            + "]");
+            + "]"
+            + model.substring(endIndex + 1);
       } else if (model.contains("type: ")) {
-        model2 = model.replace("type: ",
-            buf + ",\n"
-            + "type: ");
+        model2 = model.replaceFirst("type: ",
+            java.util.regex.Matcher.quoteReplacement(buf + ",\n"
+            + "type: "));
       } else {
         throw new AssertionError("do not know where to splice");
       }

http://git-wip-us.apache.org/repos/asf/calcite/blob/6d2fc4ec/core/src/test/java/org/apache/calcite/test/MaterializationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/MaterializationTest.java b/core/src/test/java/org/apache/calcite/test/MaterializationTest.java
index fb96721..6a3bcc9 100644
--- a/core/src/test/java/org/apache/calcite/test/MaterializationTest.java
+++ b/core/src/test/java/org/apache/calcite/test/MaterializationTest.java
@@ -197,14 +197,22 @@ public class MaterializationTest {
         RuleSets.ofList(ImmutableList.<RelOptRule>of()));
   }
 
+
+  private void checkMaterialize(String materialize, String query, String model,
+      Function<ResultSet, Void> explainChecker, final RuleSet rules) {
+    checkThatMaterialize(materialize, query, "m0", false, model, explainChecker,
+        rules).sameResultWithMaterializationsDisabled();
+  }
+
   /** Checks that a given query can use a materialized view with a given
    * definition. */
-  private void checkMaterialize(String materialize, String query, String model,
+  private CalciteAssert.AssertQuery checkThatMaterialize(String materialize,
+      String query, String name, boolean existing, String model,
       Function<ResultSet, Void> explainChecker, final RuleSet rules) {
     try (final TryThreadLocal.Memo ignored = Prepare.THREAD_TRIM.push(true)) {
       MaterializationService.setThreadLocal();
       CalciteAssert.AssertQuery that = CalciteAssert.that()
-          .withMaterializations(model, "m0", materialize)
+          .withMaterializations(model, existing, name, materialize)
           .query(query)
           .enableMaterializations(true);
 
@@ -220,8 +228,7 @@ public class MaterializationTest {
         });
       }
 
-      that.explainMatches("", explainChecker)
-          .sameResultWithMaterializationsDisabled();
+      return that.explainMatches("", explainChecker);
     }
   }
 
@@ -1797,6 +1804,23 @@ public class MaterializationTest {
         HR_FKUK_MODEL);
   }
 
+  @Test public void testViewMaterialization() {
+    checkThatMaterialize(
+        "select \"depts\".\"name\"\n"
+            + "from \"emps\"\n"
+            + "join \"depts\" on (\"emps\".\"deptno\" = \"depts\".\"deptno\")",
+        "select \"depts\".\"name\"\n"
+            + "from \"depts\"\n"
+            + "join \"emps\" on (\"emps\".\"deptno\" = \"depts\".\"deptno\")",
+        "matview",
+        true,
+        HR_FKUK_MODEL,
+        CalciteAssert.checkResultContains(
+            "EnumerableValues(tuples=[[{ 'noname' }]])"),
+        RuleSets.ofList(ImmutableList.<RelOptRule>of()))
+        .returnsValue("noname");
+  }
+
   @Test public void testSubQuery() {
     String q = "select \"empid\", \"deptno\", \"salary\" from \"emps\" e1\n"
         + "where \"empid\" = (\n"
@@ -2131,6 +2155,10 @@ public class MaterializationTest {
     public TranslatableTable view(String s) {
       return Smalls.view(s);
     }
+
+    public TranslatableTable matview() {
+      return Smalls.strView("noname");
+    }
   }
 }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/6d2fc4ec/core/src/test/java/org/apache/calcite/util/Smalls.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/util/Smalls.java b/core/src/test/java/org/apache/calcite/util/Smalls.java
index b3e64ca..39f0263 100644
--- a/core/src/test/java/org/apache/calcite/util/Smalls.java
+++ b/core/src/test/java/org/apache/calcite/util/Smalls.java
@@ -349,6 +349,17 @@ public class Smalls {
         }, "values (1), (3), " + s, ImmutableList.<String>of(), Arrays.asList("view"));
   }
 
+  public static TranslatableTable strView(String s) {
+    return new ViewTable(Object.class,
+        new RelProtoDataType() {
+          public RelDataType apply(RelDataTypeFactory typeFactory) {
+            return typeFactory.builder().add("c", SqlTypeName.VARCHAR, 100)
+                    .build();
+          }
+        }, "values (" + SqlDialect.CALCITE.quoteStringLiteral(s) + ")",
+        ImmutableList.<String>of(), Arrays.asList("view"));
+  }
+
   public static TranslatableTable str(Object o, Object p) {
     assertThat(RexLiteral.validConstant(o, Litmus.THROW), is(true));
     assertThat(RexLiteral.validConstant(p, Litmus.THROW), is(true));