Add a test that a SQL query generates a particular logical plan.

Signed-off-by: Jacques Nadeau <[email protected]>


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

Branch: refs/heads/execwork
Commit: a30254726f21ab93cdd2ced98a774863aa07cfe0
Parents: 46696a7
Author: Julian Hyde <[email protected]>
Authored: Fri Mar 8 15:03:06 2013 -0800
Committer: Jacques Nadeau <[email protected]>
Committed: Thu Jun 6 11:06:42 2013 -0700

----------------------------------------------------------------------
 .../java/org/apache/drill/common/util/Hook.java    |   79 +++++++++++++++
 .../org/apache/drill/optiq/EnumerableDrillRel.java |    2 +
 .../org/apache/drill/jdbc/test/JdbcAssert.java     |   23 ++++
 .../java/org/apache/drill/jdbc/test/JdbcTest.java  |   11 ++
 4 files changed, 115 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a3025472/sandbox/prototype/common/src/main/java/org/apache/drill/common/util/Hook.java
----------------------------------------------------------------------
diff --git 
a/sandbox/prototype/common/src/main/java/org/apache/drill/common/util/Hook.java 
b/sandbox/prototype/common/src/main/java/org/apache/drill/common/util/Hook.java
new file mode 100644
index 0000000..2629e4d
--- /dev/null
+++ 
b/sandbox/prototype/common/src/main/java/org/apache/drill/common/util/Hook.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ 
******************************************************************************/
+package org.apache.drill.common.util;
+
+import com.google.common.base.Function;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Collection of hooks that can be set by observers and are executed at various
+ * parts of the query preparation process.
+ *
+ * <p>For testing and debugging rather than for end-users.</p>
+ */
+public enum Hook {
+  /** Called with the logical plan. */
+  LOGICAL_PLAN;
+
+  private final List<Function<Object, Object>> handlers =
+      new CopyOnWriteArrayList<>();
+
+  /** Adds a handler for this Hook.
+   *
+   * <p>Returns a {@link Hook.Closeable} so that you can use the following
+   * try-finally pattern to prevent leaks:</p>
+   *
+   * <blockquote><pre>
+   *     final Hook.Closeable closeable = Hook.FOO.add(HANDLER);
+   *     try {
+   *         ...
+   *     } finally {
+   *         closeable.close();
+   *     }</pre>
+   * </blockquote>
+   */
+  public Closeable add(final Function handler) {
+    handlers.add(handler);
+    return new Closeable() {
+      public void close() {
+        remove(handler);
+      }
+    };
+  }
+
+  /** Removes a handler from this Hook. */
+  private boolean remove(Function handler) {
+    return handlers.remove(handler);
+  }
+
+  /** Runs all handlers registered for this Hook, with the given argument. */
+  public void run(Object arg) {
+    for (Function<Object, Object> handler : handlers) {
+      handler.apply(arg);
+    }
+  }
+
+  /** Removes a Hook after use. */
+  public interface Closeable extends AutoCloseable {
+    void close(); // override, removing "throws"
+  }
+}
+
+// End Hook.java

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a3025472/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/optiq/EnumerableDrillRel.java
----------------------------------------------------------------------
diff --git 
a/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/optiq/EnumerableDrillRel.java
 
b/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/optiq/EnumerableDrillRel.java
index 706bb5b..b914619 100644
--- 
a/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/optiq/EnumerableDrillRel.java
+++ 
b/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/optiq/EnumerableDrillRel.java
@@ -23,6 +23,7 @@ import net.hydromatic.linq4j.expressions.Expressions;
 import net.hydromatic.optiq.impl.java.JavaTypeFactory;
 import net.hydromatic.optiq.rules.java.*;
 
+import org.apache.drill.common.util.Hook;
 import org.eigenbase.rel.RelNode;
 import org.eigenbase.rel.SingleRel;
 import org.eigenbase.relopt.RelOptCluster;
@@ -88,6 +89,7 @@ public class EnumerableDrillRel extends SingleRel implements 
EnumerableRel {
       throw new RuntimeException(e);
     }
     String plan = drillImplementor.getJsonString();
+    Hook.LOGICAL_PLAN.run(plan);
     return new BlockBuilder()
         .append(
             Expressions.call(

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a3025472/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcAssert.java
----------------------------------------------------------------------
diff --git 
a/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcAssert.java
 
b/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcAssert.java
index 4bd3462..1479673 100644
--- 
a/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcAssert.java
+++ 
b/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcAssert.java
@@ -19,6 +19,7 @@ package org.apache.drill.jdbc.test;
 
 import com.google.common.base.Function;
 import junit.framework.Assert;
+import org.apache.drill.common.util.Hook;
 
 import java.sql.*;
 import java.util.Properties;
@@ -111,6 +112,28 @@ public class JdbcAssert {
         }
       }
     }
+
+    public void plainContains(String expected) {
+      final String[] plan = {null};
+      Connection connection = null;
+      Statement statement = null;
+      Hook.Closeable x =
+          Hook.LOGICAL_PLAN.add(
+              new Function<String, Void>() {
+                public Void apply(String o) {
+                  plan[0] = o;
+                  return null;
+                }
+              });
+      try {
+        connection = connectionFactory.createConnection();
+        statement = connection.prepareStatement(sql);
+        statement.close();
+        Assert.assertTrue(plan[0].contains(expected));
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+    }
   }
 
   private static interface ConnectionFactory {

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/a3025472/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcTest.java
----------------------------------------------------------------------
diff --git 
a/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcTest.java
 
b/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcTest.java
index d0d30fd..958990a 100644
--- 
a/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcTest.java
+++ 
b/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcTest.java
@@ -111,6 +111,17 @@ public class JdbcTest extends TestCase {
             + "PPU=1.0\n");
   }
 
+  /** Checks the logical plan. */
+  public void testProjectPlan() throws Exception {
+    JdbcAssert.withModel(MODEL, "DONUTS")
+        .sql("select _MAP['donuts']['ppu'] as ppu from donuts")
+        
.plainContains("{\"head\":{\"type\":\"apache_drill_logical_plan\",\"version\":\"1\",\"generator\":{\"type\":\"manual\",\"info\":\"na\"}},"
 +
+            
"\"storage\":[{\"name\":\"donuts-json\",\"type\":\"classpath\"},{\"name\":\"queue\",\"type\":\"queue\"}],"
 +
+            "\"query\":[" +
+            
"{\"op\":\"sequence\",\"do\":[{\"op\":\"scan\",\"memo\":\"initial_scan\",\"ref\":\"donuts\",\"storageengine\":\"donuts-json\",\"selection\":{\"path\":\"/donuts.json\",\"type\":\"JSON\"}},"
 +
+            "{\"op\":\"store\",\"storageengine\":\"queue\",\"memo\":\"output 
sink\",\"target\":{\"number\":0}}]}]}");
+  }
+
   /** Query with subquery, filter, and projection of one real and one
    * nonexistent field from a map field. */
   public void testProjectFilterSubquery() throws Exception {

Reply via email to