Merge branch 'master' into execwork

Conflicts:
        
sandbox/prototype/common/src/main/java/org/apache/drill/common/logical/data/Order.java
        
sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/rops/OrderROP.java
        
sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/rse/QueueRSE.java
        
sandbox/prototype/sqlparser/src/main/java/org/apache/drill/jdbc/Driver.java
        
sandbox/prototype/sqlparser/src/main/java/org/apache/drill/optiq/DrillScan.java


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

Branch: refs/heads/execwork
Commit: 5c07ccde62323ad409562a2bfb70754bc55bb939
Parents: ea52111 3a11d29
Author: Jacques Nadeau <[email protected]>
Authored: Thu Jun 6 12:00:16 2013 -0700
Committer: Jacques Nadeau <[email protected]>
Committed: Thu Jun 6 12:00:16 2013 -0700

----------------------------------------------------------------------
 .../apache/drill/common/logical/data/Order.java    |   61 +++++-
 .../apache/drill/common/logical/data/Union.java    |   10 +-
 .../java/org/apache/drill/common/util/Hook.java    |   79 ++++++
 .../common/src/test/resources/donuts-model.json    |   19 ++
 .../org/apache/drill/exec/ref/ROPConverter.java    |    3 +-
 .../drill/exec/ref/ReferenceInterpreter.java       |   68 +++++-
 .../org/apache/drill/exec/ref/UnbackedRecord.java  |   22 ++
 .../exec/ref/rops/CollapsingAggregateROP.java      |   10 +-
 .../org/apache/drill/exec/ref/rops/JoinROP.java    |   12 +-
 .../org/apache/drill/exec/ref/rops/OrderROP.java   |   18 +-
 .../org/apache/drill/exec/ref/rops/UnionROP.java   |   79 ++++--
 .../org/apache/drill/exec/ref/rse/QueueRSE.java    |   51 +++-
 .../org/apache/drill/exec/ref/rse/RSERegistry.java |    4 +-
 .../apache/drill/exec/ref/values/DataValue.java    |    1 +
 .../apache/drill/exec/ref/values/ScalarValues.java |    4 +-
 .../drill/exec/ref/values/SimpleMapValue.java      |   21 ++
 .../org/apache/drill/exec/ref/RSERegistryTest.java |   40 +++
 .../java/org/apache/drill/exec/ref/TestUtils.java  |   82 ++++++-
 .../exec/ref/rops/CollapsingAggregateTest.java     |   50 ++++
 .../apache/drill/exec/ref/rops/JoinROPTest.java    |   39 +++
 .../apache/drill/exec/ref/rops/OrderROPTest.java   |   60 +++++
 .../apache/drill/exec/ref/rops/UnionROPTest.java   |   46 ++++
 .../ref/src/test/resources/collapse/test1.json     |   73 ++++++
 .../ref/src/test/resources/join/departments.json   |   16 ++
 .../ref/src/test/resources/join/employees.json     |   24 ++
 .../ref/src/test/resources/join/full_join.json     |   72 ++++++
 .../ref/src/test/resources/join/left_join.json     |   71 ++++++
 .../ref/src/test/resources/join/simple_join.json   |   71 ++++++
 .../ref/src/test/resources/order/nulls-first.json  |   79 ++++++
 .../ref/src/test/resources/order/nulls-last.json   |   79 ++++++
 .../ref/src/test/resources/union/distinct.json     |   82 ++++++
 .../ref/src/test/resources/union/nondistinct.json  |   82 ++++++
 sandbox/prototype/sqlparser/pom.xml                |   10 +-
 .../java/org/apache/drill/jdbc/DrillTable.java     |   71 ++++--
 .../main/java/org/apache/drill/jdbc/Driver.java    |   68 ++---
 .../org/apache/drill/optiq/DrillFilterRel.java     |   66 +++++
 .../org/apache/drill/optiq/DrillFilterRule.java    |   52 ++++
 .../org/apache/drill/optiq/DrillImplementor.java   |    5 +
 .../java/org/apache/drill/optiq/DrillOptiq.java    |  103 +++++++--
 .../org/apache/drill/optiq/DrillPrepareImpl.java   |   47 ++++
 .../org/apache/drill/optiq/DrillProjectRel.java    |   88 +++++++
 .../org/apache/drill/optiq/DrillProjectRule.java   |   51 ++++
 .../main/java/org/apache/drill/optiq/DrillRel.java |    5 +
 .../java/org/apache/drill/optiq/DrillScan.java     |    7 +-
 .../org/apache/drill/optiq/DrillValuesRel.java     |   58 +++++
 .../org/apache/drill/optiq/DrillValuesRule.java    |   48 ++++
 .../org/apache/drill/optiq/EnumerableDrill.java    |  145 ++++++-----
 .../org/apache/drill/optiq/EnumerableDrillRel.java |   53 +++--
 .../apache/drill/optiq/EnumerableDrillRule.java    |   12 +-
 .../org/apache/drill/jdbc/test/JdbcAssert.java     |  148 +++++++++++
 .../java/org/apache/drill/jdbc/test/JdbcTest.java  |  197 ++++++++++++---
 51 files changed, 2385 insertions(+), 277 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c07ccde/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/rse/QueueRSE.java
----------------------------------------------------------------------
diff --cc 
sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/rse/QueueRSE.java
index 9a0a132,8f7a6a5..3bb1648
--- 
a/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/rse/QueueRSE.java
+++ 
b/sandbox/prototype/exec/ref/src/main/java/org/apache/drill/exec/ref/rse/QueueRSE.java
@@@ -48,7 -52,25 +52,24 @@@ public class QueueRSE extends RSEBase 
      return sinkQueues.get(number);
    }
    
-   @JsonTypeName("queue") public static class QueueRSEConfig extends 
StorageEngineConfigBase {}
+   @JsonTypeName("queue")
+   public static class QueueRSEConfig extends StorageEngineConfigBase {
+     
+     public static enum Encoding {JSON, RECORD};
+     
+     private final Encoding encoding;
+     
+     @JsonCreator
 -    public QueueRSEConfig(@JsonProperty("name") String name, 
@JsonProperty("encoding") Encoding encoding) {
 -      super(name);
++    public QueueRSEConfig(@JsonProperty("encoding") Encoding encoding) {
+       this.encoding = encoding == null ? Encoding.JSON : encoding;
+     }
+ 
+     public Encoding getEncoding() {
+       return encoding;
+     }
+     
+     
+   }
    
    public static class QueueOutputInfo{
      public int number;

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c07ccde/sandbox/prototype/exec/ref/src/test/java/org/apache/drill/exec/ref/RSERegistryTest.java
----------------------------------------------------------------------
diff --cc 
sandbox/prototype/exec/ref/src/test/java/org/apache/drill/exec/ref/RSERegistryTest.java
index 0000000,efb3855..fe9d497
mode 000000,100644..100644
--- 
a/sandbox/prototype/exec/ref/src/test/java/org/apache/drill/exec/ref/RSERegistryTest.java
+++ 
b/sandbox/prototype/exec/ref/src/test/java/org/apache/drill/exec/ref/RSERegistryTest.java
@@@ -1,0 -1,40 +1,40 @@@
+ 
/*******************************************************************************
+  * 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.exec.ref;
+ 
+ import org.apache.drill.common.config.DrillConfig;
+ import org.apache.drill.common.logical.StorageEngineConfig;
+ import org.apache.drill.exec.ref.rse.ConsoleRSE;
+ import org.apache.drill.exec.ref.rse.RSERegistry;
+ import org.junit.Test;
+ 
+ import static junit.framework.Assert.assertSame;
+ 
+ 
+ public class RSERegistryTest {
+ 
+   @Test
+   public void testEnginesWithTheSameNameAreEqual() {
+     DrillConfig config = DrillConfig.create();
+     RSERegistry rses = new RSERegistry(config);
 -    StorageEngineConfig hconfig = new ConsoleRSE.ConsoleRSEConfig("console");
++    StorageEngineConfig hconfig = new ConsoleRSE.ConsoleRSEConfig();
+     ConsoleRSE engine = (ConsoleRSE) rses.getEngine(hconfig);
+     ConsoleRSE engine2 = (ConsoleRSE) rses.getEngine(hconfig);
+     assertSame(engine, engine2);
+   }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c07ccde/sandbox/prototype/exec/ref/src/test/resources/collapse/test1.json
----------------------------------------------------------------------
diff --cc sandbox/prototype/exec/ref/src/test/resources/collapse/test1.json
index 0000000,43ef233..d4b1e24
mode 000000,100644..100644
--- a/sandbox/prototype/exec/ref/src/test/resources/collapse/test1.json
+++ b/sandbox/prototype/exec/ref/src/test/resources/collapse/test1.json
@@@ -1,0 -1,71 +1,73 @@@
+ {
+   "head" : {
 -    "type" : "apache_drill_logical_plan",
++    "type" : "APACHE_DRILL_LOGICAL",
+     "version" : 1,
+     "generator" : {
+       "type" : "manual",
+       "info" : "na"
+     }
+   },
 -  "storage" : [ {
 -    "type" : "queue",
 -    "name" : "queue",
 -    "encoding" : "RECORD"
 -  }, {
 -    "type" : "classpath",
 -    "name" : "donuts-json"
 -  } ],
++  "storage" : {
++    "queue" : {
++        "type" : "queue",
++        "encoding" : "RECORD"
++    },
++    "donuts-json" : {
++          "type": "classpath"
++    }
++  },
++
+   "query" : [ {
+     "op" : "scan",
+     "@id" : 1,
+     "memo" : "initial_scan",
+     "storageengine" : "donuts-json",
+     "selection" : {
+       "path" : "/employees.json",
+       "type" : "JSON"
+     },
+     "ref" : "_MAP"
+   }, {
+     "op" : "project",
+     "input" : 1,
+     "@id" : 2,
+     "projections" : [ {
+       "ref" : "output.deptId",
+       "expr" : "_MAP.deptId"
+     } ]
+   },  {
+     op: "segment",
+     "input" : 2,
+     "@id" : 3,
+     ref: "segment",
+     exprs: ["deptId"]
+   }, {
+     "input" : 3,
+     "@id" : 4,
+     op: "collapsingaggregate",
+     within: "segment",
+     carryovers: [ "deptId" ],
+     aggregations: [
+                 { ref: "typeCount",  expr: "count(1)" }
+               ]
+   }, 
+   {
+     op: "order",
+     "input" : 4,
+     "@id" : 5,
+     orderings: [
+       {order: "asc", expr: "deptId"}
+     ]
+   },
+   {
+     "op" : "store",
+     "input" : 5,
+     "@id" : 6,
+     "memo" : "output sink",
+     "target" : {
+       "number" : 0
+     },
+     "partition" : null,
+     "storageEngine" : "queue"
+   } ]
+ }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c07ccde/sandbox/prototype/exec/ref/src/test/resources/join/full_join.json
----------------------------------------------------------------------
diff --cc sandbox/prototype/exec/ref/src/test/resources/join/full_join.json
index 0000000,d565a08..59a53f3
mode 000000,100644..100644
--- a/sandbox/prototype/exec/ref/src/test/resources/join/full_join.json
+++ b/sandbox/prototype/exec/ref/src/test/resources/join/full_join.json
@@@ -1,0 -1,74 +1,72 @@@
+ {
+    head: {
 -      type: "apache_drill_logical_plan",
++      type: "APACHE_DRILL_LOGICAL",
+       version: "1",
+       generator: {
+          type: "manual",
+          info: "na"
+       }
+    },
 -   storage:[
 -       {
 -         type:"console",
 -         name:"console"
 -       },
 -       {
 -         type:"fs",
 -         name:"fs1",
 -         root:"file:///"
 -       },
 -       {
 -         type:"classpath",
 -         name:"cp"
 -       },
 -       {
 -         type: "queue",
 -         name: "queue"
 -       }
 -   ],
 -   query: [
++    "storage" : {
++        "queue" : {
++            "type" : "queue",
++            "encoding" : "RECORD"
++        },
++        "cp" : {
++            "type": "classpath"
++        },
++        "fs1" : {
++            "type" : "fs",
++            "root" : "file:///"
++        },
++        "console" : {
++            "type" : "console"
++        }
++    },
++
++   "query": [
+       {
+          @id: 1,
+          op: "scan",
+          memo: "initial_scan",
+          ref: "employees",
+          storageengine: "cp",
+          selection: {
+                path: "/join/employees.json",
+                type: "JSON"
+          }
+       },
+       {
+          @id: 2,
+          op: "scan",
+          memo: "second_scan",
+          ref: "departments",
+          storageengine: "cp",
+          selection: {
+              path: "/join/departments.json",
+              type: "JSON"
+          }
+       },
+       {
+          @id: 3,
+          op: "join",
+          left: 1,
+          right: 2,
+          type: "outer",
+          conditions: [
+             {
+                relationship: "==",
+                left: "employees.deptId",
+                right: "departments.deptId"
+             }
+          ]
+       },
+       {
+          input: 3,
+          op: "store",
+          memo: "output sink",
+          storageengine: "queue",
+          target: {number: 0}
+       }
+    ]
+ }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c07ccde/sandbox/prototype/exec/ref/src/test/resources/join/left_join.json
----------------------------------------------------------------------
diff --cc sandbox/prototype/exec/ref/src/test/resources/join/left_join.json
index 0000000,ac43be4..96e6a79
mode 000000,100644..100644
--- a/sandbox/prototype/exec/ref/src/test/resources/join/left_join.json
+++ b/sandbox/prototype/exec/ref/src/test/resources/join/left_join.json
@@@ -1,0 -1,74 +1,71 @@@
+ {
+    head: {
 -      type: "apache_drill_logical_plan",
++      type: "APACHE_DRILL_LOGICAL",
+       version: "1",
+       generator: {
+          type: "manual",
+          info: "na"
+       }
+    },
 -   storage:[
 -       {
 -         type:"console",
 -         name:"console"
++   storage:{
++       "queue" : {
++           "type" : "queue",
++           "encoding" : "RECORD"
+        },
 -       {
 -         type:"fs",
 -         name:"fs1",
 -         root:"file:///"
++       "cp" : {
++           "type": "classpath"
+        },
 -       {
 -         type:"classpath",
 -         name:"cp"
++       "fs1" : {
++           "type" : "fs",
++           "root" : "file:///"
+        },
 -       {
 -         type: "queue",
 -         name: "queue"
++       "console" : {
++           "type" : "console"
+        }
 -   ],
++   },
+    query: [
+       {
+          @id: 1,
+          op: "scan",
+          memo: "initial_scan",
+          ref: "employees",
+          storageengine: "cp",
+          selection: {
+                path: "/join/employees.json",
+                type: "JSON"
+          }
+       },
+       {
+          @id: 2,
+          op: "scan",
+          memo: "second_scan",
+          ref: "departments",
+          storageengine: "cp",
+          selection: {
+              path: "/join/departments.json",
+              type: "JSON"
+          }
+       },
+       {
+          @id: 3,
+          op: "join",
+          left: 1,
+          right: 2,
+          type: "left",
+          conditions: [
+             {
+                relationship: "==",
+                left: "employees.deptId",
+                right: "departments.deptId"
+             }
+          ]
+       },
+       {
+          input: 3,
+          op: "store",
+          memo: "output sink",
+          storageengine: "queue",
+          target: {number: 0}
+       }
+    ]
+ }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c07ccde/sandbox/prototype/exec/ref/src/test/resources/join/simple_join.json
----------------------------------------------------------------------
diff --cc sandbox/prototype/exec/ref/src/test/resources/join/simple_join.json
index 0000000,65c82cf..1587a78
mode 000000,100644..100644
--- a/sandbox/prototype/exec/ref/src/test/resources/join/simple_join.json
+++ b/sandbox/prototype/exec/ref/src/test/resources/join/simple_join.json
@@@ -1,0 -1,74 +1,71 @@@
+ {
+    head: {
 -      type: "apache_drill_logical_plan",
++      type: "APACHE_DRILL_LOGICAL",
+       version: "1",
+       generator: {
+          type: "manual",
+          info: "na"
+       }
+    },
 -   storage:[
 -       {
 -         type:"console",
 -         name:"console"
++   storage:{
++       "queue" : {
++           "type" : "queue",
++           "encoding" : "RECORD"
+        },
 -       {
 -         type:"fs",
 -         name:"fs1",
 -         root:"file:///"
++       "cp" : {
++           "type": "classpath"
+        },
 -       {
 -         type:"classpath",
 -         name:"cp"
++       "fs1" : {
++           "type" : "fs",
++           "root" : "file:///"
+        },
 -       {
 -         type: "queue",
 -         name: "queue"
++       "console" : {
++           "type" : "console"
+        }
 -   ],
++   },
+    query: [
+       {
+          @id: 1,
+          op: "scan",
+          memo: "initial_scan",
+          ref: "employees",
+          storageengine: "cp",
+          selection: {
+                path: "/join/employees.json",
+                type: "JSON"
+          }
+       },
+       {
+          @id: 2,
+          op: "scan",
+          memo: "second_scan",
+          ref: "departments",
+          storageengine: "cp",
+          selection: {
+              path: "/join/departments.json",
+              type: "JSON"
+          }
+       },
+       {
+          @id: 3,
+          op: "join",
+          left: 1,
+          right: 2,
+          type: "inner",
+          conditions: [
+             {
+                relationship: "==",
+                left: "employees.deptId",
+                right: "departments.deptId"
+             }
+          ]
+       },
+       {
+          input: 3,
+          op: "store",
+          memo: "output sink",
+          storageengine: "queue",
+          target: {number: 0}
+       }
+    ]
+ }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c07ccde/sandbox/prototype/exec/ref/src/test/resources/order/nulls-first.json
----------------------------------------------------------------------
diff --cc sandbox/prototype/exec/ref/src/test/resources/order/nulls-first.json
index 0000000,a0810e5..6e541e9
mode 000000,100644..100644
--- a/sandbox/prototype/exec/ref/src/test/resources/order/nulls-first.json
+++ b/sandbox/prototype/exec/ref/src/test/resources/order/nulls-first.json
@@@ -1,0 -1,71 +1,79 @@@
+ {
+   "head" : {
 -    "type" : "apache_drill_logical_plan",
++    "type" : "APACHE_DRILL_LOGICAL",
+     "version" : 1,
+     "generator" : {
+       "type" : "manual",
+       "info" : "na"
+     }
+   },
 -  "storage" : [ {
 -    "type" : "queue",
 -    "name" : "queue",
 -    "encoding" : "RECORD"
 -  }, {
 -    "type" : "classpath",
 -    "name" : "donuts-json"
 -  } ],
++  "storage" : {
++      "queue" : {
++          "type" : "queue",
++          "encoding" : "RECORD"
++      },
++      "cp" : {
++          "type": "classpath"
++      },
++      "fs1" : {
++          "type" : "fs",
++          "root" : "file:///"
++      },
++      "console" : {
++          "type" : "console"
++      }
++  },
+   "query" : [ {
+     "op" : "scan",
+     "@id" : 1,
+     "memo" : "initial_scan",
 -    "storageengine" : "donuts-json",
++    "storageengine" : "cp",
+     "selection" : {
+       "path" : "/employees.json",
+       "type" : "JSON"
+     },
+     "ref" : "_MAP"
+   }, {
+     "op" : "project",
+     "input" : 1,
+     "@id" : 2,
+     "projections" : [ {
+       "ref" : "output.deptId",
+       "expr" : "_MAP.deptId"
+     } ]
+   },  {
+     op: "segment",
+     "input" : 2,
+     "@id" : 3,
+     ref: "segment",
+     exprs: ["deptId"]
+   }, {
+     "input" : 3,
+     "@id" : 4,
+     op: "collapsingaggregate",
+     within: "segment",
+     carryovers: [ "deptId" ],
+     aggregations: [
+                 { ref: "typeCount",  expr: "count(1)" }
+               ]
+   }, 
+   {
+     op: "order",
+     "input" : 4,
+     "@id" : 5,
+     orderings: [
+       {order: "asc", expr: "deptId", nullCollation: "first"}
+     ]
+   },
+   {
+     "op" : "store",
+     "input" : 5,
+     "@id" : 6,
+     "memo" : "output sink",
+     "target" : {
+       "number" : 0
+     },
+     "partition" : null,
+     "storageEngine" : "queue"
+   } ]
+ }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c07ccde/sandbox/prototype/exec/ref/src/test/resources/order/nulls-last.json
----------------------------------------------------------------------
diff --cc sandbox/prototype/exec/ref/src/test/resources/order/nulls-last.json
index 0000000,117a562..83338b7
mode 000000,100644..100644
--- a/sandbox/prototype/exec/ref/src/test/resources/order/nulls-last.json
+++ b/sandbox/prototype/exec/ref/src/test/resources/order/nulls-last.json
@@@ -1,0 -1,71 +1,79 @@@
+ {
+   "head" : {
 -    "type" : "apache_drill_logical_plan",
++    "type" : "APACHE_DRILL_LOGICAL",
+     "version" : 1,
+     "generator" : {
+       "type" : "manual",
+       "info" : "na"
+     }
+   },
 -  "storage" : [ {
 -    "type" : "queue",
 -    "name" : "queue",
 -    "encoding" : "RECORD"
 -  }, {
 -    "type" : "classpath",
 -    "name" : "donuts-json"
 -  } ],
++  "storage" : {
++      "queue" : {
++          "type" : "queue",
++          "encoding" : "RECORD"
++      },
++      "cp" : {
++          "type": "classpath"
++      },
++      "fs1" : {
++          "type" : "fs",
++          "root" : "file:///"
++      },
++      "console" : {
++          "type" : "console"
++      }
++  },
+   "query" : [ {
+     "op" : "scan",
+     "@id" : 1,
+     "memo" : "initial_scan",
 -    "storageengine" : "donuts-json",
++    "storageengine" : "cp",
+     "selection" : {
+       "path" : "/employees.json",
+       "type" : "JSON"
+     },
+     "ref" : "_MAP"
+   }, {
+     "op" : "project",
+     "input" : 1,
+     "@id" : 2,
+     "projections" : [ {
+       "ref" : "output.deptId",
+       "expr" : "_MAP.deptId"
+     } ]
+   },  {
+     op: "segment",
+     "input" : 2,
+     "@id" : 3,
+     ref: "segment",
+     exprs: ["deptId"]
+   }, {
+     "input" : 3,
+     "@id" : 4,
+     op: "collapsingaggregate",
+     within: "segment",
+     carryovers: [ "deptId" ],
+     aggregations: [
+                 { ref: "typeCount",  expr: "count(1)" }
+               ]
+   }, 
+   {
+     op: "order",
+     "input" : 4,
+     "@id" : 5,
+     orderings: [
+       {order: "asc", expr: "deptId", nullCollation: "last"}
+     ]
+   },
+   {
+     "op" : "store",
+     "input" : 5,
+     "@id" : 6,
+     "memo" : "output sink",
+     "target" : {
+       "number" : 0
+     },
+     "partition" : null,
+     "storageEngine" : "queue"
+   } ]
+ }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c07ccde/sandbox/prototype/exec/ref/src/test/resources/union/distinct.json
----------------------------------------------------------------------
diff --cc sandbox/prototype/exec/ref/src/test/resources/union/distinct.json
index 0000000,b975a77..9361009
mode 000000,100644..100644
--- a/sandbox/prototype/exec/ref/src/test/resources/union/distinct.json
+++ b/sandbox/prototype/exec/ref/src/test/resources/union/distinct.json
@@@ -1,0 -1,71 +1,82 @@@
+ {
 -  "head" : {
 -    "type" : "apache_drill_logical_plan",
 -    "version" : 1,
 -    "generator" : {
 -      "type" : "manual",
 -      "info" : "na"
 -    }
 -  },
 -  "storage" : [ {
 -    "type" : "queue",
 -    "name" : "queue",
 -    "encoding" : "RECORD"
 -    
 -  }, {
 -    "type" : "classpath",
 -    "name" : "donuts-json"
 -  } ],
 -  "query" : [ {
 -    "op" : "scan",
 -    "@id" : 1,
 -    "memo" : "initial_scan",
 -    "storageengine" : "donuts-json",
 -    "selection" : {
 -      "path" : "/employees.json",
 -      "type" : "JSON"
++    "head": {
++        "type": "APACHE_DRILL_LOGICAL",
++        "version": 1,
++        "generator": {
++            "type": "manual",
++            "info": "na"
++        }
+     },
 -    "ref" : "_MAP"
 -  }, {
 -    "op" : "project",
 -    "input" : 1,
 -    "@id" : 2,
 -    "projections" : [ {
 -      "ref" : "output.deptId",
 -      "expr" : "_MAP.deptId"
 -    } ]
 -  }, {
 -    "op" : "scan",
 -    "@id" : 3,
 -    "memo" : "initial_scan",
 -    "storageengine" : "donuts-json",
 -    "selection" : {
 -      "path" : "/departments.json",
 -      "type" : "JSON"
++    "storage": {
++        "queue": {
++            "type": "queue",
++            "encoding": "RECORD"
++        },
++        "donuts-json": {
++            "type": "classpath"
++        }
+     },
 -    "ref" : "_MAP"
 -  }, {
 -    "op" : "project",
 -    "input" : 3,
 -    "@id" : 4,
 -    "projections" : [ {
 -      "ref" : "output.deptId",
 -      "expr" : "_MAP.deptId"
 -    } ]
 -  },  {
 -    "op": "union",
 -    "@id" : 5,
 -    "distinct": true,
 -    "inputs": [2, 4]
 -  }, {
 -    "op" : "store",
 -    "input" : 5,
 -    "@id" : 6,
 -    "memo" : "output sink",
 -    "target" : {
 -      "number" : 0
 -    },
 -    "partition" : null,
 -    "storageEngine" : "queue"
 -  } ]
++    "query": [
++        {
++            "op": "scan",
++            "@id": 1,
++            "memo": "initial_scan",
++            "storageengine": "donuts-json",
++            "selection": {
++                "path": "/employees.json",
++                "type": "JSON"
++            },
++            "ref": "_MAP"
++        },
++        {
++            "op": "project",
++            "input": 1,
++            "@id": 2,
++            "projections": [
++                {
++                    "ref": "output.deptId",
++                    "expr": "_MAP.deptId"
++                }
++            ]
++        },
++        {
++            "op": "scan",
++            "@id": 3,
++            "memo": "initial_scan",
++            "storageengine": "donuts-json",
++            "selection": {
++                "path": "/departments.json",
++                "type": "JSON"
++            },
++            "ref": "_MAP"
++        },
++        {
++            "op": "project",
++            "input": 3,
++            "@id": 4,
++            "projections": [
++                {
++                    "ref": "output.deptId",
++                    "expr": "_MAP.deptId"
++                }
++            ]
++        },
++        {
++            "op": "union",
++            "@id": 5,
++            "distinct": true,
++            "inputs": [2, 4]
++        },
++        {
++            "op": "store",
++            "input": 5,
++            "@id": 6,
++            "memo": "output sink",
++            "target": {
++                "number": 0
++            },
++            "partition": null,
++            "storageEngine": "queue"
++        }
++    ]
+ }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c07ccde/sandbox/prototype/exec/ref/src/test/resources/union/nondistinct.json
----------------------------------------------------------------------
diff --cc sandbox/prototype/exec/ref/src/test/resources/union/nondistinct.json
index 0000000,817ed48..35ad70e
mode 000000,100644..100644
--- a/sandbox/prototype/exec/ref/src/test/resources/union/nondistinct.json
+++ b/sandbox/prototype/exec/ref/src/test/resources/union/nondistinct.json
@@@ -1,0 -1,71 +1,82 @@@
+ {
 -  "head" : {
 -    "type" : "apache_drill_logical_plan",
 -    "version" : 1,
 -    "generator" : {
 -      "type" : "manual",
 -      "info" : "na"
 -    }
 -  },
 -  "storage" : [ {
 -    "type" : "queue",
 -    "name" : "queue",
 -    "encoding" : "RECORD"
 -    
 -  }, {
 -    "type" : "classpath",
 -    "name" : "donuts-json"
 -  } ],
 -  "query" : [ {
 -    "op" : "scan",
 -    "@id" : 1,
 -    "memo" : "initial_scan",
 -    "storageengine" : "donuts-json",
 -    "selection" : {
 -      "path" : "/employees.json",
 -      "type" : "JSON"
++    "head": {
++        "type": "APACHE_DRILL_LOGICAL",
++        "version": 1,
++        "generator": {
++            "type": "manual",
++            "info": "na"
++        }
+     },
 -    "ref" : "_MAP"
 -  }, {
 -    "op" : "project",
 -    "input" : 1,
 -    "@id" : 2,
 -    "projections" : [ {
 -      "ref" : "output.deptId",
 -      "expr" : "_MAP.deptId"
 -    } ]
 -  }, {
 -    "op" : "scan",
 -    "@id" : 3,
 -    "memo" : "initial_scan",
 -    "storageengine" : "donuts-json",
 -    "selection" : {
 -      "path" : "/departments.json",
 -      "type" : "JSON"
++    "storage": {
++        "queue": {
++            "type": "queue",
++            "encoding": "RECORD"
++        },
++        "donuts-json": {
++            "type": "classpath"
++        }
+     },
 -    "ref" : "_MAP"
 -  }, {
 -    "op" : "project",
 -    "input" : 3,
 -    "@id" : 4,
 -    "projections" : [ {
 -      "ref" : "output.deptId",
 -      "expr" : "_MAP.deptId"
 -    } ]
 -  },  {
 -    "op": "union",
 -    "@id" : 5,
 -    "distinct": false,
 -    "inputs": [2, 4]
 -  }, {
 -    "op" : "store",
 -    "input" : 5,
 -    "@id" : 6,
 -    "memo" : "output sink",
 -    "target" : {
 -      "number" : 0
 -    },
 -    "partition" : null,
 -    "storageEngine" : "queue"
 -  } ]
++    "query": [
++        {
++            "op": "scan",
++            "@id": 1,
++            "memo": "initial_scan",
++            "storageengine": "donuts-json",
++            "selection": {
++                "path": "/employees.json",
++                "type": "JSON"
++            },
++            "ref": "_MAP"
++        },
++        {
++            "op": "project",
++            "input": 1,
++            "@id": 2,
++            "projections": [
++                {
++                    "ref": "output.deptId",
++                    "expr": "_MAP.deptId"
++                }
++            ]
++        },
++        {
++            "op": "scan",
++            "@id": 3,
++            "memo": "initial_scan",
++            "storageengine": "donuts-json",
++            "selection": {
++                "path": "/departments.json",
++                "type": "JSON"
++            },
++            "ref": "_MAP"
++        },
++        {
++            "op": "project",
++            "input": 3,
++            "@id": 4,
++            "projections": [
++                {
++                    "ref": "output.deptId",
++                    "expr": "_MAP.deptId"
++                }
++            ]
++        },
++        {
++            "op": "union",
++            "@id": 5,
++            "distinct": false,
++            "inputs": [2, 4]
++        },
++        {
++            "op": "store",
++            "input": 5,
++            "@id": 6,
++            "memo": "output sink",
++            "target": {
++                "number": 0
++            },
++            "partition": null,
++            "storageEngine": "queue"
++        }
++    ]
+ }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c07ccde/sandbox/prototype/sqlparser/pom.xml
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c07ccde/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/jdbc/DrillTable.java
----------------------------------------------------------------------
diff --cc 
sandbox/prototype/sqlparser/src/main/java/org/apache/drill/jdbc/DrillTable.java
index f530ea8,022e05d..23d7237
--- 
a/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/jdbc/DrillTable.java
+++ 
b/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/jdbc/DrillTable.java
@@@ -48,6 -48,6 +48,7 @@@ public class DrillTable extends BaseQue
  {
    private final Schema schema;
    private final String name;
++  private final String storageEngineName;
    private final RelDataType rowType;
    public final StorageEngineConfig storageEngineConfig;
    public final Object selection;
@@@ -59,18 -59,21 +60,26 @@@
        RelDataType rowType,
        String name,
        StorageEngineConfig storageEngineConfig,
-       Object selection
 -      Object selection) {
++      Object selection,
++      String storageEngineName
 +      ) {
      super(schema.getQueryProvider(), elementType, expression);
      this.schema = schema;
      this.name = name;
      this.rowType = rowType;
      this.storageEngineConfig = storageEngineConfig;
      this.selection = selection;
++    this.storageEngineName = storageEngineName;
    }
  
-   static void addTable(RelDataTypeFactory typeFactory, MutableSchema schema,
-       String name, StorageEngineConfig storageEngineConfig, Object selection) 
{
+   private static DrillTable createTable(
+       RelDataTypeFactory typeFactory,
+       MutableSchema schema,
+       String name,
+       StorageEngineConfig storageEngineConfig,
 -      Object selection) {
++      Object selection,
++      String storageEngineName
++      ) {
      final MethodCallExpression call = Expressions.call(schema.getExpression(),
          BuiltinMethod.DATA_CONTEXT_GET_TABLE.method,
          Expressions.constant(name),
@@@ -78,11 -81,12 +87,12 @@@
      final RelDataType rowType =
          typeFactory.createStructType(
              Collections.singletonList(
-                 typeFactory.createSqlType(SqlTypeName.ANY)),
-             Collections.singletonList("_extra"));
-     final DrillTable table =
-         new DrillTable(schema, Object.class, call, rowType, name, 
storageEngineConfig, selection);
-     schema.addTable(name, table);
+                 typeFactory.createMapType(
+                     typeFactory.createSqlType(SqlTypeName.VARCHAR),
+                     typeFactory.createSqlType(SqlTypeName.ANY))),
+             Collections.singletonList("_MAP"));
+       return new DrillTable(schema, Object.class, call, rowType, name,
 -          storageEngineConfig, selection);
++          storageEngineConfig, selection, storageEngineName);
    }
  
    @Override
@@@ -96,15 -100,40 +106,44 @@@
    }
  
    @Override
+   public Statistic getStatistic() {
+     return Statistics.UNKNOWN;
+   }
+ 
++  public String getStorageEngineName() {
++    return storageEngineName;
++  }
++
+   @Override
    public Enumerator<Object> enumerator() {
      return Linq4j.emptyEnumerator();
    }
  
    public RelNode toRel(RelOptTable.ToRelContext context, RelOptTable table) {
      return new DrillScan(context.getCluster(),
-         context.getCluster().traitSetOf(DrillOptiq.CONVENTION),
+         context.getCluster().traitSetOf(DrillRel.CONVENTION),
          table);
    }
+ 
+   private static <T> T last(T t0, T t1) {
+     return t0 != null ? t0 : t1;
+   }
+ 
+   /** Factory for custom tables in Optiq schema. */
+   @SuppressWarnings("UnusedDeclaration")
+   public static class Factory implements TableFactory<DrillTable> {
+     @Override
+     public DrillTable create(Schema schema, String name,
+         Map<String, Object> operand, RelDataType rowType) {
+       final ClasspathRSE.ClasspathRSEConfig rseConfig =
 -          new ClasspathRSE.ClasspathRSEConfig("donuts-json");
++          new ClasspathRSE.ClasspathRSEConfig();
+       final ClasspathInputConfig inputConfig = new ClasspathInputConfig();
+       inputConfig.path = last((String) operand.get("path"), "/donuts.json");
+       inputConfig.type = DataWriter.ConverterType.JSON;
+       return createTable(schema.getTypeFactory(), (MutableSchema) schema, 
name,
 -          rseConfig, inputConfig);
++          rseConfig, inputConfig, "donuts-json");
+     }
+   }
  }
  
  // End DrillTable.java

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c07ccde/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/optiq/DrillImplementor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c07ccde/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/optiq/DrillScan.java
----------------------------------------------------------------------
diff --cc 
sandbox/prototype/sqlparser/src/main/java/org/apache/drill/optiq/DrillScan.java
index 2e2849a,89713ae..11897d5
--- 
a/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/optiq/DrillScan.java
+++ 
b/sandbox/prototype/sqlparser/src/main/java/org/apache/drill/optiq/DrillScan.java
@@@ -37,9 -37,8 +37,8 @@@ public class DrillScan extends TableAcc
      final ObjectNode node = implementor.mapper.createObjectNode();
      node.put("op", "scan");
      node.put("memo", "initial_scan");
-     node.put("ref", "donuts");
-     final ObjectNode engines = implementor.mapper.createObjectNode();
-     node.put("storageengine", "donuts-json");
+     node.put("ref", "_MAP"); // output is a record with a single field, '_MAP'
 -    node.put("storageengine", drillTable.storageEngineConfig.getName());
++    node.put("storageengine", drillTable.getStorageEngineName());
      node.put("selection", 
implementor.mapper.convertValue(drillTable.selection, JsonNode.class));
      implementor.add(node);
    }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/5c07ccde/sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcTest.java
----------------------------------------------------------------------
diff --cc 
sandbox/prototype/sqlparser/src/test/java/org/apache/drill/jdbc/test/JdbcTest.java
index eb0b51a,71ed10d..2d57732
--- 
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
@@@ -49,39 -87,118 +87,118 @@@ public class JdbcTest extends TestCase 
  
    /** Simple query against JSON. */
    public void testSelectJson() throws Exception {
-     Class.forName("org.apache.drill.jdbc.Driver");
-     final Connection connection = DriverManager.getConnection(
-         "jdbc:drill:schema=DONUTS;tables=DONUTS");
-     final Statement statement = connection.createStatement();
-     final ResultSet resultSet = statement.executeQuery(
-         "select * from donuts");
-     assertEquals(
-         "_extra={donuts={batters={batter=[{id=1001, type=Regular}, {id=1002, 
type=Chocolate}, {id=1003, type=Blueberry}, {id=1004, type=Devil's Food}]}, 
id=0001, name=Cake, ppu=0.55, sales=35, topping=[{id=5001, type=None}, 
{id=5002, type=Glazed}, {id=5005, type=Sugar}, {id=5007, type=Powdered Sugar}, 
{id=5006, type=Chocolate with Sprinkles}, {id=5003, type=Chocolate}, {id=5004, 
type=Maple}], type=donut}}\n"
-         + "_extra={donuts={batters={batter=[{id=1001, type=Regular}]}, 
id=0002, name=Raised, ppu=0.69, sales=145, topping=[{id=5001, type=None}, 
{id=5002, type=Glazed}, {id=5005, type=Sugar}, {id=5003, type=Chocolate}, 
{id=5004, type=Maple}], type=donut}}\n"
-         + "_extra={donuts={batters={batter=[{id=1001, type=Regular}, 
{id=1002, type=Chocolate}]}, id=0003, name=Old Fashioned, ppu=0.55, sales=300, 
topping=[{id=5001, type=None}, {id=5002, type=Glazed}, {id=5003, 
type=Chocolate}, {id=5004, type=Maple}], type=donut}}\n"
-         + "_extra={donuts={batters={batter=[{id=1001, type=Regular}, 
{id=1002, type=Chocolate}, {id=1003, type=Blueberry}, {id=1004, type=Devil's 
Food}]}, filling=[{id=6001, type=None}, {id=6002, type=Raspberry}, {id=6003, 
type=Lemon}, {id=6004, type=Chocolate}, {id=6005, type=Kreme}], id=0004, 
name=Filled, ppu=0.69, sales=14, topping=[{id=5001, type=None}, {id=5002, 
type=Glazed}, {id=5005, type=Sugar}, {id=5007, type=Powdered Sugar}, {id=5006, 
type=Chocolate with Sprinkles}, {id=5003, type=Chocolate}, {id=5004, 
type=Maple}], type=donut}}\n"
-         + "_extra={donuts={batters={batter=[{id=1001, type=Regular}]}, 
id=0005, name=Apple Fritter, ppu=1.0, sales=700, topping=[{id=5002, 
type=Glazed}], type=donut}}\n",
-         toString(resultSet));
-     resultSet.close();
-     statement.close();
-     connection.close();
+     JdbcAssert.withModel(MODEL, "DONUTS")
+         .sql("select * from donuts")
+         .returns(EXPECTED);
+   }
+ 
+   /** Query with project list. No field references yet. */
+   public void testProjectConstant() throws Exception {
+     JdbcAssert.withModel(MODEL, "DONUTS")
+         .sql("select 1 + 3 as c from donuts")
+         .returns("C=4\n"
+             + "C=4\n"
+             + "C=4\n"
+             + "C=4\n"
+             + "C=4\n");
    }
  
-   static String toString(ResultSet resultSet) throws SQLException {
-     StringBuilder buf = new StringBuilder();
-     while (resultSet.next()) {
-       int n = resultSet.getMetaData().getColumnCount();
-       String sep = "";
-       for (int i = 1; i <= n; i++) {
-         buf.append(sep)
-             .append(resultSet.getMetaData().getColumnLabel(i))
-             .append("=")
-             .append(resultSet.getObject(i));
-         sep = "; ";
-       }
-       buf.append("\n");
-     }
-     return buf.toString();
+   /** Query that projects an element from the map. */
+   public void testProject() throws Exception {
+     JdbcAssert.withModel(MODEL, "DONUTS")
+         .sql("select _MAP['ppu'] as ppu from donuts")
+         .returns("PPU=0.55\n"
+             + "PPU=0.69\n"
+             + "PPU=0.55\n"
+             + "PPU=0.69\n"
+             + "PPU=1.0\n");
+   }
+ 
+   /** Same logic as {@link #testProject()}, but using a subquery. */
+   public void testProjectOnSubquery() throws Exception {
+     JdbcAssert.withModel(MODEL, "DONUTS")
+         .sql("select d['ppu'] as ppu from (\n"
+              + " select _MAP as d from donuts)")
+         .returns("PPU=0.55\n"
+             + "PPU=0.69\n"
+             + "PPU=0.55\n"
+             + "PPU=0.69\n"
+             + "PPU=1.0\n");
+   }
+ 
+   /** Checks the logical plan. */
+   public void testProjectPlan() throws Exception {
+     JdbcAssert.withModel(MODEL, "DONUTS")
+         .sql("select _MAP['ppu'] as ppu from donuts")
+         .planContains(
 -            
"{'head':{'type':'apache_drill_logical_plan','version':'1','generator':{'type':'manual','info':'na'}},"
 -            + 
"'storage':[{'name':'donuts-json','type':'classpath'},{'name':'queue','type':'queue'}],"
++            
"{'head':{'type':'APACHE_DRILL_LOGICAL','version':'1','generator':{'type':'manual','info':'na'}},"
++            + 
"'storage':{'donuts-json':{'type':'classpath'},'queue':{'type':'queue'}},"
+             + "'query':["
+             + "{'op':'sequence','do':["
+             + 
"{'op':'scan','memo':'initial_scan','ref':'_MAP','storageengine':'donuts-json','selection':{'path':'/donuts.json','type':'JSON'}},"
+             + 
"{'op':'project','projections':[{'expr':'_MAP.ppu','ref':'output.PPU'}]},"
+             + "{'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 {
+     JdbcAssert.withModel(MODEL, "DONUTS")
+         .sql("select d['name'] as name, d['xx'] as xx from (\n"
+             + " select _MAP as d from donuts)\n"
+             + "where cast(d['ppu'] as double) > 0.6")
+         .returns("NAME=Raised; XX=null\n"
+             + "NAME=Filled; XX=null\n"
+             + "NAME=Apple Fritter; XX=null\n");
+   }
+ 
+   public void testProjectFilterSubqueryPlan() throws Exception {
+     JdbcAssert.withModel(MODEL, "DONUTS")
+         .sql("select d['name'] as name, d['xx'] as xx from (\n"
+             + " select _MAP['donuts'] as d from donuts)\n"
+             + "where cast(d['ppu'] as double) > 0.6")
+         .planContains(
 -            
"{'head':{'type':'apache_drill_logical_plan','version':'1','generator':{'type':'manual','info':'na'}},'storage':[{'name':'donuts-json','type':'classpath'},{'name':'queue','type':'queue'}],"
++            
"{'head':{'type':'APACHE_DRILL_LOGICAL','version':'1','generator':{'type':'manual','info':'na'}},'storage':{'donuts-json':{'type':'classpath'},'queue':{'type':'queue'}},"
+             + "'query':["
+             + "{'op':'sequence','do':["
+             + 
"{'op':'scan','memo':'initial_scan','ref':'_MAP','storageengine':'donuts-json','selection':{'path':'/donuts.json','type':'JSON'}},"
+             + "{'op':'filter','expr':'(_MAP.donuts.ppu > 0.6)'},"
+             + 
"{'op':'project','projections':[{'expr':'_MAP.donuts','ref':'output.D'}]},"
+             + 
"{'op':'project','projections':[{'expr':'D.name','ref':'output.NAME'},{'expr':'D.xx','ref':'output.XX'}]},"
+             + "{'op':'store','storageengine':'queue','memo':'output 
sink','target':{'number':0}}]}]}");
+   }
+ 
+   /** Query that projects one field. (Disabled; uses sugared syntax.) */
+   public void _testProjectNestedFieldSugared() throws Exception {
+     JdbcAssert.withModel(MODEL, "DONUTS")
+         .sql("select donuts.ppu from donuts")
+         .returns("C=4\n"
+             + "C=4\n"
+             + "C=4\n"
+             + "C=4\n"
+             + "C=4\n");
+   }
+ 
+   /** Query with filter. No field references yet. */
+   public void testFilterConstantFalse() throws Exception {
+     JdbcAssert.withModel(MODEL, "DONUTS")
+         .sql("select * from donuts where 3 > 4")
+         .returns("");
+   }
+ 
+   public void testFilterConstant() throws Exception {
+     JdbcAssert.withModel(MODEL, "DONUTS")
+         .sql("select * from donuts where 3 < 4")
+         .returns(EXPECTED);
+   }
+ 
+   public void testValues() throws Exception {
+     JdbcAssert.withModel(MODEL, "DONUTS")
+         .sql("values (1)")
+         .returns("EXPR$0=1\n");
+ 
+     // Enable when https://issues.apache.org/jira/browse/DRILL-57 fixed
+     // .planContains("store");
    }
  }
  

Reply via email to