You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@drill.apache.org by ja...@apache.org on 2014/05/22 03:14:41 UTC

[04/24] git commit: Use PrelVisitor to add Project when Join has conflicting names from inputs. Move common code of MergeJoin, HashJoin to base class.

Use PrelVisitor to add Project when Join has conflicting names from inputs. Move common code of MergeJoin, HashJoin to base class.


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

Branch: refs/heads/diagnostics2
Commit: 73d3bd063e2286cc1a71ebf7ef71ae6171bd592e
Parents: ebf3d34
Author: Jinfeng Ni <jn...@maprtech.com>
Authored: Fri May 16 16:02:53 2014 -0700
Committer: Jacques Nadeau <ja...@apache.org>
Committed: Mon May 19 09:11:22 2014 -0700

----------------------------------------------------------------------
 .../exec/planner/logical/DrillProjectRel.java   |  6 +-
 .../exec/planner/physical/ExchangePrel.java     | 18 ++++
 .../exec/planner/physical/HashJoinPrel.java     | 64 +------------
 .../drill/exec/planner/physical/JoinPrel.java   | 98 ++++++++++++++++++++
 .../planner/physical/JoinPrelRenameVisitor.java | 75 +++++++++++++++
 .../exec/planner/physical/MergeJoinPrel.java    | 67 +------------
 .../exec/planner/physical/PrelVisitor.java      |  3 +
 .../physical/SelectionVectorPrelVisitor.java    |  5 +
 .../physical/SelectionVectorRemoverPrel.java    | 14 +++
 .../planner/physical/explain/PrelSequencer.java |  6 ++
 .../planner/sql/handlers/DefaultSqlHandler.java |  5 +
 .../apache/drill/exec/TestOpSerialization.java  | 18 ++++
 12 files changed, 250 insertions(+), 129 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/73d3bd06/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
index aa75f52..c3eb3fb 100644
--- 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
@@ -17,7 +17,6 @@
  */
 package org.apache.drill.exec.planner.logical;
 
-import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.drill.common.logical.data.LogicalOperator;
@@ -28,10 +27,7 @@ import org.apache.drill.exec.planner.torel.ConversionContext;
 import org.eigenbase.rel.InvalidRelException;
 import org.eigenbase.rel.ProjectRelBase;
 import org.eigenbase.rel.RelNode;
-import org.eigenbase.rel.metadata.RelMetadataQuery;
 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;
@@ -78,5 +74,5 @@ public class DrillProjectRel extends DrillProjectRelBase implements DrillRel {
     }
     return new DrillProjectRel(context.getCluster(), context.getLogicalTraits(), input, exps, new RelRecordType(fields));
   }
-  
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/73d3bd06/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ExchangePrel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ExchangePrel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ExchangePrel.java
index 360fa80..21bf3b1 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ExchangePrel.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/ExchangePrel.java
@@ -1,3 +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.
+ */
+
 package org.apache.drill.exec.planner.physical;
 
 import org.eigenbase.rel.RelNode;

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/73d3bd06/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/HashJoinPrel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/HashJoinPrel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/HashJoinPrel.java
index 87da31e..b03ef62 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/HashJoinPrel.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/HashJoinPrel.java
@@ -18,16 +18,12 @@
 package org.apache.drill.exec.planner.physical;
 
 import java.io.IOException;
-import java.util.Iterator;
 import java.util.List;
 
 import org.apache.drill.common.expression.FieldReference;
 import org.apache.drill.common.logical.data.JoinCondition;
-import org.apache.drill.common.logical.data.NamedExpression;
 import org.apache.drill.exec.physical.base.PhysicalOperator;
 import org.apache.drill.exec.physical.config.HashJoinPOP;
-import org.apache.drill.exec.physical.config.Project;
-import org.apache.drill.exec.planner.common.DrillJoinRelBase;
 import org.apache.drill.exec.planner.cost.DrillCostBase;
 import org.apache.drill.exec.planner.cost.DrillCostBase.DrillCostFactory;
 import org.apache.drill.exec.record.BatchSchema.SelectionVectorMode;
@@ -46,7 +42,7 @@ import org.eigenbase.util.Pair;
 
 import com.beust.jcommander.internal.Lists;
 
-public class HashJoinPrel  extends DrillJoinRelBase implements Prel {
+public class HashJoinPrel  extends JoinPrel {
 
   public HashJoinPrel(RelOptCluster cluster, RelTraitSet traits, RelNode left, RelNode right, RexNode condition,
       JoinRelType joinType) throws InvalidRelException {
@@ -94,8 +90,8 @@ public class HashJoinPrel  extends DrillJoinRelBase implements Prel {
     final List<String> leftFields = fields.subList(0, leftCount);
     final List<String> rightFields = fields.subList(leftCount, fields.size());
 
-    PhysicalOperator leftPop = implementInput(creator, 0, left);
-    PhysicalOperator rightPop = implementInput(creator, leftCount, right);
+    PhysicalOperator leftPop = ((Prel)left).getPhysicalOperator(creator);
+    PhysicalOperator rightPop = ((Prel)right).getPhysicalOperator(creator);
 
     JoinRelType jtype = this.getJoinType();
 
@@ -111,60 +107,6 @@ public class HashJoinPrel  extends DrillJoinRelBase implements Prel {
     return hjoin;
   }
 
-  public List<Integer> getLeftKeys() {
-    return this.leftKeys;
-  }
-
-  public List<Integer> getRightKeys() {
-    return this.rightKeys;
-  }
-
-  /**
-   * 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 PhysicalOperator implementInput(PhysicalPlanCreator creator, int offset, RelNode input) throws IOException {
-    final PhysicalOperator inputOp = ((Prel) input).getPhysicalOperator(creator);
-    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(creator, inputOp, inputFields, outputFields);
-    } else {
-      return inputOp;
-    }
-  }
-
-  private PhysicalOperator rename(PhysicalPlanCreator creator, PhysicalOperator inputOp, List<String> inputFields, List<String> outputFields) {
-    List<NamedExpression> exprs = Lists.newArrayList();
-
-    for (Pair<String, String> pair : Pair.zip(inputFields, outputFields)) {
-      exprs.add(new NamedExpression(new FieldReference(pair.left), new FieldReference(pair.right)));
-    }
-
-    Project proj = new Project(exprs, inputOp);
-
-    return proj;
-  }
-
-  @Override
-  public Iterator<Prel> iterator() {
-    return PrelUtil.iter(getLeft(), getRight());
-  }
-
-  @Override
-  public <T, X, E extends Throwable> T accept(PrelVisitor<T, X, E> logicalVisitor, X value) throws E {
-    return logicalVisitor.visitPrel(this, value);
-  }
-
   @Override
   public SelectionVectorMode[] getSupportedEncodings() {
     return SelectionVectorMode.DEFAULT;

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/73d3bd06/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/JoinPrel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/JoinPrel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/JoinPrel.java
new file mode 100644
index 0000000..9e1f6fb
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/JoinPrel.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.physical;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.drill.exec.planner.common.DrillJoinRelBase;
+import org.eigenbase.rel.InvalidRelException;
+import org.eigenbase.rel.JoinRelType;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.RelOptCluster;
+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 com.google.common.collect.Lists;
+
+/**
+ *
+ * Base class for MergeJoinPrel and HashJoinPrel
+ *
+ */
+public abstract class JoinPrel extends DrillJoinRelBase implements Prel{
+
+  public JoinPrel(RelOptCluster cluster, RelTraitSet traits, RelNode left, RelNode right, RexNode condition,
+      JoinRelType joinType) throws InvalidRelException{
+    super(cluster, traits, left, right, condition, joinType);
+  }
+
+  @Override
+  public <T, X, E extends Throwable> T accept(PrelVisitor<T, X, E> logicalVisitor, X value) throws E {
+    return logicalVisitor.visitJoin(this, value);
+  }
+
+  @Override
+  public Iterator<Prel> iterator() {
+    return PrelUtil.iter(getLeft(), getRight());
+  }
+
+  /**
+   * 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
+   */
+  public RelNode getJoinInput(int offset, RelNode 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.
+      // In such case, we need insert a rename Project on top of the input.
+      return rename(input, input.getRowType().getFieldList(), outputFields);
+    } else {
+      return input;
+    }
+  }
+
+  private RelNode rename(RelNode input, List<RelDataTypeField> inputFields, List<String> outputFieldNames) {
+    List<RexNode> exprs = Lists.newArrayList();
+
+    for (RelDataTypeField field : inputFields) {
+      RexNode expr = input.getCluster().getRexBuilder().makeInputRef(field.getType(), field.getIndex());
+      exprs.add(expr);
+    }
+
+    RelDataType rowType = RexUtil.createStructType(input.getCluster().getTypeFactory(), exprs, outputFieldNames);
+
+    ProjectPrel proj = new ProjectPrel(input.getCluster(), input.getTraitSet(), input, exprs, rowType);
+
+    return proj;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/73d3bd06/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/JoinPrelRenameVisitor.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/JoinPrelRenameVisitor.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/JoinPrelRenameVisitor.java
new file mode 100644
index 0000000..ed4b8f8
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/JoinPrelRenameVisitor.java
@@ -0,0 +1,75 @@
+/**
+ * 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.physical;
+
+import java.util.List;
+
+import org.eigenbase.rel.RelNode;
+
+import com.google.common.collect.Lists;
+
+public class JoinPrelRenameVisitor implements PrelVisitor<Prel, Void, RuntimeException>{
+
+  private static JoinPrelRenameVisitor INSTANCE = new JoinPrelRenameVisitor();
+
+  public static Prel insertRenameProject(Prel prel){
+    return prel.accept(INSTANCE, null);
+  }
+
+  @Override
+  public Prel visitExchange(ExchangePrel prel, Void value) throws RuntimeException {
+    return visitPrel(prel, value);
+  }
+
+  @Override
+  public Prel visitPrel(Prel prel, Void value) throws RuntimeException {
+    List<RelNode> children = Lists.newArrayList();
+    for(Prel child : prel){
+      child = child.accept(this, null);
+      children.add(child);
+    }
+
+    return (Prel) prel.copy(prel.getTraitSet(), children);
+
+  }
+
+  @Override
+  public Prel visitJoin(JoinPrel prel, Void value) throws RuntimeException {
+
+    List<RelNode> children = Lists.newArrayList();
+
+    for(Prel child : prel){
+      child = child.accept(this, null);
+      children.add(child);
+    }
+
+    final int leftCount = children.get(0).getRowType().getFieldCount();
+
+    List<RelNode> reNamedChildren = Lists.newArrayList();
+
+    RelNode left = prel.getJoinInput(0, children.get(0));
+    RelNode right = prel.getJoinInput(leftCount, children.get(1));
+
+    reNamedChildren.add(left);
+    reNamedChildren.add(right);
+
+    return (Prel) prel.copy(prel.getTraitSet(), reNamedChildren);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/73d3bd06/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/MergeJoinPrel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/MergeJoinPrel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/MergeJoinPrel.java
index 400c6a8..1987e99 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/MergeJoinPrel.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/MergeJoinPrel.java
@@ -18,17 +18,12 @@
 package org.apache.drill.exec.planner.physical;
 
 import java.io.IOException;
-import java.util.Iterator;
 import java.util.List;
 
 import org.apache.drill.common.expression.FieldReference;
 import org.apache.drill.common.logical.data.JoinCondition;
-import org.apache.drill.common.logical.data.NamedExpression;
 import org.apache.drill.exec.physical.base.PhysicalOperator;
 import org.apache.drill.exec.physical.config.MergeJoinPOP;
-import org.apache.drill.exec.physical.config.Project;
-import org.apache.drill.exec.physical.config.SelectionVectorRemover;
-import org.apache.drill.exec.planner.common.DrillJoinRelBase;
 import org.apache.drill.exec.planner.cost.DrillCostBase;
 import org.apache.drill.exec.planner.cost.DrillCostBase.DrillCostFactory;
 import org.apache.drill.exec.record.BatchSchema.SelectionVectorMode;
@@ -47,9 +42,7 @@ import org.eigenbase.util.Pair;
 
 import com.beust.jcommander.internal.Lists;
 
-public class MergeJoinPrel  extends DrillJoinRelBase implements Prel {
-
-  //private final JoinCondition[] joinConditions; // Drill's representation of join conditions
+public class MergeJoinPrel  extends JoinPrel {
 
   /** Creates a MergeJoiPrel. */
   public MergeJoinPrel(RelOptCluster cluster, RelTraitSet traits, RelNode left, RelNode right, RexNode condition,
@@ -94,12 +87,13 @@ public class MergeJoinPrel  extends DrillJoinRelBase implements Prel {
   public PhysicalOperator getPhysicalOperator(PhysicalPlanCreator creator) throws IOException {
     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());
 
-    PhysicalOperator leftPop = implementInput(creator, 0, left);
-    PhysicalOperator rightPop = implementInput(creator, leftCount, right);
+    PhysicalOperator leftPop = ((Prel)left).getPhysicalOperator(creator);
+    PhysicalOperator rightPop = ((Prel)right).getPhysicalOperator(creator);
 
     JoinRelType jtype = this.getJoinType();
 
@@ -113,60 +107,7 @@ public class MergeJoinPrel  extends DrillJoinRelBase implements Prel {
     mjoin.setOperatorId(creator.getOperatorId(this));
 
     return mjoin;
-  }
-
-  public List<Integer> getLeftKeys() {
-    return this.leftKeys;
-  }
-
-  public List<Integer> getRightKeys() {
-    return this.rightKeys;
-  }
-
-  /**
-   * 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 PhysicalOperator implementInput(PhysicalPlanCreator creator, int offset, RelNode input) throws IOException {
-    final PhysicalOperator inputOp = ((Prel) input).getPhysicalOperator(creator);
-    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(creator, inputOp, inputFields, outputFields);
-    } else {
-      return inputOp;
-    }
-  }
 
-  private PhysicalOperator rename(PhysicalPlanCreator creator, PhysicalOperator inputOp, List<String> inputFields, List<String> outputFields) {
-    List<NamedExpression> exprs = Lists.newArrayList();
-
-    for (Pair<String, String> pair : Pair.zip(inputFields, outputFields)) {
-      exprs.add(new NamedExpression(new FieldReference(pair.left), new FieldReference(pair.right)));
-    }
-
-    Project proj = new Project(exprs, inputOp);
-
-    return proj;
-  }
-
-  @Override
-  public Iterator<Prel> iterator() {
-    return PrelUtil.iter(getLeft(), getRight());
-  }
-
-  @Override
-  public <T, X, E extends Throwable> T accept(PrelVisitor<T, X, E> logicalVisitor, X value) throws E {
-    return logicalVisitor.visitPrel(this, value);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/73d3bd06/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/PrelVisitor.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/PrelVisitor.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/PrelVisitor.java
index 862b133..93f95a8 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/PrelVisitor.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/PrelVisitor.java
@@ -22,6 +22,9 @@ public interface PrelVisitor<RETURN, EXTRA, EXCEP extends Throwable> {
   static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(PrelVisitor.class);
 
   public RETURN visitExchange(ExchangePrel prel, EXTRA value) throws EXCEP;
+
+  public RETURN visitJoin(JoinPrel prel, EXTRA value) throws EXCEP;
+
   public RETURN visitPrel(Prel prel, EXTRA value) throws EXCEP;
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/73d3bd06/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/SelectionVectorPrelVisitor.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/SelectionVectorPrelVisitor.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/SelectionVectorPrelVisitor.java
index 224ab76..8f2ecd4 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/SelectionVectorPrelVisitor.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/SelectionVectorPrelVisitor.java
@@ -39,6 +39,11 @@ public class SelectionVectorPrelVisitor implements PrelVisitor<Prel, Void, Runti
   }
 
   @Override
+  public Prel visitJoin(JoinPrel prel, Void value) throws RuntimeException {
+    return visitPrel(prel, value);
+  }
+
+  @Override
   public Prel visitPrel(Prel prel, Void value) throws RuntimeException {
     SelectionVectorMode[] encodings = prel.getSupportedEncodings();
     List<RelNode> children = Lists.newArrayList();

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/73d3bd06/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/SelectionVectorRemoverPrel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/SelectionVectorRemoverPrel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/SelectionVectorRemoverPrel.java
index fd07749..4332188 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/SelectionVectorRemoverPrel.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/SelectionVectorRemoverPrel.java
@@ -18,10 +18,16 @@
 package org.apache.drill.exec.planner.physical;
 
 import java.io.IOException;
+import java.util.List;
 
 import org.apache.drill.exec.physical.base.PhysicalOperator;
 import org.apache.drill.exec.physical.config.SelectionVectorRemover;
 import org.apache.drill.exec.record.BatchSchema.SelectionVectorMode;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.RelOptCluster;
+import org.eigenbase.relopt.RelTraitSet;
+import org.eigenbase.reltype.RelDataType;
+import org.eigenbase.rex.RexNode;
 
 public class SelectionVectorRemoverPrel extends SinglePrel{
   static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(SelectionVectorRemoverPrel.class);
@@ -30,6 +36,14 @@ public class SelectionVectorRemoverPrel extends SinglePrel{
     super(child.getCluster(), child.getTraitSet(), child);
   }
 
+  public SelectionVectorRemoverPrel(RelOptCluster cluster, RelTraitSet traits, RelNode child) {
+    super(cluster, traits, child);
+  }
+
+  public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
+    return new SelectionVectorRemoverPrel(this.getCluster(), traitSet, inputs.get(0));
+  }
+
   @Override
   public PhysicalOperator getPhysicalOperator(PhysicalPlanCreator creator) throws IOException {
     SelectionVectorRemover r =  new SelectionVectorRemover( ((Prel)getChild()).getPhysicalOperator(creator));

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/73d3bd06/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/explain/PrelSequencer.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/explain/PrelSequencer.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/explain/PrelSequencer.java
index 2ab6c74..771546a 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/explain/PrelSequencer.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/explain/PrelSequencer.java
@@ -25,6 +25,7 @@ import java.util.Map;
 import java.util.Queue;
 
 import org.apache.drill.exec.planner.physical.ExchangePrel;
+import org.apache.drill.exec.planner.physical.JoinPrel;
 import org.apache.drill.exec.planner.physical.Prel;
 import org.apache.drill.exec.planner.physical.PrelVisitor;
 import org.eigenbase.rel.RelWriter;
@@ -234,6 +235,11 @@ public class PrelSequencer implements PrelVisitor<Void, PrelSequencer.Frag, Runt
   }
 
   @Override
+  public Void visitJoin(JoinPrel prel, Frag value) throws RuntimeException {
+    return visitPrel(prel, value);
+  }
+
+  @Override
   public Void visitPrel(Prel prel, Frag value) throws RuntimeException {
     for(Prel children : prel){
       children.accept(this, value);

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/73d3bd06/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
index b06432a..36ec0e8 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
@@ -38,6 +38,7 @@ import org.apache.drill.exec.planner.logical.DrillRel;
 import org.apache.drill.exec.planner.logical.DrillScreenRel;
 import org.apache.drill.exec.planner.logical.DrillStoreRel;
 import org.apache.drill.exec.planner.physical.DrillDistributionTrait;
+import org.apache.drill.exec.planner.physical.JoinPrelRenameVisitor;
 import org.apache.drill.exec.planner.physical.PhysicalPlanCreator;
 import org.apache.drill.exec.planner.physical.Prel;
 import org.apache.drill.exec.planner.physical.SelectionVectorPrelVisitor;
@@ -125,6 +126,10 @@ public class DefaultSqlHandler extends AbstractSqlHandler {
     RelTraitSet traits = drel.getTraitSet().plus(Prel.DRILL_PHYSICAL).plus(DrillDistributionTrait.SINGLETON);
     Prel phyRelNode = (Prel) planner.transform(DrillSqlWorker.PHYSICAL_MEM_RULES, traits, drel);
 
+    // Join might cause naming conflicts from its left and right child.
+    // In such case, we have to insert Project to rename the conflicting names.
+    phyRelNode = JoinPrelRenameVisitor.insertRenameProject(phyRelNode);
+
     // the last thing we do is add any required selection vector removers given the supported encodings of each
     // operator. This will ultimately move to a new trait but we're managing here for now to avoid introducing new
     // issues in planning before the next release

http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/73d3bd06/exec/java-exec/src/test/java/org/apache/drill/exec/TestOpSerialization.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/TestOpSerialization.java b/exec/java-exec/src/test/java/org/apache/drill/exec/TestOpSerialization.java
index ad1d6b6..906361a 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/exec/TestOpSerialization.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/TestOpSerialization.java
@@ -1,3 +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.
+ */
+
 package org.apache.drill.exec;
 
 import static org.junit.Assert.assertEquals;