drill-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jacq...@apache.org
Subject [14/38] DRILL-257: Move SQL parsing to server side. Switch to Avatica based JDBC driver. Update QuerySubmitter to support SQL queries. Update SqlAccesors to support getObject() Remove ref, clean up SQL packages some. Various performance fixes. Updating
Date Tue, 04 Mar 2014 08:07:41 GMT
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillAggregateRel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillAggregateRel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillAggregateRel.java
new file mode 100644
index 0000000..b4c1bf9
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillAggregateRel.java
@@ -0,0 +1,108 @@
+/**
+ * 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.planner.logical;
+
+import java.util.BitSet;
+import java.util.List;
+
+import net.hydromatic.linq4j.Ord;
+import net.hydromatic.optiq.util.BitSets;
+
+import org.apache.drill.common.expression.ExpressionPosition;
+import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.expression.ValueExpressions;
+import org.apache.drill.common.logical.data.GroupingAggregate;
+import org.apache.drill.common.logical.data.LogicalOperator;
+import org.apache.drill.exec.planner.torel.ConversionContext;
+import org.eigenbase.rel.AggregateCall;
+import org.eigenbase.rel.AggregateRelBase;
+import org.eigenbase.rel.InvalidRelException;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.RelOptCluster;
+import org.eigenbase.relopt.RelTraitSet;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Aggregation implemented in Drill.
+ */
+public class DrillAggregateRel extends AggregateRelBase implements DrillRel {
+  /** Creates a DrillAggregateRel. */
+  public DrillAggregateRel(RelOptCluster cluster, RelTraitSet traits, RelNode child, BitSet groupSet,
+      List<AggregateCall> aggCalls) throws InvalidRelException {
+    super(cluster, traits, child, groupSet, aggCalls);
+    for (AggregateCall aggCall : aggCalls) {
+      if (aggCall.isDistinct()) {
+        throw new InvalidRelException("DrillAggregateRel does not support DISTINCT aggregates");
+      }
+    }
+  }
+
+  @Override
+  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
+    try {
+      return new DrillAggregateRel(getCluster(), traitSet, sole(inputs), getGroupSet(), aggCalls);
+    } catch (InvalidRelException e) {
+      throw new AssertionError(e);
+    }
+  }
+
+  @Override
+  public LogicalOperator implement(DrillImplementor implementor) {
+
+    GroupingAggregate.Builder builder = GroupingAggregate.builder();
+    builder.setInput(implementor.visitChild(this, 0, getChild()));
+    final List<String> childFields = getChild().getRowType().getFieldNames();
+    final List<String> fields = getRowType().getFieldNames();
+
+    for (int group : BitSets.toIter(groupSet)) {
+      FieldReference fr = new FieldReference(childFields.get(group), ExpressionPosition.UNKNOWN);
+      builder.addKey(fr, fr);
+    }
+    
+    for (Ord<AggregateCall> aggCall : Ord.zip(aggCalls)) {
+      FieldReference ref = new FieldReference(fields.get(groupSet.cardinality() + aggCall.i));
+      LogicalExpression expr = toDrill(aggCall.e, childFields, implementor);
+      builder.addExpr(ref, expr);
+    }
+    
+    return builder.build();
+  }
+
+  
+  
+  
+  private LogicalExpression toDrill(AggregateCall call, List<String> fn, DrillImplementor implementor) {
+    List<LogicalExpression> args = Lists.newArrayList();
+    for(Integer i : call.getArgList()){
+      args.add(new FieldReference(fn.get(i)));
+    }
+    
+    // for count(1).
+    if(args.isEmpty()) args.add(new ValueExpressions.LongExpression(1l));
+    LogicalExpression expr = implementor.getContext().getRegistry().createExpression(call.getAggregation().getName().toLowerCase(), ExpressionPosition.UNKNOWN, args);
+    return expr;
+  }
+  
+  public static DrillAggregateRel convert(GroupingAggregate groupBy, ConversionContext value)
+      throws InvalidRelException {
+    throw new UnsupportedOperationException();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillAggregateRule.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillAggregateRule.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillAggregateRule.java
new file mode 100644
index 0000000..77f1ba6
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillAggregateRule.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.exec.planner.logical;
+
+import org.eigenbase.rel.AggregateRel;
+import org.eigenbase.rel.InvalidRelException;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.*;
+import org.eigenbase.trace.EigenbaseTrace;
+
+import java.util.logging.Logger;
+
+/**
+ * Rule that converts an {@link AggregateRel} to a {@link DrillAggregateRel}, implemented by a Drill "segment" operation
+ * followed by a "collapseaggregate" operation.
+ */
+public class DrillAggregateRule extends RelOptRule {
+  public static final RelOptRule INSTANCE = new DrillAggregateRule();
+  protected static final Logger tracer = EigenbaseTrace.getPlannerTracer();
+
+  private DrillAggregateRule() {
+    super(RelOptHelper.some(AggregateRel.class, Convention.NONE, RelOptHelper.any(RelNode.class)), "DrillAggregateRule");
+  }
+
+  @Override
+  public void onMatch(RelOptRuleCall call) {
+    final AggregateRel aggregate = (AggregateRel) call.rel(0);
+    final RelNode input = call.rel(1);
+    final RelTraitSet traits = aggregate.getTraitSet().plus(DrillRel.CONVENTION);
+    final RelNode convertedInput = convert(input, traits);
+    try {
+      call.transformTo(new DrillAggregateRel(aggregate.getCluster(), traits, convertedInput, aggregate.getGroupSet(),
+          aggregate.getAggCallList()));
+    } catch (InvalidRelException e) {
+      tracer.warning(e.toString());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillFilterRel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillFilterRel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillFilterRel.java
new file mode 100644
index 0000000..cc147e3
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillFilterRel.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.exec.planner.logical;
+
+import java.util.List;
+
+import org.apache.drill.common.logical.data.Filter;
+import org.apache.drill.common.logical.data.LogicalOperator;
+import org.apache.drill.exec.planner.torel.ConversionContext;
+import org.eigenbase.rel.FilterRelBase;
+import org.eigenbase.rel.InvalidRelException;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.RelOptCluster;
+import org.eigenbase.relopt.RelOptCost;
+import org.eigenbase.relopt.RelOptPlanner;
+import org.eigenbase.relopt.RelTraitSet;
+import org.eigenbase.rex.RexNode;
+
+/**
+ * Filter implemented in Drill.
+ */
+public class DrillFilterRel extends FilterRelBase implements DrillRel {
+  protected DrillFilterRel(RelOptCluster cluster, RelTraitSet traits, RelNode child, RexNode condition) {
+    super(cluster, traits, child, condition);
+    assert getConvention() == CONVENTION;
+  }
+
+  @Override
+  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
+    return new DrillFilterRel(getCluster(), traitSet, sole(inputs), getCondition());
+  }
+
+  @Override
+  public RelOptCost computeSelfCost(RelOptPlanner planner) {
+    return super.computeSelfCost(planner).multiplyBy(0.1);
+  }
+
+  @Override
+  public LogicalOperator implement(DrillImplementor implementor) {
+    final LogicalOperator input = implementor.visitChild(this, 0, getChild());
+    Filter f = new Filter(DrillOptiq.toDrill(implementor.getContext(), getChild(), getCondition()));
+    f.setInput(input);
+    return f;
+  }
+  
+  public static DrillFilterRel convert(Filter filter, ConversionContext context) throws InvalidRelException{
+    RelNode input = context.toRel(filter.getInput());
+    return new DrillFilterRel(context.getCluster(), context.getLogicalTraits(), input, context.toRex(filter.getExpr()));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillFilterRule.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillFilterRule.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillFilterRule.java
new file mode 100644
index 0000000..d4fb239
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillFilterRule.java
@@ -0,0 +1,42 @@
+/**
+ * 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.planner.logical;
+
+import org.eigenbase.rel.FilterRel;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.*;
+
+/**
+ * Rule that converts a {@link org.eigenbase.rel.FilterRel} to a Drill "filter" operation.
+ */
+public class DrillFilterRule extends RelOptRule {
+  public static final RelOptRule INSTANCE = new DrillFilterRule();
+
+  private DrillFilterRule() {
+    super(RelOptHelper.some(FilterRel.class, Convention.NONE, RelOptHelper.any(RelNode.class)), "DrillFilterRule");
+  }
+
+  @Override
+  public void onMatch(RelOptRuleCall call) {
+    final FilterRel filter = (FilterRel) call.rel(0);
+    final RelNode input = call.rel(1);
+    final RelTraitSet traits = filter.getTraitSet().plus(DrillRel.CONVENTION);
+    final RelNode convertedInput = convert(input, traits);
+    call.transformTo(new DrillFilterRel(filter.getCluster(), traits, convertedInput, filter.getCondition()));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillImplementor.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillImplementor.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillImplementor.java
new file mode 100644
index 0000000..acd218c
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillImplementor.java
@@ -0,0 +1,88 @@
+/**
+ * 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.planner.logical;
+
+import java.util.Set;
+
+import org.apache.drill.common.logical.LogicalPlan;
+import org.apache.drill.common.logical.LogicalPlanBuilder;
+import org.apache.drill.common.logical.PlanProperties.Generator.ResultMode;
+import org.apache.drill.common.logical.PlanProperties.PlanType;
+import org.apache.drill.common.logical.data.LogicalOperator;
+import org.apache.drill.common.logical.data.visitors.AbstractLogicalVisitor;
+import org.eigenbase.rel.RelNode;
+
+import com.google.common.collect.Sets;
+
+/**
+ * Context for converting a tree of {@link DrillRel} nodes into a Drill logical plan.
+ */
+public class DrillImplementor {
+  
+  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillImplementor.class);
+  
+  private Set<DrillTable> tables = Sets.newHashSet();
+  private LogicalPlanBuilder planBuilder = new LogicalPlanBuilder();
+  private LogicalPlan plan;
+  private final DrillParseContext context;
+  
+  
+  public DrillImplementor(DrillParseContext context, ResultMode mode) {
+    planBuilder.planProperties(PlanType.APACHE_DRILL_LOGICAL, 1, DrillImplementor.class.getName(), "", mode);
+    this.context = context;
+  }
+  
+  public DrillParseContext getContext(){
+    return context;
+  }
+
+  public void registerSource(DrillTable table){
+    if(tables.add(table)){
+      planBuilder.addStorageEngine(table.getStorageEngineName(), table.getStorageEngineConfig());
+    }
+  }
+
+  public void go(DrillRel root) {
+    LogicalOperator rootLOP = root.implement(this);
+    rootLOP.accept(new AddOpsVisitor(), null);
+  }
+  
+  public LogicalPlan getPlan(){
+    if(plan == null){
+      plan = planBuilder.build();
+      planBuilder = null;
+    }
+    return plan;
+  }
+
+  public LogicalOperator visitChild(DrillRel parent, int ordinal, RelNode child) {
+    return ((DrillRel) child).implement(this);
+  }
+  
+  private class AddOpsVisitor extends AbstractLogicalVisitor<Void, Void, RuntimeException> {
+    @Override
+    public Void visitOp(LogicalOperator op, Void value) throws RuntimeException {
+      planBuilder.addLogicalOperator(op);
+      for(LogicalOperator o : op){
+        o.accept(this, null);
+      }
+      return null;
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRel.java
new file mode 100644
index 0000000..c08712e
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRel.java
@@ -0,0 +1,165 @@
+/**
+ * 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.planner.logical;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+
+import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.logical.data.Join;
+import org.apache.drill.common.logical.data.JoinCondition;
+import org.apache.drill.common.logical.data.LogicalOperator;
+import org.apache.drill.common.logical.data.Project;
+import org.apache.drill.exec.planner.torel.ConversionContext;
+import org.eigenbase.rel.InvalidRelException;
+import org.eigenbase.rel.JoinRelBase;
+import org.eigenbase.rel.JoinRelType;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.RelOptCluster;
+import org.eigenbase.relopt.RelOptUtil;
+import org.eigenbase.relopt.RelTraitSet;
+import org.eigenbase.reltype.RelDataType;
+import org.eigenbase.reltype.RelDataTypeField;
+import org.eigenbase.rex.RexNode;
+import org.eigenbase.rex.RexUtil;
+import org.eigenbase.sql.fun.SqlStdOperatorTable;
+import org.eigenbase.util.Pair;
+
+/**
+ * Join implemented in Drill.
+ */
+public class DrillJoinRel extends JoinRelBase implements DrillRel {
+  private final List<Integer> leftKeys = new ArrayList<>();
+  private final List<Integer> rightKeys = new ArrayList<>();
+
+  /** Creates a DrillJoinRel. */
+  public DrillJoinRel(RelOptCluster cluster, RelTraitSet traits, RelNode left, RelNode right, RexNode condition,
+      JoinRelType joinType) throws InvalidRelException {
+    super(cluster, traits, left, right, condition, joinType, Collections.<String> emptySet());
+
+    RexNode remaining = RelOptUtil.splitJoinCondition(left, right, condition, leftKeys, rightKeys);
+    if (!remaining.isAlwaysTrue()) {
+      throw new InvalidRelException("DrillJoinRel only supports equi-join");
+    }
+  }
+  
+  @Override
+  public DrillJoinRel copy(RelTraitSet traitSet, RexNode condition, RelNode left, RelNode right, JoinRelType joinType) {
+    try {
+      return new DrillJoinRel(getCluster(), traitSet, left, right, condition, joinType);
+    } catch (InvalidRelException e) {
+      throw new AssertionError(e);
+    }
+  }
+
+  @Override
+  public LogicalOperator implement(DrillImplementor implementor) {
+    final List<String> fields = getRowType().getFieldNames();
+    assert isUnique(fields);
+    final int leftCount = left.getRowType().getFieldCount();
+    final List<String> leftFields = fields.subList(0, leftCount);
+    final List<String> rightFields = fields.subList(leftCount, fields.size());
+
+    final LogicalOperator leftOp = implementInput(implementor, 0, 0, left);
+    final LogicalOperator rightOp = implementInput(implementor, 1, leftCount, right);
+
+    Join.Builder builder = Join.builder();
+    builder.type(joinType);
+    builder.left(leftOp);
+    builder.right(rightOp);
+    
+    for (Pair<Integer, Integer> pair : Pair.zip(leftKeys, rightKeys)) {
+      builder.addCondition("==", new FieldReference(leftFields.get(pair.left)), new FieldReference(rightFields.get(pair.right)));
+    }
+    return builder.build();
+  }
+
+  /**
+   * Check to make sure that the fields of the inputs are the same as the output field names.  If not, insert a project renaming them.
+   * @param implementor
+   * @param i
+   * @param offset
+   * @param input
+   * @return
+   */
+  private LogicalOperator implementInput(DrillImplementor implementor, int i, int offset, RelNode input) {
+    final LogicalOperator inputOp = implementor.visitChild(this, i, input);
+    assert uniqueFieldNames(input.getRowType());
+    final List<String> fields = getRowType().getFieldNames();
+    final List<String> inputFields = input.getRowType().getFieldNames();
+    final List<String> outputFields = fields.subList(offset, offset + inputFields.size());
+    if (!outputFields.equals(inputFields)) {
+      // Ensure that input field names are the same as output field names.
+      // If there are duplicate field names on left and right, fields will get
+      // lost.
+      return rename(implementor, inputOp, inputFields, outputFields);
+    } else {
+      return inputOp;
+    }
+  }
+
+  private LogicalOperator rename(DrillImplementor implementor, LogicalOperator inputOp, List<String> inputFields, List<String> outputFields) {
+    Project.Builder builder = Project.builder();
+    builder.setInput(inputOp);
+    for (Pair<String, String> pair : Pair.zip(inputFields, outputFields)) {
+      builder.addExpr(new FieldReference(pair.right), new FieldReference(pair.left));
+    }
+    return builder.build();
+  }
+
+  public static DrillJoinRel convert(Join join, ConversionContext context) throws InvalidRelException{
+    RelNode left = context.toRel(join.getLeft());
+    RelNode right = context.toRel(join.getRight());
+    
+    List<RexNode> joinConditions = new ArrayList<RexNode>();
+    // right fields appear after the LHS fields.
+    final int rightInputOffset = left.getRowType().getFieldCount();
+    for (JoinCondition condition : join.getConditions()) {
+      RelDataTypeField leftField = left.getRowType().getField(ExprHelper.getFieldName(condition.getLeft()), true);
+      RelDataTypeField rightField = right.getRowType().getField(ExprHelper.getFieldName(condition.getRight()), true);
+        joinConditions.add(
+            context.getRexBuilder().makeCall(
+                SqlStdOperatorTable.EQUALS,
+                context.getRexBuilder().makeInputRef(leftField.getType(), leftField.getIndex()),
+                context.getRexBuilder().makeInputRef(rightField.getType(), rightInputOffset + rightField.getIndex())
+                )
+                );
+    }
+    RexNode rexCondition = RexUtil.composeConjunction(context.getRexBuilder(), joinConditions, false);
+    return new DrillJoinRel(context.getCluster(), context.getLogicalTraits(), left, right, rexCondition, join.getJoinType());
+  }
+  
+  
+  /**
+   * Returns whether there are any elements in common between left and right.
+   */
+  private static <T> boolean intersects(List<T> left, List<T> right) {
+    return new HashSet<>(left).removeAll(right);
+  }
+
+  private boolean uniqueFieldNames(RelDataType rowType) {
+    return isUnique(rowType.getFieldNames());
+  }
+
+  private static <T> boolean isUnique(List<T> list) {
+    return new HashSet<>(list).size() == list.size();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRule.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRule.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRule.java
new file mode 100644
index 0000000..f32fa59
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRule.java
@@ -0,0 +1,57 @@
+/**
+ * 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.planner.logical;
+
+import org.eigenbase.rel.InvalidRelException;
+import org.eigenbase.rel.JoinRel;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.*;
+import org.eigenbase.trace.EigenbaseTrace;
+
+import java.util.logging.Logger;
+
+/**
+ * Rule that converts a {@link JoinRel} to a {@link DrillJoinRel}, which is implemented by Drill "join" operation.
+ */
+public class DrillJoinRule extends RelOptRule {
+  public static final RelOptRule INSTANCE = new DrillJoinRule();
+  protected static final Logger tracer = EigenbaseTrace.getPlannerTracer();
+
+  private DrillJoinRule() {
+    super(
+        RelOptHelper.some(JoinRel.class, Convention.NONE, RelOptHelper.any(RelNode.class), RelOptHelper.any(RelNode.class)),
+        "DrillJoinRule");
+  }
+
+  @Override
+  public void onMatch(RelOptRuleCall call) {
+    final JoinRel join = (JoinRel) call.rel(0);
+    final RelNode left = call.rel(1);
+    final RelNode right = call.rel(2);
+    final RelTraitSet traits = join.getTraitSet().plus(DrillRel.CONVENTION);
+
+    final RelNode convertedLeft = convert(left, traits);
+    final RelNode convertedRight = convert(right, traits);
+    try {
+      call.transformTo(new DrillJoinRel(join.getCluster(), traits, convertedLeft, convertedRight, join.getCondition(),
+          join.getJoinType()));
+    } catch (InvalidRelException e) {
+      tracer.warning(e.toString());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillLimitRel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillLimitRel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillLimitRel.java
new file mode 100644
index 0000000..54be052
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillLimitRel.java
@@ -0,0 +1,73 @@
+/**
+ * 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.planner.logical;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import org.apache.drill.common.logical.data.Limit;
+import org.apache.drill.common.logical.data.LogicalOperator;
+import org.apache.drill.exec.planner.torel.ConversionContext;
+import org.eigenbase.rel.InvalidRelException;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.rel.SingleRel;
+import org.eigenbase.relopt.RelOptCluster;
+import org.eigenbase.relopt.RelTraitSet;
+import org.eigenbase.rex.RexLiteral;
+import org.eigenbase.rex.RexNode;
+import org.eigenbase.sql.type.SqlTypeName;
+
+public class DrillLimitRel extends SingleRel implements DrillRel {
+  private RexNode offset;
+  private RexNode fetch;
+
+  public DrillLimitRel(RelOptCluster cluster, RelTraitSet traitSet, RelNode child, RexNode offset, RexNode fetch) {
+    super(cluster, traitSet, child);
+    this.offset = offset;
+    this.fetch = fetch;
+  }
+
+  @Override
+  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
+    return new DrillLimitRel(getCluster(), traitSet, sole(inputs), offset, fetch);
+  }
+
+  @Override
+  public LogicalOperator implement(DrillImplementor implementor) {
+    LogicalOperator inputOp = implementor.visitChild(this, 0, getChild());
+    
+    // First offset to include into results (inclusive). Null implies it is starting from offset 0
+    int first = offset != null ? Math.max(0, RexLiteral.intValue(offset)) : 0;
+
+    // Last offset to stop including into results (exclusive), translating fetch row counts into an offset.
+    // Null value implies including entire remaining result set from first offset
+    Integer last = fetch != null ? Math.max(0, RexLiteral.intValue(fetch)) + first : null;
+    Limit limit = new Limit(first, last);
+    limit.setInput(inputOp);
+    return limit;
+  }
+  
+  public static DrillLimitRel convert(Limit limit, ConversionContext context) throws InvalidRelException{
+    RelNode input = context.toRel(limit.getInput());
+    RexNode first = context.getRexBuilder().makeExactLiteral(BigDecimal.valueOf(limit.getFirst()), context.getTypeFactory().createSqlType(SqlTypeName.INTEGER));
+    RexNode last = context.getRexBuilder().makeExactLiteral(BigDecimal.valueOf(limit.getLast()), context.getTypeFactory().createSqlType(SqlTypeName.INTEGER));
+    return new DrillLimitRel(context.getCluster(), context.getLogicalTraits(), input, first, last);
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillLimitRule.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillLimitRule.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillLimitRule.java
new file mode 100644
index 0000000..85c594e
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillLimitRule.java
@@ -0,0 +1,59 @@
+/**
+ * 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.planner.logical;
+
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.rel.SortRel;
+import org.eigenbase.relopt.Convention;
+import org.eigenbase.relopt.RelOptRule;
+import org.eigenbase.relopt.RelOptRuleCall;
+import org.eigenbase.relopt.RelTraitSet;
+
+/**
+ * This rule converts a SortRel that has either a offset and fetch into a Drill Sort and Limit Rel
+ */
+public class DrillLimitRule extends RelOptRule {
+  public static DrillLimitRule INSTANCE = new DrillLimitRule();
+
+  private DrillLimitRule() {
+    super(RelOptHelper.some(SortRel.class, Convention.NONE, RelOptHelper.any(RelNode.class)), "DrillLimitRule");
+  }
+
+  @Override
+  public boolean matches(RelOptRuleCall call) {
+    final SortRel sort = call.rel(0);
+    return sort.offset != null || sort.fetch != null;
+  }
+
+  @Override
+  public void onMatch(RelOptRuleCall call) {
+    final SortRel incomingSort = call.rel(0);
+    final RelTraitSet incomingTraits = incomingSort.getTraitSet();
+    RelNode input = incomingSort.getChild();
+
+    // if the Optiq sort rel includes a collation and a limit, we need to create a copy the sort rel that excludes the
+    // limit information.
+    if (!incomingSort.getCollation().getFieldCollations().isEmpty()) {
+      input = incomingSort.copy(incomingTraits, input, incomingSort.getCollation(), null, null);
+    }
+
+    RelNode convertedInput = convert(input, input.getTraitSet().plus(DrillRel.CONVENTION));
+    call.transformTo(new DrillLimitRel(incomingSort.getCluster(), incomingTraits.plus(DrillRel.CONVENTION), convertedInput, incomingSort.offset, incomingSort.fetch));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
new file mode 100644
index 0000000..2e29bd4
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillOptiq.java
@@ -0,0 +1,200 @@
+/**
+ * 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.planner.logical;
+
+import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.expression.SchemaPath;
+import org.apache.drill.common.expression.ValueExpressions;
+import org.apache.drill.common.expression.ValueExpressions.LongExpression;
+import org.apache.drill.exec.record.NullExpression;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.RelOptPlanner;
+import org.eigenbase.reltype.RelDataTypeField;
+import org.eigenbase.rex.RexCall;
+import org.eigenbase.rex.RexCorrelVariable;
+import org.eigenbase.rex.RexDynamicParam;
+import org.eigenbase.rex.RexFieldAccess;
+import org.eigenbase.rex.RexInputRef;
+import org.eigenbase.rex.RexLiteral;
+import org.eigenbase.rex.RexLocalRef;
+import org.eigenbase.rex.RexNode;
+import org.eigenbase.rex.RexOver;
+import org.eigenbase.rex.RexRangeRef;
+import org.eigenbase.rex.RexVisitorImpl;
+import org.eigenbase.sql.SqlSyntax;
+import org.eigenbase.sql.fun.SqlStdOperatorTable;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Utilities for Drill's planner.
+ */
+public class DrillOptiq {
+  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillOptiq.class);
+  
+  /**
+   * Converts a tree of {@link RexNode} operators into a scalar expression in Drill syntax.
+   */
+  static LogicalExpression toDrill(DrillParseContext context, RelNode input, RexNode expr) {
+    final RexToDrill visitor = new RexToDrill(context, input);
+    return expr.accept(visitor);
+  }
+
+  private static class RexToDrill extends RexVisitorImpl<LogicalExpression> {
+    private final RelNode input;
+    private final DrillParseContext context;
+    
+    RexToDrill(DrillParseContext context, RelNode input) {
+      super(true);
+      this.context = context;
+      this.input = input;
+    }
+
+    @Override
+    public LogicalExpression visitInputRef(RexInputRef inputRef) {
+      final int index = inputRef.getIndex();
+      final RelDataTypeField field = input.getRowType().getFieldList().get(index);
+      return new FieldReference(field.getName());
+    }
+    
+    @Override
+    public LogicalExpression visitCall(RexCall call) {
+      logger.debug("RexCall {}, {}", call);
+      final SqlSyntax syntax = call.getOperator().getSyntax();
+      switch (syntax) {
+      case BINARY:
+        logger.debug("Binary");
+        LogicalExpression op1 = call.getOperands().get(0).accept(this);
+        LogicalExpression op2 = call.getOperands().get(1).accept(this);
+        return context.getRegistry().createExpression(call.getOperator().getName(), Lists.newArrayList(op1, op2));
+      case FUNCTION:
+        logger.debug("Function");
+        List<LogicalExpression> exprs = Lists.newArrayList();
+        for(RexNode n : call.getOperands()){
+          exprs.add(n.accept(this));
+        }
+        return context.getRegistry().createExpression(call.getOperator().getName().toLowerCase(), Lists.newArrayList(exprs));
+      case SPECIAL:
+        logger.debug("Special");
+        switch(call.getKind()){
+          
+        case CAST:
+          return getDrillCastFunctionFromOptiq(call);
+        }
+        
+        if (call.getOperator() == SqlStdOperatorTable.ITEM) {
+          SchemaPath left = (SchemaPath) call.getOperands().get(0).accept(this);
+          final RexLiteral literal = (RexLiteral) call.getOperands().get(1);
+          return left.getChild((String) literal.getValue2());
+        }
+        
+        // fall through
+      default:
+        throw new AssertionError("todo: implement syntax " + syntax + "(" + call + ")");
+      }
+    }
+
+    private LogicalExpression doUnknown(Object o){
+      logger.warn("Doesn't currently support consumption of {}.", o);
+      return NullExpression.INSTANCE;
+    }
+    @Override
+    public LogicalExpression visitLocalRef(RexLocalRef localRef) {
+      return doUnknown(localRef);
+    }
+
+    @Override
+    public LogicalExpression visitOver(RexOver over) {
+      return doUnknown(over);
+    }
+
+    @Override
+    public LogicalExpression visitCorrelVariable(RexCorrelVariable correlVariable) {
+      return doUnknown(correlVariable);
+    }
+
+    @Override
+    public LogicalExpression visitDynamicParam(RexDynamicParam dynamicParam) {
+      return doUnknown(dynamicParam);
+    }
+
+    @Override
+    public LogicalExpression visitRangeRef(RexRangeRef rangeRef) {
+      return doUnknown(rangeRef);
+    }
+
+    @Override
+    public LogicalExpression visitFieldAccess(RexFieldAccess fieldAccess) {
+      return super.visitFieldAccess(fieldAccess);
+    }
+
+
+    private LogicalExpression getDrillCastFunctionFromOptiq(RexCall call){
+      LogicalExpression arg = call.getOperands().get(0).accept(this);
+      List<LogicalExpression> args = Collections.singletonList(arg);
+      String fname = null;
+      switch(call.getType().getSqlTypeName().getName()){
+      case "VARCHAR": {
+        args = Lists.newArrayList(arg, new LongExpression(call.getType().getPrecision()));
+        return context.getRegistry().createExpression("castVARCHAR", args);
+      }
+      case "INTEGER": fname = "castINT"; break;
+      case "FLOAT": fname = "castFLOAT4"; break;
+      case "DOUBLE": fname = "castFLOAT8"; break;
+      case "DECIMAL": throw new UnsupportedOperationException("Need to add decimal.");
+      default: fname = "cast" + call.getType().getSqlTypeName().getName();
+      }
+      return context.getRegistry().createExpression(fname, args);
+
+    }
+    
+    
+
+    @Override
+    public LogicalExpression visitLiteral(RexLiteral literal) {
+      switch(literal.getTypeName()){
+      case BIGINT:
+        long l = ((BigDecimal) literal.getValue()).longValue();
+        return ValueExpressions.getBigInt(l);
+      case BOOLEAN:
+        return ValueExpressions.getBit(((Boolean) literal.getValue()));
+      case CHAR:
+        return ValueExpressions.getChar(((String) literal.getValue()));
+      case DOUBLE:
+        double d = ((BigDecimal) literal.getValue()).doubleValue();
+        return ValueExpressions.getFloat8(d);
+      case FLOAT:
+        float f = ((BigDecimal) literal.getValue()).floatValue();
+        return ValueExpressions.getFloat4(f);
+      case INTEGER:
+      case DECIMAL:
+        int i = ((BigDecimal) literal.getValue()).intValue();
+        return ValueExpressions.getInt(i);
+      case VARCHAR:
+        return ValueExpressions.getChar(((String) literal.getValue()));
+      default:
+        throw new UnsupportedOperationException(String.format("Unable to convert the value of %s and type %s to a Drill constant expression.", literal, literal.getTypeName()));
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillParseContext.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillParseContext.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillParseContext.java
new file mode 100644
index 0000000..b82fef5
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillParseContext.java
@@ -0,0 +1,36 @@
+/**
+ * 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.planner.logical;
+
+import org.apache.drill.common.expression.FunctionRegistry;
+
+public class DrillParseContext {
+  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillParseContext.class);
+  
+  private final FunctionRegistry registry;
+  
+  public DrillParseContext(FunctionRegistry registry) {
+    super();
+    this.registry = registry;
+  }
+
+  public FunctionRegistry getRegistry(){
+    return registry;
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillProjectRel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillProjectRel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillProjectRel.java
new file mode 100644
index 0000000..ee3a0f4
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillProjectRel.java
@@ -0,0 +1,98 @@
+/**
+ * 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.planner.logical;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.logical.data.LogicalOperator;
+import org.apache.drill.common.logical.data.NamedExpression;
+import org.apache.drill.common.logical.data.Project;
+import org.apache.drill.exec.planner.torel.ConversionContext;
+import org.eigenbase.rel.InvalidRelException;
+import org.eigenbase.rel.ProjectRelBase;
+import org.eigenbase.rel.RelCollation;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.RelOptCluster;
+import org.eigenbase.relopt.RelOptCost;
+import org.eigenbase.relopt.RelOptPlanner;
+import org.eigenbase.relopt.RelTraitSet;
+import org.eigenbase.reltype.RelDataType;
+import org.eigenbase.reltype.RelDataTypeField;
+import org.eigenbase.reltype.RelDataTypeFieldImpl;
+import org.eigenbase.reltype.RelRecordType;
+import org.eigenbase.rex.RexNode;
+import org.eigenbase.sql.type.SqlTypeName;
+import org.eigenbase.util.Pair;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Lists;
+
+/**
+ * Project implemented in Drill.
+ */
+public class DrillProjectRel extends ProjectRelBase implements DrillRel {
+  protected DrillProjectRel(RelOptCluster cluster, RelTraitSet traits, RelNode child, List<RexNode> exps,
+      RelDataType rowType) {
+    super(cluster, traits, child, exps, rowType, Flags.BOXED);
+    assert getConvention() == CONVENTION;
+  }
+
+
+  @Override
+  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
+    return new DrillProjectRel(getCluster(), traitSet, sole(inputs), new ArrayList<RexNode>(exps), rowType);
+  }
+
+  @Override
+  public RelOptCost computeSelfCost(RelOptPlanner planner) {
+    return super.computeSelfCost(planner).multiplyBy(0.1);
+  }
+
+  private List<Pair<RexNode, String>> projects() {
+    return Pair.zip(exps, getRowType().getFieldNames());
+  }
+
+  @Override
+  public LogicalOperator implement(DrillImplementor implementor) {
+    LogicalOperator inputOp = implementor.visitChild(this, 0, getChild());
+    Project.Builder builder = Project.builder();
+    builder.setInput(inputOp);
+    for (Pair<RexNode, String> pair : projects()) {
+      LogicalExpression expr = DrillOptiq.toDrill(implementor.getContext(), getChild(), pair.left);
+      builder.addExpr(new FieldReference("output." + pair.right), expr);
+    }
+    return builder.build();
+  }
+  
+  public static DrillProjectRel convert(Project project, ConversionContext context) throws InvalidRelException{
+    RelNode input = context.toRel(project.getInput());
+    List<RelDataTypeField> fields = Lists.newArrayList();
+    List<RexNode> exps = Lists.newArrayList();
+    for(NamedExpression expr : project.getSelections()){
+      fields.add(new RelDataTypeFieldImpl(expr.getRef().getPath().toString(), fields.size(), context.getTypeFactory().createSqlType(SqlTypeName.ANY) ));
+      exps.add(context.toRex(expr.getExpr()));
+    }
+    return new DrillProjectRel(context.getCluster(), context.getLogicalTraits(), input, exps, new RelRecordType(fields));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillProjectRule.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillProjectRule.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillProjectRule.java
new file mode 100644
index 0000000..bf5bcff
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillProjectRule.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.exec.planner.logical;
+
+import org.eigenbase.rel.ProjectRel;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.Convention;
+import org.eigenbase.relopt.RelOptRule;
+import org.eigenbase.relopt.RelOptRuleCall;
+import org.eigenbase.relopt.RelTraitSet;
+
+/**
+ * Rule that converts a {@link org.eigenbase.rel.ProjectRel} to a Drill "project" operation.
+ */
+public class DrillProjectRule extends RelOptRule {
+  public static final RelOptRule INSTANCE = new DrillProjectRule();
+
+  private DrillProjectRule() {
+    super(RelOptHelper.some(ProjectRel.class, Convention.NONE, RelOptHelper.any(RelNode.class)), "DrillProjectRule");
+  }
+
+  @Override
+  public void onMatch(RelOptRuleCall call) {
+    final ProjectRel project = (ProjectRel) call.rel(0);
+    final RelNode input = call.rel(1);
+    final RelTraitSet traits = project.getTraitSet().plus(DrillRel.CONVENTION);
+    final RelNode convertedInput = convert(input, traits);
+    call.transformTo(new DrillProjectRel(project.getCluster(), traits, convertedInput, project.getProjects(), project
+        .getRowType()));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillRel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillRel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillRel.java
new file mode 100644
index 0000000..63a7207
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillRel.java
@@ -0,0 +1,33 @@
+/**
+ * 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.planner.logical;
+
+import org.apache.drill.common.logical.data.LogicalOperator;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.Convention;
+
+/**
+ * Relational expression that is implemented in Drill.
+ */
+public interface DrillRel extends RelNode {
+  /** Calling convention for relational expressions that are "implemented" by
+   * generating Drill logical plans. */
+  Convention CONVENTION = new Convention.Impl("DRILL", DrillRel.class);
+
+  LogicalOperator implement(DrillImplementor implementor);
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillRuleSets.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillRuleSets.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillRuleSets.java
new file mode 100644
index 0000000..53da67f
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillRuleSets.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.exec.planner.logical;
+
+import java.util.Iterator;
+
+import net.hydromatic.optiq.tools.RuleSet;
+
+import org.eigenbase.rel.rules.MergeProjectRule;
+import org.eigenbase.rel.rules.PushFilterPastJoinRule;
+import org.eigenbase.rel.rules.PushFilterPastProjectRule;
+import org.eigenbase.rel.rules.PushJoinThroughJoinRule;
+import org.eigenbase.rel.rules.PushSortPastProjectRule;
+import org.eigenbase.rel.rules.ReduceAggregatesRule;
+import org.eigenbase.rel.rules.RemoveDistinctAggregateRule;
+import org.eigenbase.rel.rules.RemoveDistinctRule;
+import org.eigenbase.rel.rules.RemoveSortRule;
+import org.eigenbase.rel.rules.RemoveTrivialCalcRule;
+import org.eigenbase.rel.rules.RemoveTrivialProjectRule;
+import org.eigenbase.rel.rules.SwapJoinRule;
+import org.eigenbase.rel.rules.TableAccessRule;
+import org.eigenbase.rel.rules.UnionToDistinctRule;
+import org.eigenbase.relopt.RelOptRule;
+import org.eigenbase.relopt.volcano.AbstractConverter.ExpandConversionRule;
+
+import com.google.common.collect.ImmutableSet;
+
+public class DrillRuleSets {
+  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillRuleSets.class);
+
+  public static final RuleSet DRILL_BASIC_RULES = new DrillRuleSet(ImmutableSet.of( //
+
+//      ExpandConversionRule.instance,
+//      SwapJoinRule.instance,
+//      RemoveDistinctRule.instance,
+//      UnionToDistinctRule.instance,
+//      RemoveTrivialProjectRule.instance,
+//      RemoveTrivialCalcRule.instance,
+//      RemoveSortRule.INSTANCE,
+//
+//      TableAccessRule.instance, //
+//      MergeProjectRule.instance, //
+//      PushFilterPastProjectRule.instance, //
+//      PushFilterPastJoinRule.FILTER_ON_JOIN, //
+//      RemoveDistinctAggregateRule.instance, //
+//      ReduceAggregatesRule.instance, //
+//      SwapJoinRule.instance, //
+//      PushJoinThroughJoinRule.RIGHT, //
+//      PushJoinThroughJoinRule.LEFT, //
+//      PushSortPastProjectRule.INSTANCE, //
+      
+      DrillScanRule.INSTANCE,
+      DrillFilterRule.INSTANCE,
+      DrillProjectRule.INSTANCE,
+      DrillAggregateRule.INSTANCE,
+
+      DrillLimitRule.INSTANCE,
+      DrillSortRule.INSTANCE,
+      DrillJoinRule.INSTANCE,
+      DrillUnionRule.INSTANCE
+      ));
+  
+  
+  private static class DrillRuleSet implements RuleSet{
+    final ImmutableSet<RelOptRule> rules;
+
+    public DrillRuleSet(ImmutableSet<RelOptRule> rules) {
+      super();
+      this.rules = rules;
+    }
+
+    @Override
+    public Iterator<RelOptRule> iterator() {
+      return rules.iterator();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillScanRel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillScanRel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillScanRel.java
new file mode 100644
index 0000000..afc2d1b
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillScanRel.java
@@ -0,0 +1,62 @@
+/**
+ * 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.planner.logical;
+
+import org.apache.drill.common.JSONOptions;
+import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.logical.data.LogicalOperator;
+import org.apache.drill.common.logical.data.Scan;
+import org.apache.drill.exec.planner.torel.ConversionContext;
+import org.eigenbase.rel.TableAccessRelBase;
+import org.eigenbase.relopt.RelOptCluster;
+import org.eigenbase.relopt.RelOptTable;
+import org.eigenbase.relopt.RelTraitSet;
+
+/**
+ * GroupScan of a Drill table.
+ */
+public class DrillScanRel extends TableAccessRelBase implements DrillRel {
+  private final DrillTable drillTable;
+
+  /** Creates a DrillScan. */
+  public DrillScanRel(RelOptCluster cluster, RelTraitSet traits, RelOptTable table) {
+    super(cluster, traits, table);
+    assert getConvention() == CONVENTION;
+    this.drillTable = table.unwrap(DrillTable.class);
+    assert drillTable != null;
+  }
+
+//  @Override
+//  public void register(RelOptPlanner planner) {
+//    super.register(planner);
+//    DrillOptiq.registerStandardPlannerRules(planner);
+//  }
+
+  public LogicalOperator implement(DrillImplementor implementor) {
+    Scan.Builder builder = Scan.builder();
+    builder.storageEngine(drillTable.getStorageEngineName());
+    builder.selection(new JSONOptions(drillTable.getSelection()));
+    //builder.outputReference(new FieldReference("_MAP"));
+    implementor.registerSource(drillTable);
+    return builder.build();
+  }
+  
+  public static DrillScanRel convert(Scan scan, ConversionContext context){
+    return new DrillScanRel(context.getCluster(), context.getLogicalTraits(), context.getTable(scan));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillScanRule.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillScanRule.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillScanRule.java
new file mode 100644
index 0000000..58e648a
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillScanRule.java
@@ -0,0 +1,43 @@
+/**
+ * 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.planner.logical;
+
+import net.hydromatic.optiq.rules.java.JavaRules.EnumerableTableAccessRel;
+
+import org.eigenbase.relopt.Convention;
+import org.eigenbase.relopt.RelOptRule;
+import org.eigenbase.relopt.RelOptRuleCall;
+import org.eigenbase.relopt.RelTraitSet;
+
+public class DrillScanRule  extends RelOptRule {
+  public static final RelOptRule INSTANCE = new DrillScanRule();
+
+  private DrillScanRule() {
+    super(RelOptHelper.any(EnumerableTableAccessRel.class), "DrillTableRule");
+  }
+
+
+
+
+  @Override
+  public void onMatch(RelOptRuleCall call) {
+    final EnumerableTableAccessRel access = (EnumerableTableAccessRel) call.rel(0);
+    final RelTraitSet traits = access.getTraitSet().plus(DrillRel.CONVENTION);
+    call.transformTo(new DrillScanRel(access.getCluster(), traits, access.getTable()));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillScreenRel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillScreenRel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillScreenRel.java
new file mode 100644
index 0000000..829947a
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillScreenRel.java
@@ -0,0 +1,76 @@
+/**
+ * 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.planner.logical;
+
+import java.util.List;
+
+import net.hydromatic.optiq.impl.java.JavaTypeFactory;
+import net.hydromatic.optiq.rules.java.EnumerableConvention;
+import net.hydromatic.optiq.rules.java.EnumerableRel;
+import net.hydromatic.optiq.rules.java.EnumerableRelImplementor;
+import net.hydromatic.optiq.rules.java.JavaRowFormat;
+import net.hydromatic.optiq.rules.java.PhysType;
+import net.hydromatic.optiq.rules.java.PhysTypeImpl;
+
+import org.apache.drill.common.logical.data.LogicalOperator;
+import org.apache.drill.common.logical.data.Store;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.rel.SingleRel;
+import org.eigenbase.relopt.RelOptCluster;
+import org.eigenbase.relopt.RelOptCost;
+import org.eigenbase.relopt.RelOptPlanner;
+import org.eigenbase.relopt.RelTraitSet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Relational expression that converts from Drill to Enumerable. At runtime it executes a Drill query and returns the
+ * results as an {@link net.hydromatic.linq4j.Enumerable}.
+ */
+public class DrillScreenRel extends SingleRel implements DrillRel {
+  private static final Logger logger = LoggerFactory.getLogger(DrillScreenRel.class);
+
+  private PhysType physType;
+
+  public DrillScreenRel(RelOptCluster cluster, RelTraitSet traitSet, RelNode input) {
+    super(cluster, traitSet, input);
+    assert input.getConvention() == DrillRel.CONVENTION;
+    physType = PhysTypeImpl.of((JavaTypeFactory) cluster.getTypeFactory(), input.getRowType(), JavaRowFormat.ARRAY);
+  }
+
+  public PhysType getPhysType() {
+    return physType;
+  }
+
+  @Override
+  public RelOptCost computeSelfCost(RelOptPlanner planner) {
+    return super.computeSelfCost(planner).multiplyBy(.1);
+  }
+
+  @Override
+  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
+    return new DrillScreenRel(getCluster(), traitSet, sole(inputs));
+  }
+  
+  @Override
+  public LogicalOperator implement(DrillImplementor implementor) {
+    LogicalOperator childOp = implementor.visitChild(this, 0, getChild());
+    return Store.builder().setInput(childOp).storageEngine("--SCREEN--").build();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillSortRel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillSortRel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillSortRel.java
new file mode 100644
index 0000000..04af9d5
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillSortRel.java
@@ -0,0 +1,100 @@
+/**
+ * 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.planner.logical;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.logical.data.LogicalOperator;
+import org.apache.drill.common.logical.data.Order;
+import org.apache.drill.common.logical.data.Order.Ordering;
+import org.apache.drill.exec.planner.torel.ConversionContext;
+import org.eigenbase.rel.InvalidRelException;
+import org.eigenbase.rel.RelCollation;
+import org.eigenbase.rel.RelCollationImpl;
+import org.eigenbase.rel.RelFieldCollation;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.rel.SortRel;
+import org.eigenbase.relopt.RelOptCluster;
+import org.eigenbase.relopt.RelTraitSet;
+import org.eigenbase.rex.RexNode;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * Sort implemented in Drill.
+ */
+public class DrillSortRel extends SortRel implements DrillRel {
+
+  /** Creates a DrillSortRel. */
+  public DrillSortRel(RelOptCluster cluster, RelTraitSet traits, RelNode input, RelCollation collation) {
+    super(cluster, traits, input, collation);
+  }
+
+  /** Creates a DrillSortRel with offset and fetch. */
+  public DrillSortRel(RelOptCluster cluster, RelTraitSet traits, RelNode input, RelCollation collation, RexNode offset, RexNode fetch) {
+    super(cluster, traits, input, collation, offset, fetch);
+  }
+
+  @Override
+  public DrillSortRel copy(RelTraitSet traitSet, RelNode input, RelCollation collation, RexNode offset, RexNode fetch) {
+    return new DrillSortRel(getCluster(), traitSet, input, collation, offset, fetch);
+  }
+
+  @Override
+  public LogicalOperator implement(DrillImplementor implementor) {
+    final Order.Builder builder = Order.builder();
+    builder.setInput(implementor.visitChild(this, 0, getChild()));
+    
+    final List<String> childFields = getChild().getRowType().getFieldNames();
+    for(RelFieldCollation fieldCollation : this.collation.getFieldCollations()){
+      builder.addOrdering(fieldCollation.getDirection(), 
+          new FieldReference(childFields.get(fieldCollation.getFieldIndex())),
+          fieldCollation.nullDirection);
+    }
+    return builder.build();
+  }
+
+  
+  public static RelNode convert(Order order, ConversionContext context) throws InvalidRelException{
+    
+    // if there are compound expressions in the order by, we need to convert into projects on either side.
+    RelNode input = context.toRel(order.getInput());
+    List<String> fields = input.getRowType().getFieldNames();
+
+    // build a map of field names to indices.
+    Map<String, Integer> fieldMap = Maps.newHashMap();
+    int i =0;
+    for(String field : fields){
+      fieldMap.put(field, i);
+      i++;
+    }
+    
+    List<RelFieldCollation> collations = Lists.newArrayList();
+    
+    for(Ordering o : order.getOrderings()){
+      String fieldName = ExprHelper.getFieldName(o.getExpr());
+      int fieldId = fieldMap.get(fieldName);
+      RelFieldCollation c = new RelFieldCollation(fieldId, o.getDirection(), o.getNullDirection());
+    }
+    return new DrillSortRel(context.getCluster(), context.getLogicalTraits(), input, RelCollationImpl.of(collations));
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillSortRule.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillSortRule.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillSortRule.java
new file mode 100644
index 0000000..c968e85
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillSortRule.java
@@ -0,0 +1,51 @@
+/**
+ * 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.planner.logical;
+
+import org.eigenbase.rel.SortRel;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.*;
+
+/**
+ * Rule that converts an {@link SortRel} to a {@link DrillSortRel}, implemented by a Drill "order" operation.
+ */
+public class DrillSortRule extends RelOptRule {
+  public static final RelOptRule INSTANCE = new DrillSortRule();
+
+  private DrillSortRule() {
+    super(RelOptHelper.some(SortRel.class, Convention.NONE, RelOptHelper.any(RelNode.class)), "DrillSortRule");
+  }
+
+  @Override
+  public boolean matches(RelOptRuleCall call) {
+    final SortRel sort = call.rel(0);
+    return sort.offset == null && sort.fetch == null;
+  }
+
+  @Override
+  public void onMatch(RelOptRuleCall call) {
+
+    final SortRel sort = call.rel(0);
+
+    final RelNode input = call.rel(1);
+    final RelTraitSet traits = sort.getTraitSet().plus(DrillRel.CONVENTION);
+
+    final RelNode convertedInput = convert(input, input.getTraitSet().plus(DrillRel.CONVENTION));
+    call.transformTo(new DrillSortRel(sort.getCluster(), traits, convertedInput, sort.getCollation()));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillStoreRel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillStoreRel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillStoreRel.java
new file mode 100644
index 0000000..30c7810
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillStoreRel.java
@@ -0,0 +1,45 @@
+/**
+ * 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.planner.logical;
+
+import java.util.List;
+
+import net.hydromatic.optiq.prepare.Prepare.CatalogReader;
+
+import org.apache.drill.common.logical.data.LogicalOperator;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.rel.TableModificationRelBase;
+import org.eigenbase.relopt.RelOptCluster;
+import org.eigenbase.relopt.RelOptTable;
+import org.eigenbase.relopt.RelTraitSet;
+
+public class DrillStoreRel extends TableModificationRelBase implements DrillRel{
+  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillStoreRel.class);
+
+  protected DrillStoreRel(RelOptCluster cluster, RelTraitSet traits, RelOptTable table, CatalogReader catalogReader,
+      RelNode child, Operation operation, List<String> updateColumnList, boolean flattened) {
+    super(cluster, traits, table, catalogReader, child, operation, updateColumnList, flattened);
+    
+  }
+
+  @Override
+  public LogicalOperator implement(DrillImplementor implementor) {
+    return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillTable.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillTable.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillTable.java
new file mode 100644
index 0000000..30dd48d
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillTable.java
@@ -0,0 +1,107 @@
+/**
+ * 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.planner.logical;
+
+import java.util.Collections;
+
+import net.hydromatic.optiq.Schema.TableType;
+import net.hydromatic.optiq.Statistic;
+import net.hydromatic.optiq.Statistics;
+import net.hydromatic.optiq.Table;
+
+import org.apache.drill.common.logical.StorageEngineConfig;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.RelOptTable;
+import org.eigenbase.reltype.RelDataType;
+import org.eigenbase.reltype.RelDataTypeFactory;
+import org.eigenbase.sql.type.SqlTypeName;
+
+/** Optiq Table used by Drill. */
+public class DrillTable implements Table{
+  
+  private final String name;
+  private final String storageEngineName;  
+  public final StorageEngineConfig storageEngineConfig;
+  private Object selection;
+  
+  
+  /** Creates a DrillTable. */
+  public DrillTable(String name, String storageEngineName, Object selection, StorageEngineConfig storageEngineConfig) {
+    this.name = name;
+    this.selection = selection;
+    this.storageEngineConfig = storageEngineConfig;
+    this.storageEngineName = storageEngineName;
+  }
+  
+  public String getName() {
+    return name;
+  }
+
+  public StorageEngineConfig getStorageEngineConfig(){
+    return storageEngineConfig;
+  }
+  
+  public Object getSelection() {
+    return selection;
+  }
+  
+  public String getStorageEngineName() {
+    return storageEngineName;
+  }
+
+  @Override
+  public Statistic getStatistic() {
+    return Statistics.UNKNOWN;
+  }
+
+  public RelNode toRel(RelOptTable.ToRelContext context, RelOptTable table) {
+    return new DrillScanRel(context.getCluster(),
+        context.getCluster().traitSetOf(DrillRel.CONVENTION),
+        table);
+  }
+
+  @Override
+  public RelDataType getRowType(RelDataTypeFactory typeFactory) {
+    return new RelDataTypeDrillImpl(typeFactory);
+  }
+
+  @Override
+  public TableType getJdbcTableType() {
+    return null;
+  }
+
+  
+  
+//  /** 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();
+//      final ClasspathInputConfig inputConfig = new ClasspathInputConfig();
+//      inputConfig.path = "/" + name.toLowerCase() + ".json";
+//      inputConfig.type = DataWriter.ConverterType.JSON;
+//      return createTable(schema.getTypeFactory(), (MutableSchema) schema, name, "donuts-json", rseConfig, inputConfig);
+//    }
+//  }
+
+  
+  
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillUnionRel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillUnionRel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillUnionRel.java
new file mode 100644
index 0000000..1be9caf
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillUnionRel.java
@@ -0,0 +1,71 @@
+/**
+ * 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.planner.logical;
+
+import java.util.List;
+
+import net.hydromatic.linq4j.Ord;
+
+import org.apache.drill.common.logical.data.Limit;
+import org.apache.drill.common.logical.data.LogicalOperator;
+import org.apache.drill.common.logical.data.Union;
+import org.apache.drill.exec.planner.torel.ConversionContext;
+import org.eigenbase.rel.InvalidRelException;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.rel.UnionRelBase;
+import org.eigenbase.relopt.RelOptCluster;
+import org.eigenbase.relopt.RelOptCost;
+import org.eigenbase.relopt.RelOptPlanner;
+import org.eigenbase.relopt.RelTraitSet;
+
+/**
+ * Union implemented in Drill.
+ */
+public class DrillUnionRel extends UnionRelBase implements DrillRel {
+  /** Creates a DrillUnionRel. */
+  public DrillUnionRel(RelOptCluster cluster, RelTraitSet traits,
+      List<RelNode> inputs, boolean all) {
+    super(cluster, traits, inputs, all);
+  }
+
+  @Override
+  public DrillUnionRel copy(RelTraitSet traitSet, List<RelNode> inputs,
+      boolean all) {
+    return new DrillUnionRel(getCluster(), traitSet, inputs, all);
+  }
+
+  @Override
+  public RelOptCost computeSelfCost(RelOptPlanner planner) {
+    // divide cost by two to ensure cheaper than EnumerableDrillRel
+    return super.computeSelfCost(planner).multiplyBy(.5);
+  }
+
+  @Override
+  public LogicalOperator implement(DrillImplementor implementor) {
+    Union.Builder builder = Union.builder();
+    for (Ord<RelNode> input : Ord.zip(inputs)) {
+      builder.addInput(implementor.visitChild(this, input.i, input.e));
+    }
+    builder.setDistinct(!all);
+    return builder.build();
+  }
+  
+  public static DrillUnionRel convert(Union union, ConversionContext context) throws InvalidRelException{
+    throw new UnsupportedOperationException();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillUnionRule.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillUnionRule.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillUnionRule.java
new file mode 100644
index 0000000..bc1e6f4
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillUnionRule.java
@@ -0,0 +1,48 @@
+/**
+ * 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.planner.logical;
+
+import org.eigenbase.rel.UnionRel;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Rule that converts a {@link UnionRel} to a {@link DrillUnionRel}, implemented by a "union" operation.
+ */
+public class DrillUnionRule extends RelOptRule {
+  public static final RelOptRule INSTANCE = new DrillUnionRule();
+
+  private DrillUnionRule() {
+    super(RelOptHelper.any(UnionRel.class, Convention.NONE), "DrillUnionRule");
+  }
+
+  @Override
+  public void onMatch(RelOptRuleCall call) {
+    final UnionRel union = (UnionRel) call.rel(0);
+    final RelTraitSet traits = union.getTraitSet().plus(DrillRel.CONVENTION);
+    final List<RelNode> convertedInputs = new ArrayList<>();
+    for (RelNode input : union.getInputs()) {
+      final RelNode convertedInput = convert(input, traits);
+      convertedInputs.add(convertedInput);
+    }
+    call.transformTo(new DrillUnionRel(union.getCluster(), traits, convertedInputs, union.all));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/b3460af8/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillValuesRel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillValuesRel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillValuesRel.java
new file mode 100644
index 0000000..e770181
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillValuesRel.java
@@ -0,0 +1,57 @@
+/**
+ * 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.planner.logical;
+
+import java.util.List;
+
+import org.apache.drill.common.logical.data.LogicalOperator;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.rel.ValuesRelBase;
+import org.eigenbase.relopt.RelOptCluster;
+import org.eigenbase.relopt.RelOptCost;
+import org.eigenbase.relopt.RelOptPlanner;
+import org.eigenbase.relopt.RelTraitSet;
+import org.eigenbase.reltype.RelDataType;
+import org.eigenbase.rex.RexLiteral;
+
+/**
+ * Values implemented in Drill.
+ */
+public class DrillValuesRel extends ValuesRelBase implements DrillRel {
+  protected DrillValuesRel(RelOptCluster cluster, RelDataType rowType, List<List<RexLiteral>> tuples, RelTraitSet traits) {
+    super(cluster, rowType, tuples, traits);
+    assert getConvention() == CONVENTION;
+  }
+
+  @Override
+  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
+    assert inputs.isEmpty();
+    return new DrillValuesRel(getCluster(), rowType, tuples, traitSet);
+  }
+
+  @Override
+  public RelOptCost computeSelfCost(RelOptPlanner planner) {
+    return super.computeSelfCost(planner).multiplyBy(0.1);
+  }
+
+  @Override
+  public LogicalOperator implement(DrillImplementor implementor) {
+    // Update when https://issues.apache.org/jira/browse/DRILL-57 fixed
+    throw new UnsupportedOperationException();
+  }
+}


Mime
View raw message