You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@drill.apache.org by ja...@apache.org on 2015/11/13 03:38:02 UTC

[32/45] drill git commit: DRILL-3987: (MOVE) Move logical expressions and operators out of common. Move to new drill-logical model.

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/JoinCondition.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/JoinCondition.java b/logical/src/main/java/org/apache/drill/common/logical/data/JoinCondition.java
new file mode 100644
index 0000000..611e70b
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/JoinCondition.java
@@ -0,0 +1,55 @@
+/**
+ * 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.logical.data;
+
+import org.apache.drill.common.expression.LogicalExpression;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class JoinCondition {
+  private final String relationship;
+  private final LogicalExpression left;
+  private final LogicalExpression right;
+
+  @JsonCreator
+  public JoinCondition(@JsonProperty("relationship") String relationship,
+      @JsonProperty("left") LogicalExpression left, @JsonProperty("right") LogicalExpression right) {
+    super();
+    this.relationship = relationship;
+    this.left = left;
+    this.right = right;
+  }
+
+  public String getRelationship() {
+    return relationship;
+  }
+
+  public LogicalExpression getLeft() {
+    return left;
+  }
+
+  public LogicalExpression getRight() {
+    return right;
+  }
+
+  public JoinCondition flip(){
+    return new JoinCondition(relationship, right, left);
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/Limit.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/Limit.java b/logical/src/main/java/org/apache/drill/common/logical/data/Limit.java
new file mode 100644
index 0000000..56ae8d9
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/Limit.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.logical.data;
+
+import java.util.Iterator;
+
+import org.apache.drill.common.logical.data.visitors.LogicalVisitor;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Iterators;
+
+@JsonTypeName("limit")
+public class Limit extends SingleInputOperator {
+
+  private final Integer first;
+  private final Integer last;
+
+  @JsonCreator
+  public Limit(@JsonProperty("first") Integer first, @JsonProperty("last") Integer last) {
+    super();
+    this.first = first;
+    this.last = last;
+  }
+
+  public Integer getFirst() {
+    return first;
+  }
+
+  public Integer getLast() {
+    return last;
+  }
+
+  @Override
+  public <T, X, E extends Throwable> T accept(LogicalVisitor<T, X, E> logicalVisitor, X value) throws E {
+    return logicalVisitor.visitLimit(this, value);
+  }
+
+  @Override
+  public NodeBuilder nodeBuilder() {
+    return new LimitNodeBuilder();  //To change body of implemented methods use File | Settings | File Templates.
+  }
+
+  @Override
+  public Iterator<LogicalOperator> iterator() {
+    return Iterators.singletonIterator(getInput());
+  }
+
+  public static class LimitNodeBuilder implements NodeBuilder<Limit> {
+
+    @Override
+    public ObjectNode convert(ObjectMapper mapper, Limit operator, Integer inputId) {
+      ObjectNode limitNode = mapper.createObjectNode();
+      limitNode.put("op", "limit");
+      limitNode.put("input", inputId);
+      limitNode.put("first", operator.first);
+      limitNode.put("last", operator.last);
+      return limitNode;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/LogicalOperator.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/LogicalOperator.java b/logical/src/main/java/org/apache/drill/common/logical/data/LogicalOperator.java
new file mode 100644
index 0000000..3343d4e
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/LogicalOperator.java
@@ -0,0 +1,56 @@
+/**
+ * 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.logical.data;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.drill.common.graph.GraphValue;
+import org.apache.drill.common.logical.ValidationError;
+import org.apache.drill.common.logical.data.visitors.LogicalVisitor;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+@JsonPropertyOrder({"@id", "memo", "input"}) // op will always be first since it is wrapped.
+@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id")
+@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "op")
+public interface LogicalOperator extends GraphValue<LogicalOperator> {
+
+  public void setupAndValidate(List<LogicalOperator> operators, Collection<ValidationError> errors);
+
+  /**
+   * Provides capability to build a set of output based on traversing a query graph tree.
+   *
+   * @param logicalVisitor
+   * @return
+   */
+  public <T, X, E extends Throwable> T accept(LogicalVisitor<T, X, E> logicalVisitor, X value) throws E;
+
+  public void registerAsSubscriber(LogicalOperator operator);
+
+  NodeBuilder nodeBuilder();
+
+  public interface NodeBuilder<T extends LogicalOperator> {
+    ObjectNode convert(ObjectMapper mapper, T operator, Integer inputId);
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/LogicalOperatorBase.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/LogicalOperatorBase.java b/logical/src/main/java/org/apache/drill/common/logical/data/LogicalOperatorBase.java
new file mode 100644
index 0000000..a213c8d
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/LogicalOperatorBase.java
@@ -0,0 +1,92 @@
+/**
+ * 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.logical.data;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.drill.common.graph.GraphVisitor;
+import org.apache.drill.common.logical.ValidationError;
+import org.apache.drill.common.scanner.persistence.ScanResult;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+
+public abstract class LogicalOperatorBase implements LogicalOperator{
+  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(LogicalOperatorBase.class);
+
+  private List<LogicalOperator> children = new ArrayList<LogicalOperator>();
+
+  private String memo;
+
+  @Override
+  public final int hashCode() {
+    return super.hashCode();
+  }
+
+  @Override
+  public void setupAndValidate(List<LogicalOperator> operators, Collection<ValidationError> errors) {
+    // TODO: remove this and implement individually.
+  }
+
+  @Override
+  public NodeBuilder nodeBuilder() {
+    // FIXME: Implement this on all logical operators
+    throw new UnsupportedOperationException("Not yet implemented.");
+  }
+
+  @Override
+  public void accept(GraphVisitor<LogicalOperator> visitor) {
+    if (visitor.enter(this)) {
+      visitor.leave(this);
+    }
+  }
+
+  @Override
+  public void registerAsSubscriber(LogicalOperator operator) {
+    if (operator == null) {
+      throw new IllegalArgumentException("You attempted to register a null operators.");
+    }
+    children.add(operator);
+  }
+
+  @Override
+  public String toString() {
+    return this.getClass().getSimpleName() + " [memo=" + memo + "]";
+  }
+
+  @JsonInclude(Include.NON_EMPTY)
+  @JsonProperty("memo")
+  public String getMemo() {
+    return memo;
+  }
+
+  public void setMemo(String memo) {
+    this.memo = memo;
+  }
+
+  public static Set<Class<? extends LogicalOperator>> getSubTypes(final ScanResult classpathScan) {
+    final Set<Class<? extends LogicalOperator>> ops = classpathScan.getImplementations(LogicalOperator.class);
+    logger.debug("Found {} logical operator classes: {}.", ops.size(), ops);
+    return ops;
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/NamedExpression.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/NamedExpression.java b/logical/src/main/java/org/apache/drill/common/logical/data/NamedExpression.java
new file mode 100644
index 0000000..a166c25
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/NamedExpression.java
@@ -0,0 +1,52 @@
+/**
+ * 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.logical.data;
+
+import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.expression.LogicalExpression;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonPropertyOrder({"ref", "expr"})
+public class NamedExpression {
+  private final LogicalExpression expr;
+  private final FieldReference ref;
+
+  @JsonCreator
+  public NamedExpression(@JsonProperty("expr") LogicalExpression expr, @JsonProperty("ref") FieldReference ref) {
+    super();
+    this.expr = expr;
+    this.ref = ref;
+  }
+
+  public LogicalExpression getExpr() {
+    return expr;
+  }
+
+  public FieldReference getRef() {
+    return ref;
+  }
+
+  @Override
+  public String toString() {
+    return "NamedExpression [expr=" + expr + ", ref=" + ref + "]";
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/Order.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/Order.java b/logical/src/main/java/org/apache/drill/common/logical/data/Order.java
new file mode 100644
index 0000000..fca6010
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/Order.java
@@ -0,0 +1,252 @@
+/**
+ * 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.logical.data;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.drill.common.exceptions.DrillRuntimeException;
+import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.logical.data.visitors.LogicalVisitor;
+import org.apache.calcite.rel.RelFieldCollation;
+import org.apache.calcite.rel.RelFieldCollation.Direction;
+import org.apache.calcite.rel.RelFieldCollation.NullDirection;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
+
+@JsonTypeName("order")
+public class Order extends SingleInputOperator {
+
+  private final Ordering[] orderings;
+  private final FieldReference within;
+
+  @JsonCreator
+  public Order(@JsonProperty("within") FieldReference within, @JsonProperty("orderings") Ordering... orderings) {
+    this.orderings = orderings;
+    this.within = within;
+  }
+
+  public Ordering[] getOrderings() {
+    return orderings;
+  }
+
+  public FieldReference getWithin() {
+    return within;
+  }
+
+    @Override
+    public <T, X, E extends Throwable> T accept(LogicalVisitor<T, X, E> logicalVisitor, X value) throws E {
+        return logicalVisitor.visitOrder(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalOperator> iterator() {
+        return Iterators.singletonIterator(getInput());
+    }
+
+
+  /**
+   * Representation of a SQL &lt;sort specification>.
+   */
+  public static class Ordering {
+
+    private final LogicalExpression expr;
+    /** Net &lt;ordering specification>. */
+    private final Direction direction;
+    /** Net &lt;null ordering> */
+    private final NullDirection nullOrdering;
+
+    /**
+     * Constructs a sort specification.
+     * @param  expr  ...
+     * @param  strOrderingSpec  the &lt;ordering specification> as string;
+     *             allowed values: {@code "ASC"}, {@code "DESC"}, {@code null};
+     *             null specifies default &lt;ordering specification>
+     *                   ({@code "ASC"} / {@link Direction#ASCENDING})
+     * @param  strNullOrdering   the &lt;null ordering> as string;
+     *             allowed values: {@code "FIRST"}, {@code "LAST"},
+     *             {@code "UNSPECIFIED"}, {@code null};
+     *             null specifies default &lt;null ordering>
+     *             (omitted / {@link NullDirection#UNSPECIFIED}, interpreted later)
+     */
+    @JsonCreator
+    public Ordering( @JsonProperty("expr") LogicalExpression expr,
+                     @JsonProperty("order") String strOrderingSpec,
+                     @JsonProperty("nullDirection") String strNullOrdering ) {
+      this.expr = expr;
+      this.direction = getOrderingSpecFromString( strOrderingSpec );
+      this.nullOrdering = getNullOrderingFromString( strNullOrdering );
+    }
+
+    public Ordering(Direction direction, LogicalExpression e, NullDirection nullOrdering) {
+      this.expr = e;
+      this.direction = direction;
+      this.nullOrdering = nullOrdering;
+    }
+
+    public Ordering(Direction direction, LogicalExpression e) {
+      this(direction, e, NullDirection.FIRST);
+    }
+
+    private static Direction getOrderingSpecFromString( String strDirection ) {
+      final Direction direction;
+      if ( null == strDirection
+          || Direction.ASCENDING.shortString.equals( strDirection ) ) {
+        direction = Direction.ASCENDING;
+      }
+      else if ( Direction.DESCENDING.shortString.equals( strDirection ) ) {
+        direction = Direction.DESCENDING;
+      }
+      else {
+        throw new DrillRuntimeException(
+            "Unknown <ordering specification> string (not \"ASC\", \"DESC\", "
+            + "or null): \"" + strDirection + "\"" );
+      }
+      return direction;
+    }
+
+    private static NullDirection getNullOrderingFromString( String strNullOrdering ) {
+      final RelFieldCollation.NullDirection nullOrdering;
+      if ( null == strNullOrdering ) {
+        nullOrdering = NullDirection.UNSPECIFIED;
+      }
+      else {
+        try {
+          nullOrdering = NullDirection.valueOf( strNullOrdering );
+        }
+        catch ( IllegalArgumentException e ) {
+          throw new DrillRuntimeException(
+              "Internal error:  Unknown <null ordering> string (not "
+              + "\"" + NullDirection.FIRST.name() + "\", "
+              + "\"" + NullDirection.LAST.name() + "\", or "
+              + "\"" + NullDirection.UNSPECIFIED.name() + "\" or null): "
+              + "\"" + strNullOrdering + "\"" );
+        }
+      }
+      return nullOrdering;
+   }
+
+    @Override
+    public String toString() {
+      return
+          super.toString()
+          + "[ "
+          + " expr = " + expr
+          + ", direction = " + direction
+          + ", nullOrdering = " + nullOrdering
+          + "] ";
+    }
+
+    @JsonIgnore
+    public Direction getDirection() {
+      return direction;
+    }
+
+    public LogicalExpression getExpr() {
+      return expr;
+    }
+
+    public String getOrder() {
+      switch (direction) {
+      case ASCENDING:
+        return Direction.ASCENDING.shortString;
+      case DESCENDING:
+        return Direction.DESCENDING.shortString;
+      default:
+        throw new DrillRuntimeException(
+            "Unexpected " + Direction.class.getName() + " value other than "
+            + Direction.ASCENDING + " or " + Direction.DESCENDING + ": "
+            + direction );
+      }
+    }
+
+    public NullDirection getNullDirection() {
+      return nullOrdering;
+    }
+
+    /**
+     * Reports whether NULL sorts high or low in this ordering.
+     *
+     * @return
+     * {@code true}  if NULL sorts higher than any other value;
+     * {@code false} if NULL sorts lower  than any other value
+     */
+    public boolean nullsSortHigh() {
+      final boolean nullsHigh;
+
+      switch (nullOrdering) {
+
+      case UNSPECIFIED:
+        // Default:  NULL sorts high: like NULLS LAST if ASC, FIRST if DESC.
+        nullsHigh = true;
+        break;
+
+      case FIRST:
+        // FIRST: NULL sorts low with ASC, high with DESC.
+        nullsHigh = Direction.DESCENDING == getDirection();
+        break;
+
+      case LAST:
+        // LAST: NULL sorts high with ASC, low with DESC.
+        nullsHigh = Direction.ASCENDING == getDirection();
+        break;
+
+      default:
+        throw new DrillRuntimeException(
+            "Unexpected " + NullDirection.class.getName() + " value other than "
+            + NullDirection.FIRST + ", " + NullDirection.LAST + " or " + NullDirection.UNSPECIFIED + ": "
+            + nullOrdering );
+      }
+
+      return nullsHigh;
+    }
+
+  }
+
+  public static Builder builder(){
+    return new Builder();
+  }
+
+  public static class Builder extends AbstractSingleBuilder<Order, Builder>{
+    private List<Ordering> orderings = Lists.newArrayList();
+    private FieldReference within;
+
+    public Builder setWithin(FieldReference within){
+      this.within = within;
+      return this;
+    }
+
+    public Builder addOrdering(Direction direction, LogicalExpression e, NullDirection collation){
+      orderings.add(new Ordering(direction, e, collation));
+      return this;
+    }
+
+    @Override
+    public Order internalBuild() {
+      return new Order(within, orderings.toArray(new Ordering[orderings.size()]));
+    }
+
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/Project.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/Project.java b/logical/src/main/java/org/apache/drill/common/logical/data/Project.java
new file mode 100644
index 0000000..4345c80
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/Project.java
@@ -0,0 +1,92 @@
+/**
+ * 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.logical.data;
+
+import java.util.List;
+
+import org.apache.drill.common.exceptions.ExpressionParsingException;
+import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.logical.data.visitors.LogicalVisitor;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.google.common.collect.Lists;
+
+@JsonTypeName("project")
+public class Project extends SingleInputOperator {
+
+  private final NamedExpression[] selections;
+
+  @JsonCreator
+  public Project(@JsonProperty("projections") NamedExpression[] selections) {
+    this.selections = selections;
+    if (selections == null || selections.length == 0) {
+      throw new ExpressionParsingException(
+          "Project did not provide any projection selections.  At least one projection must be provided.");
+//    for (int i = 0; i < selections.length; i++) {
+//      PathSegment segment = selections[i].getRef().getRootSegment();
+//      CharSequence path = segment.getNameSegment().getPath();
+//      if (!segment.isNamed() || !path.equals("output"))
+//        throw new ExpressionParsingException(
+//            String
+//                .format(
+//                    "Outputs for projections always have to start with named path of output. First segment was named '%s' or was named [%s]",
+//                    path, segment.isNamed()));
+//
+//    }
+    }
+  }
+
+  @JsonProperty("projections")
+  public NamedExpression[] getSelections() {
+    return selections;
+  }
+
+  @Override
+  public <T, X, E extends Throwable> T accept(LogicalVisitor<T, X, E> logicalVisitor, X value) throws E {
+    return logicalVisitor.visitProject(this, value);
+  }
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  public static class Builder extends AbstractSingleBuilder<Project, Builder> {
+
+    private List<NamedExpression> exprs = Lists.newArrayList();
+
+    public Builder addExpr(NamedExpression expr) {
+      exprs.add(expr);
+      return this;
+    }
+
+    public Builder addExpr(FieldReference ref, LogicalExpression expr) {
+      exprs.add(new NamedExpression(expr, ref));
+      return this;
+    }
+
+    @Override
+    public Project internalBuild() {
+      return new Project(aN(exprs));
+    }
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/RunningAggregate.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/RunningAggregate.java b/logical/src/main/java/org/apache/drill/common/logical/data/RunningAggregate.java
new file mode 100644
index 0000000..e280627
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/RunningAggregate.java
@@ -0,0 +1,63 @@
+/**
+ * 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.logical.data;
+
+import java.util.Iterator;
+
+import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.logical.data.visitors.LogicalVisitor;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.google.common.collect.Iterators;
+
+@JsonTypeName("runningaggregate")
+public class RunningAggregate extends SingleInputOperator{
+
+  private final FieldReference within;
+  private final NamedExpression[]  aggregations;
+
+  @JsonCreator
+  public RunningAggregate(@JsonProperty("within") FieldReference within, @JsonProperty("aggregations") NamedExpression[] aggregations) {
+    super();
+    this.within = within;
+    this.aggregations = aggregations;
+  }
+
+  public FieldReference getWithin() {
+    return within;
+  }
+
+  public NamedExpression[] getAggregations() {
+    return aggregations;
+  }
+
+    @Override
+    public <T, X, E extends Throwable> T accept(LogicalVisitor<T, X, E> logicalVisitor, X value) throws E {
+        return logicalVisitor.visitRunningAggregate(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalOperator> iterator() {
+        return Iterators.singletonIterator(getInput());
+    }
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/Scan.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/Scan.java b/logical/src/main/java/org/apache/drill/common/logical/data/Scan.java
new file mode 100644
index 0000000..68eabbb
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/Scan.java
@@ -0,0 +1,78 @@
+/**
+ * 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.logical.data;
+
+import org.apache.drill.common.JSONOptions;
+import org.apache.drill.common.logical.data.visitors.LogicalVisitor;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+
+@JsonTypeName("scan")
+public class Scan extends SourceOperator {
+  private final String storageEngine;
+  private final JSONOptions selection;
+
+  @JsonCreator
+  public Scan(@JsonProperty("storageengine") String storageEngine, @JsonProperty("selection") JSONOptions selection) {
+    super();
+    this.storageEngine = storageEngine;
+    this.selection = selection;
+  }
+
+  @JsonProperty("storageengine")
+  public String getStorageEngine() {
+    return storageEngine;
+  }
+
+  public JSONOptions getSelection() {
+    return selection;
+  }
+
+  @Override
+  public <T, X, E extends Throwable> T accept(LogicalVisitor<T, X, E> logicalVisitor, X value) throws E {
+      return logicalVisitor.visitScan(this, value);
+  }
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  public static class Builder extends AbstractBuilder<Scan>{
+    private String storageEngine;
+    private JSONOptions selection;
+
+    public Builder storageEngine(String storageEngine) {
+      this.storageEngine = storageEngine;
+      return this;
+    }
+
+    public Builder selection(JSONOptions selection) {
+      this.selection = selection;
+      return this;
+    }
+
+    @Override
+    public Scan build() {
+      return new Scan(storageEngine, selection);
+    }
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/Sequence.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/Sequence.java b/logical/src/main/java/org/apache/drill/common/logical/data/Sequence.java
new file mode 100644
index 0000000..f04b09c
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/Sequence.java
@@ -0,0 +1,187 @@
+/**
+ * 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.logical.data;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+import org.apache.drill.common.logical.data.Sequence.De;
+import org.apache.drill.common.logical.data.visitors.LogicalVisitor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.annotation.ObjectIdGenerator;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+import com.fasterxml.jackson.core.JsonLocation;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+import com.google.common.collect.Iterators;
+
+/**
+ * Describes a list of operators where each operator only has one input and that
+ * input is the operator that came before.
+ *
+ */
+@JsonDeserialize(using = De.class)
+@JsonTypeName("sequence")
+public class Sequence extends LogicalOperatorBase {
+  static final Logger logger = LoggerFactory.getLogger(Sequence.class);
+
+  private Sequence() {}
+
+  public boolean openTop;
+  public LogicalOperator input;
+  @JsonProperty("do")
+  public LogicalOperator[] stream;
+
+    @Override
+    public <T, X, E extends Throwable> T accept(LogicalVisitor<T, X, E> logicalVisitor, X value) throws E {
+        return logicalVisitor.visitSequence(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalOperator> iterator() {
+        return Iterators.singletonIterator(stream[stream.length - 1]);
+    }
+
+    public static class De extends StdDeserializer<LogicalOperator> {
+
+    protected De() {
+      super(Sequence.class);
+    }
+
+    @Override
+    public LogicalOperator deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
+        JsonProcessingException {
+      ObjectIdGenerator<Integer> idGenerator = new ObjectIdGenerators.IntSequenceGenerator();
+      JsonLocation start = jp.getCurrentLocation();
+      JsonToken t = jp.getCurrentToken();
+      LogicalOperator parent = null;
+      LogicalOperator first = null;
+      LogicalOperator prev = null;
+      Integer id = null;
+
+      while (true) {
+        String fieldName = jp.getText();
+        t = jp.nextToken();
+        switch (fieldName) { // switch on field names.
+        case "@id":
+          id = _parseIntPrimitive(jp, ctxt);
+          break;
+        case "input":
+          JavaType tp = ctxt.constructType(LogicalOperator.class);
+          JsonDeserializer<Object> d = ctxt.findRootValueDeserializer(tp);
+          parent = (LogicalOperator) d.deserialize(jp, ctxt);
+          break;
+
+        case "do":
+          if (!jp.isExpectedStartArrayToken()) {
+            throwE(
+                jp,
+                "The do parameter of sequence should be an array of SimpleOperators.  Expected a JsonToken.START_ARRAY token but received a "
+                    + t.name() + "token.");
+          }
+
+          int pos = 0;
+          while ((t = jp.nextToken()) != JsonToken.END_ARRAY) {
+            // logger.debug("Reading sequence child {}.", pos);
+            JsonLocation l = jp.getCurrentLocation(); // get current location
+                                                      // first so we can
+                                                      // correctly reference the
+                                                      // start of the object in
+                                                      // the case that the type
+                                                      // is wrong.
+            LogicalOperator o = jp.readValueAs(LogicalOperator.class);
+
+            if (pos == 0) {
+              if (!(o instanceof SingleInputOperator) && !(o instanceof SourceOperator)) {
+                throwE(
+                    l,
+                    "The first operator in a sequence must be either a ZeroInput or SingleInput operator.  The provided first operator was not. It was of type "
+                        + o.getClass().getName());
+              }
+              first = o;
+            } else {
+              if (!(o instanceof SingleInputOperator)) {
+                throwE(l, "All operators after the first must be single input operators.  The operator at position "
+                    + pos + " was not. It was of type " + o.getClass().getName());
+              }
+              SingleInputOperator now = (SingleInputOperator) o;
+              now.setInput(prev);
+            }
+            prev = o;
+
+            pos++;
+          }
+          break;
+        default:
+          throwE(jp, "Unknown field name provided for Sequence: " + jp.getText());
+        }
+
+        t = jp.nextToken();
+        if (t == JsonToken.END_OBJECT) {
+          break;
+        }
+      }
+
+      if (first == null) {
+        throwE(start, "A sequence must include at least one operator.");
+      }
+      if ((parent == null && first instanceof SingleInputOperator)
+          || (parent != null && first instanceof SourceOperator)) {
+        throwE(start,
+            "A sequence must either start with a ZeroInputOperator or have a provided input. It cannot have both or neither.");
+      }
+
+      if (parent != null && first instanceof SingleInputOperator) {
+        ((SingleInputOperator) first).setInput(parent);
+      }
+
+      // set input reference.
+      if (id != null) {
+
+        ReadableObjectId rid = ctxt.findObjectId(id, idGenerator);
+        rid.bindItem(prev);
+        // logger.debug("Binding id {} to item {}.", rid.id, rid.item);
+
+      }
+
+      return first;
+    }
+
+  }
+
+  private static void throwE(JsonLocation l, String e) throws JsonParseException {
+    throw new JsonParseException(e, l);
+  }
+
+  private static void throwE(JsonParser jp, String e) throws JsonParseException {
+    throw new JsonParseException(e, jp.getCurrentLocation());
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/SingleInputOperator.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/SingleInputOperator.java b/logical/src/main/java/org/apache/drill/common/logical/data/SingleInputOperator.java
new file mode 100644
index 0000000..e46cb6b
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/SingleInputOperator.java
@@ -0,0 +1,53 @@
+/**
+ * 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.logical.data;
+
+import java.util.Iterator;
+
+import org.apache.drill.common.logical.UnexpectedOperatorType;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.Iterators;
+
+/**
+ * SimpleOperator is an operator that has one inputs at most.
+ */
+public abstract class SingleInputOperator extends LogicalOperatorBase {
+
+  private LogicalOperator input;
+
+  @JsonProperty("input")
+  public LogicalOperator getInput() {
+    return input;
+  }
+
+  @JsonProperty(value="input", required=true)
+  public void setInput(LogicalOperator input) {
+    if (input instanceof SinkOperator) {
+      throw new UnexpectedOperatorType("You have set the input of a sink node of type ["+input.getClass().getSimpleName()+ "] as the input for another node of type ["+this.getClass().getSimpleName()+ "].  This is invalid.");
+    }
+    this.input = input;
+    input.registerAsSubscriber(this);
+  }
+
+  @Override
+  public Iterator<LogicalOperator> iterator() {
+    return Iterators.singletonIterator(input);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/SinkOperator.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/SinkOperator.java b/logical/src/main/java/org/apache/drill/common/logical/data/SinkOperator.java
new file mode 100644
index 0000000..2ca4006
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/SinkOperator.java
@@ -0,0 +1,30 @@
+/**
+ * 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.logical.data;
+
+
+/**
+ * An operator that cannot be subscribed to.
+ */
+public abstract class SinkOperator extends SingleInputOperator{
+
+  @Override
+  public void registerAsSubscriber(LogicalOperator operator) {
+    throw new UnsupportedOperationException("You can not subscribe to a sink operator such as " + this.getClass().getSimpleName());
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/SourceOperator.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/SourceOperator.java b/logical/src/main/java/org/apache/drill/common/logical/data/SourceOperator.java
new file mode 100644
index 0000000..d4f8246
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/SourceOperator.java
@@ -0,0 +1,35 @@
+/**
+ * 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.logical.data;
+
+import java.util.Iterator;
+
+import com.google.common.collect.Iterators;
+
+
+/**
+ * An operator that produces data without any parents.  (zero input operator)
+ */
+public abstract class SourceOperator extends LogicalOperatorBase{
+
+  @Override
+  public Iterator<LogicalOperator> iterator() {
+      return Iterators.emptyIterator();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/Store.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/Store.java b/logical/src/main/java/org/apache/drill/common/logical/data/Store.java
new file mode 100644
index 0000000..8f99eed
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/Store.java
@@ -0,0 +1,85 @@
+/**
+ * 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.logical.data;
+
+import java.util.Iterator;
+
+import org.apache.drill.common.JSONOptions;
+import org.apache.drill.common.logical.data.visitors.LogicalVisitor;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.google.common.collect.Iterators;
+
+@JsonTypeName("store")
+public class Store extends SinkOperator{
+  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(Store.class);
+
+  private final String storageEngine;
+  private final JSONOptions target;
+
+  @JsonCreator
+  public Store(@JsonProperty("storageengine") String storageEngine, @JsonProperty("target") JSONOptions target) {
+    super();
+    this.storageEngine = storageEngine;
+    this.target = target;
+  }
+
+  public String getStorageEngine() {
+    return storageEngine;
+  }
+
+  public JSONOptions getTarget() {
+    return target;
+  }
+
+  @Override
+  public <T, X, E extends Throwable> T accept(LogicalVisitor<T, X, E> logicalVisitor, X value) throws E {
+      return logicalVisitor.visitStore(this, value);
+  }
+
+  @Override
+  public Iterator<LogicalOperator> iterator() {
+      return Iterators.singletonIterator(getInput());
+  }
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  public static class Builder extends AbstractSingleBuilder<Store, Builder>{
+    private String storageEngine;
+    private JSONOptions target;
+
+    public Builder storageEngine(String storageEngine) {
+      this.storageEngine = storageEngine;
+      return this;
+    }
+
+    public Builder target(JSONOptions target) {
+      this.target = target;
+      return this;
+    }
+
+    @Override
+    public Store internalBuild() {
+      return new Store(storageEngine, target);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/Transform.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/Transform.java b/logical/src/main/java/org/apache/drill/common/logical/data/Transform.java
new file mode 100644
index 0000000..129ae2c
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/Transform.java
@@ -0,0 +1,54 @@
+/**
+ * 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.logical.data;
+
+import java.util.Iterator;
+
+import org.apache.drill.common.logical.data.visitors.LogicalVisitor;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.google.common.collect.Iterators;
+
+@JsonTypeName("transform")
+public class Transform extends SingleInputOperator {
+
+  private final NamedExpression[] transforms;
+
+  @JsonCreator
+  public Transform(@JsonProperty("transforms") NamedExpression[] transforms) {
+    super();
+    this.transforms = transforms;
+  }
+
+  public NamedExpression[] getTransforms() {
+    return transforms;
+  }
+
+  @Override
+  public <T, X, E extends Throwable> T accept(LogicalVisitor<T, X, E> logicalVisitor, X value) throws E {
+    return logicalVisitor.visitTransform(this, value);
+  }
+
+  @Override
+  public Iterator<LogicalOperator> iterator() {
+    return Iterators.singletonIterator(getInput());
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/Union.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/Union.java b/logical/src/main/java/org/apache/drill/common/logical/data/Union.java
new file mode 100644
index 0000000..113ffe0
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/Union.java
@@ -0,0 +1,94 @@
+/**
+ * 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.logical.data;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.drill.common.logical.data.visitors.LogicalVisitor;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
+
+@JsonTypeName("union")
+public class Union extends LogicalOperatorBase {
+  private final LogicalOperator[] inputs;
+  private final boolean distinct;
+
+//  @JsonCreator
+//  public Union(@JsonProperty("inputs") LogicalOperator[] inputs){
+//    this(inputs, false);
+//  }
+
+  @JsonCreator
+  public Union(@JsonProperty("inputs") LogicalOperator[] inputs, @JsonProperty("distinct") Boolean distinct){
+    this.inputs = inputs;
+      for (LogicalOperator o : inputs) {
+          o.registerAsSubscriber(this);
+      }
+    this.distinct = distinct == null ? false : distinct;
+  }
+
+  public LogicalOperator[] getInputs() {
+    return inputs;
+  }
+
+  public boolean isDistinct() {
+    return distinct;
+  }
+
+    @Override
+    public <T, X, E extends Throwable> T accept(LogicalVisitor<T, X, E> logicalVisitor, X value) throws E {
+        return logicalVisitor.visitUnion(this, value);
+    }
+
+    @Override
+    public Iterator<LogicalOperator> iterator() {
+        return Iterators.forArray(inputs);
+    }
+
+
+    public static Builder builder(){
+      return new Builder();
+    }
+
+    public static class Builder extends AbstractBuilder<Union>{
+      private List<LogicalOperator> inputs = Lists.newArrayList();
+      private boolean distinct;
+
+      public Builder addInput(LogicalOperator o){
+        inputs.add(o);
+        return this;
+      }
+
+      public Builder setDistinct(boolean distinct){
+        this.distinct = distinct;
+        return this;
+      }
+
+      @Override
+      public Union build() {
+        return new Union(inputs.toArray(new LogicalOperator[inputs.size()]), distinct);
+      }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/Values.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/Values.java b/logical/src/main/java/org/apache/drill/common/logical/data/Values.java
new file mode 100644
index 0000000..9276e55
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/Values.java
@@ -0,0 +1,69 @@
+/**
+ * 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.logical.data;
+
+import org.apache.drill.common.JSONOptions;
+import org.apache.drill.common.logical.data.visitors.LogicalVisitor;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.core.JsonLocation;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.base.Preconditions;
+
+@JsonTypeName("values")
+public class Values extends SourceOperator {
+
+    private final JSONOptions content;
+
+    @JsonCreator
+    public Values(@JsonProperty("content") JSONOptions content){
+        super();
+        this.content = content;
+        Preconditions.checkNotNull(content, "content attribute is required for source operator 'constant'.");
+    }
+
+    public JSONOptions getContent() {
+        return content;
+    }
+
+    @Override
+    public <T, X, E extends Throwable> T accept(LogicalVisitor<T, X, E> logicalVisitor, X value) throws E {
+      return logicalVisitor.visitValues(this, value);
+    }
+
+    public static Builder builder(){
+      return new Builder();
+    }
+
+    public static class Builder extends AbstractBuilder<Values>{
+      private JSONOptions content;
+
+      public Builder content(JsonNode n){
+        content = new JSONOptions(n, JsonLocation.NA);
+        return this;
+      }
+
+      @Override
+      public Values build() {
+        return new Values(content);
+      }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/Window.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/Window.java b/logical/src/main/java/org/apache/drill/common/logical/data/Window.java
new file mode 100644
index 0000000..0f550dc
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/Window.java
@@ -0,0 +1,120 @@
+/**
+ * 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.logical.data;
+
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
+import org.apache.drill.common.expression.FieldReference;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.logical.data.visitors.LogicalVisitor;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+@JsonTypeName("window")
+public class Window extends SingleInputOperator {
+  private final NamedExpression[] withins;
+  private final NamedExpression[] aggregations;
+  private final Order.Ordering[] orderings;
+  private final long start;
+  private final long end;
+
+
+  @JsonCreator
+  public Window(@JsonProperty("withins") NamedExpression[] withins,
+                @JsonProperty("aggregations") NamedExpression[] aggregations,
+                @JsonProperty("orderings") Order.Ordering[] orderings,
+                @JsonProperty("start") Long start,
+                @JsonProperty("end") Long end) {
+    super();
+    this.withins = withins;
+    this.start = start == null ? Long.MIN_VALUE : start;
+    this.end = end == null ? Long.MIN_VALUE : end;
+    this.aggregations = aggregations;
+    this.orderings = orderings;
+  }
+
+  public NamedExpression[] getWithins() {
+    return withins;
+  }
+
+  public long getStart() {
+    return start;
+  }
+
+  public long getEnd() {
+    return end;
+  }
+
+  public NamedExpression[] getAggregations() {
+    return aggregations;
+  }
+
+  public Order.Ordering[] getOrderings() {
+    return orderings;
+  }
+
+  @Override
+  public <T, X, E extends Throwable> T accept(LogicalVisitor<T, X, E> logicalVisitor, X value) throws E {
+    return logicalVisitor.visitWindow(this, value);
+  }
+
+  @Override
+  public Iterator<LogicalOperator> iterator() {
+    return Iterators.singletonIterator(getInput());
+  }
+
+  public static class Builder extends AbstractSingleBuilder<Window, Builder>{
+    private List<NamedExpression> aggregations = Lists.newArrayList();
+    private List<NamedExpression> withins = Lists.newArrayList();
+    private List<Order.Ordering> orderings = Lists.newArrayList();
+    private long start = Long.MIN_VALUE;
+    private long end = Long.MIN_VALUE;
+
+
+    public Builder addAggregation(FieldReference ref, LogicalExpression expr){
+      aggregations.add(new NamedExpression(expr, ref));
+      return this;
+    }
+
+    public Builder addWithin(FieldReference within, LogicalExpression expr) {
+      withins.add(new NamedExpression(expr, within));
+      return this;
+    }
+
+    public Window internalBuild() {
+      //TODO withins can actually be empty: over(), over(order by <expression>), ...
+      checkState(!withins.isEmpty(), "Withins in window must not be empty.");
+      checkState(!aggregations.isEmpty(), "Aggregations in window must not be empty.");
+      return new Window(aN(withins), aN(aggregations), aO(orderings), start, end);
+    }
+
+    public Builder addOrdering(Order.Ordering ordering) {
+      orderings.add(ordering);
+      return this;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/Writer.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/Writer.java b/logical/src/main/java/org/apache/drill/common/logical/data/Writer.java
new file mode 100644
index 0000000..6e51df7
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/Writer.java
@@ -0,0 +1,61 @@
+/**
+ * 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.logical.data;
+
+import org.apache.drill.common.logical.data.visitors.LogicalVisitor;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+
+@JsonTypeName("writer")
+public class Writer extends SingleInputOperator {
+
+  // TODO: Hack - Make the type generic until "common" and "java-exec" modules are merged (DRILL-507).
+  private final Object createTableEntry;
+
+  @JsonCreator
+  public Writer(@JsonProperty("createTableEntry") Object createTableEntry) {
+    this.createTableEntry = createTableEntry;
+  }
+
+  @Override
+  public <T, X, E extends Throwable> T accept(LogicalVisitor<T, X, E> logicalVisitor, X value) throws E {
+    return logicalVisitor.visitWriter(this, value);
+  }
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  public static class Builder extends AbstractSingleBuilder<Writer, Builder> {
+
+    // TODO: Hack - Make the type generic until "common" and "java-exec" modules are merged (DRILL-507).
+    private Object createTableEntry;
+
+    public Builder setCreateTableEntry(Object createTableEntry) {
+      this.createTableEntry = createTableEntry;
+      return this;
+    }
+
+    @Override
+    public Writer internalBuild() {
+      return new Writer(createTableEntry);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/package-info.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/package-info.java b/logical/src/main/java/org/apache/drill/common/logical/data/package-info.java
new file mode 100644
index 0000000..fc76c0d
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/package-info.java
@@ -0,0 +1,21 @@
+/**
+ * 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.
+ */
+/**
+ * Logical operators in a query graph.
+ */
+package org.apache.drill.common.logical.data;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/visitors/AbstractLogicalVisitor.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/visitors/AbstractLogicalVisitor.java b/logical/src/main/java/org/apache/drill/common/logical/data/visitors/AbstractLogicalVisitor.java
new file mode 100644
index 0000000..165ee66
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/visitors/AbstractLogicalVisitor.java
@@ -0,0 +1,126 @@
+/**
+ * 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.logical.data.visitors;
+
+import org.apache.drill.common.logical.data.Values;
+import org.apache.drill.common.logical.data.Filter;
+import org.apache.drill.common.logical.data.Flatten;
+import org.apache.drill.common.logical.data.GroupingAggregate;
+import org.apache.drill.common.logical.data.Join;
+import org.apache.drill.common.logical.data.Limit;
+import org.apache.drill.common.logical.data.LogicalOperator;
+import org.apache.drill.common.logical.data.Order;
+import org.apache.drill.common.logical.data.Project;
+import org.apache.drill.common.logical.data.RunningAggregate;
+import org.apache.drill.common.logical.data.Scan;
+import org.apache.drill.common.logical.data.Sequence;
+import org.apache.drill.common.logical.data.Store;
+import org.apache.drill.common.logical.data.Transform;
+import org.apache.drill.common.logical.data.Union;
+import org.apache.drill.common.logical.data.Window;
+import org.apache.drill.common.logical.data.Writer;
+
+
+public abstract class AbstractLogicalVisitor<T, X, E extends Throwable> implements LogicalVisitor<T, X, E> {
+
+    public T visitOp(LogicalOperator op, X value) throws E{
+        throw new UnsupportedOperationException(String.format(
+                "The LogicalVisitor of type %s does not currently support visiting the PhysicalOperator type %s.", this
+                .getClass().getCanonicalName(), op.getClass().getCanonicalName()));
+    }
+
+    @Override
+    public T visitScan(Scan scan, X value) throws E {
+        return visitOp(scan, value);
+    }
+
+    @Override
+    public T visitStore(Store store, X value) throws E {
+        return visitOp(store, value);
+    }
+
+    @Override
+    public T visitFilter(Filter filter, X value) throws E {
+        return visitOp(filter, value);
+    }
+
+    @Override
+    public T visitFlatten(Flatten flatten, X value) throws E {
+        return visitOp(flatten, value);
+    }
+
+    @Override
+    public T visitProject(Project project, X value) throws E {
+        return visitOp(project, value);
+    }
+
+    @Override
+    public T visitOrder(Order order, X value) throws E {
+        return visitOp(order, value);
+    }
+
+    @Override
+    public T visitJoin(Join join, X value) throws E {
+        return visitOp(join, value);
+    }
+
+    @Override
+    public T visitLimit(Limit limit, X value) throws E {
+        return visitOp(limit, value);
+    }
+
+    @Override
+    public T visitRunningAggregate(RunningAggregate runningAggregate, X value) throws E {
+        return visitOp(runningAggregate, value);
+    }
+
+    @Override
+    public T visitGroupingAggregate(GroupingAggregate groupBy, X value) throws E {
+      return visitOp(groupBy, value);
+    }
+
+    @Override
+    public T visitSequence(Sequence sequence, X value) throws E {
+        return visitOp(sequence, value);
+    }
+
+    @Override
+    public T visitTransform(Transform transform, X value) throws E {
+        return visitOp(transform, value);
+    }
+
+    @Override
+    public T visitUnion(Union union, X value) throws E {
+        return visitOp(union, value);
+    }
+
+    @Override
+    public T visitWindow(Window window, X value) throws E {
+        return visitOp(window, value);
+    }
+
+    @Override
+    public T visitValues(Values constant, X value) throws E {
+       return visitOp(constant, value);
+    }
+
+    @Override
+    public T visitWriter(Writer writer, X value) throws E {
+      return visitOp(writer, value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/visitors/LogicalVisitor.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/visitors/LogicalVisitor.java b/logical/src/main/java/org/apache/drill/common/logical/data/visitors/LogicalVisitor.java
new file mode 100644
index 0000000..1e07dc6
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/visitors/LogicalVisitor.java
@@ -0,0 +1,66 @@
+/**
+ * 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.logical.data.visitors;
+
+
+import org.apache.drill.common.logical.data.Values;
+import org.apache.drill.common.logical.data.Filter;
+import org.apache.drill.common.logical.data.Flatten;
+import org.apache.drill.common.logical.data.GroupingAggregate;
+import org.apache.drill.common.logical.data.Join;
+import org.apache.drill.common.logical.data.Limit;
+import org.apache.drill.common.logical.data.Order;
+import org.apache.drill.common.logical.data.Project;
+import org.apache.drill.common.logical.data.RunningAggregate;
+import org.apache.drill.common.logical.data.Scan;
+import org.apache.drill.common.logical.data.Sequence;
+import org.apache.drill.common.logical.data.Store;
+import org.apache.drill.common.logical.data.Transform;
+import org.apache.drill.common.logical.data.Union;
+import org.apache.drill.common.logical.data.Window;
+import org.apache.drill.common.logical.data.Window;
+import org.apache.drill.common.logical.data.Writer;
+
+/**
+ * Visitor class designed to traversal of a operator tree.  Basis for a number of operator manipulations including fragmentation and materialization.
+ * @param <RETURN> The class associated with the return of each visit method.
+ * @param <EXTRA> The class object associated with additional data required for a particular operator modification.
+ * @param <EXCEP> An optional exception class that can be thrown when a portion of a modification or traversal fails.  Must extend Throwable.  In the case where the visitor does not throw any caught exception, this can be set as RuntimeException.
+ */
+public interface LogicalVisitor<RETURN, EXTRA, EXCEP extends Throwable> {
+    static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(LogicalVisitor.class);
+
+
+    public RETURN visitScan(Scan scan, EXTRA value) throws EXCEP;
+    public RETURN visitStore(Store store, EXTRA value) throws EXCEP;
+    public RETURN visitGroupingAggregate(GroupingAggregate groupBy, EXTRA value) throws EXCEP;
+    public RETURN visitFilter(Filter filter, EXTRA value) throws EXCEP;
+    public RETURN visitFlatten(Flatten flatten, EXTRA value) throws EXCEP;
+
+    public RETURN visitProject(Project project, EXTRA value) throws EXCEP;
+    public RETURN visitValues(Values constant, EXTRA value) throws EXCEP;
+    public RETURN visitOrder(Order order, EXTRA value) throws EXCEP;
+    public RETURN visitJoin(Join join, EXTRA value) throws EXCEP;
+    public RETURN visitLimit(Limit limit, EXTRA value) throws EXCEP;
+    public RETURN visitRunningAggregate(RunningAggregate runningAggregate, EXTRA value) throws EXCEP;
+    public RETURN visitSequence(Sequence sequence, EXTRA value) throws EXCEP;
+    public RETURN visitTransform(Transform transform, EXTRA value) throws EXCEP;
+    public RETURN visitUnion(Union union, EXTRA value) throws EXCEP;
+    public RETURN visitWindow(Window window, EXTRA value) throws EXCEP;
+    public RETURN visitWriter(Writer writer, EXTRA value) throws EXCEP;
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/data/visitors/package-info.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/data/visitors/package-info.java b/logical/src/main/java/org/apache/drill/common/logical/data/visitors/package-info.java
new file mode 100644
index 0000000..9b82bb3
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/data/visitors/package-info.java
@@ -0,0 +1,21 @@
+/**
+ * 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.
+ */
+/**
+ * Visitors for Drill logical plan graphs.
+ */
+package org.apache.drill.common.logical.data.visitors;

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/logical/package-info.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/logical/package-info.java b/logical/src/main/java/org/apache/drill/common/logical/package-info.java
new file mode 100644
index 0000000..1f88f06
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/logical/package-info.java
@@ -0,0 +1,25 @@
+/**
+ * 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.
+ */
+/**
+ * Storage plugin interfaces and logical plan representation.
+ *
+ * This package includes the interface for storage and format plugins for Drill
+ * as well as the top level class for representing a Drill logical plan and a
+ * builder for constructing plans.
+ */
+package org.apache.drill.common.logical;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/main/java/org/apache/drill/common/util/AbstractDynamicBean.java
----------------------------------------------------------------------
diff --git a/logical/src/main/java/org/apache/drill/common/util/AbstractDynamicBean.java b/logical/src/main/java/org/apache/drill/common/util/AbstractDynamicBean.java
new file mode 100644
index 0000000..07a3620
--- /dev/null
+++ b/logical/src/main/java/org/apache/drill/common/util/AbstractDynamicBean.java
@@ -0,0 +1,81 @@
+/**
+ * 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 java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.drill.common.exceptions.LogicalPlanParsingException;
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.core.JsonParser.Feature;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Captures all properties and turns them into an object node for late bind conversion.
+ */
+public abstract class AbstractDynamicBean {
+  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(AbstractDynamicBean.class);
+
+  private static volatile ObjectMapper MAPPER;
+
+  private ObjectNode objectNode = new ObjectNode(null);
+
+  @JsonAnySetter
+  public void _anySetter(String name, JsonNode value){
+    objectNode.put(name, value);
+  }
+
+  @JsonAnyGetter
+  public Map<String,JsonNode> _anyGetter() {
+    Map<String, JsonNode> unknowns = new HashMap<String, JsonNode>();
+
+    for(Iterator<Entry<String, JsonNode>> i = objectNode.fields(); i.hasNext(); ){
+      Entry<String, JsonNode> e = i.next();
+      unknowns.put(e.getKey(), e.getValue());
+    }
+    return unknowns;
+  }
+
+  public <T> T getWith(Class<T> c){
+    try {
+      return getMapper().treeToValue(objectNode, c);
+    } catch (JsonProcessingException e) {
+      throw new LogicalPlanParsingException(String.format("Failure while trying to convert late bound json type to type of %s.", c.getCanonicalName()), e);
+    }
+  }
+
+
+  private static synchronized ObjectMapper getMapper(){
+    if(MAPPER == null){
+      ObjectMapper mapper = new ObjectMapper();
+      mapper.enable(SerializationFeature.INDENT_OUTPUT);
+      mapper.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
+      mapper.configure(Feature.ALLOW_COMMENTS, true);
+      MAPPER = mapper;
+    }
+    return MAPPER;
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/44dea433/logical/src/test/java/org/apache/drill/common/expression/PathSegmentTests.java
----------------------------------------------------------------------
diff --git a/logical/src/test/java/org/apache/drill/common/expression/PathSegmentTests.java b/logical/src/test/java/org/apache/drill/common/expression/PathSegmentTests.java
new file mode 100644
index 0000000..97cd578
--- /dev/null
+++ b/logical/src/test/java/org/apache/drill/common/expression/PathSegmentTests.java
@@ -0,0 +1,46 @@
+/**
+ * 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.expression;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.drill.test.DrillTest;
+import org.junit.Test;
+
+public class PathSegmentTests extends DrillTest {
+  protected PathSegment makeArraySegment(final int len, final PathSegment tail) {
+    PathSegment node = tail;
+    for (int i = 0; i < len; i++) {
+      node = new PathSegment.ArraySegment(node);
+    }
+    return node;
+  }
+
+  @Test
+  public void testIfMultiLevelCloneWorks() {
+    final int levels = 10;
+    final PathSegment segment = new PathSegment.NameSegment("test", makeArraySegment(levels, null));
+    final PathSegment clone = segment.clone();
+    assertEquals("result of clone & original segments must be identical", segment, clone);
+
+    final PathSegment tail = new PathSegment.NameSegment("tail");
+    final PathSegment newSegment = new PathSegment.NameSegment("test", makeArraySegment(levels, tail));
+    final PathSegment newClone = segment.cloneWithNewChild(tail);
+    assertEquals("result of cloneWithChild & original segment must be identical", newSegment, newClone);
+  }
+}