You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by kr...@apache.org on 2020/07/29 04:57:31 UTC

[hive] branch master updated: HIVE-23750: Rewrite plan to join back tables: support function calls in project (Krisztian Kasa, reviewed by Jesus Camacho Rodriguez)

This is an automated email from the ASF dual-hosted git repository.

krisztiankasa pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git


The following commit(s) were added to refs/heads/master by this push:
     new c1dc4d9  HIVE-23750: Rewrite plan to join back tables: support function calls in project (Krisztian Kasa, reviewed by Jesus Camacho Rodriguez)
c1dc4d9 is described below

commit c1dc4d9b23e84dee5ce21ac1446c719310177aa1
Author: kasakrisz <kk...@cloudera.com>
AuthorDate: Wed Jul 29 06:57:17 2020 +0200

    HIVE-23750: Rewrite plan to join back tables: support function calls in project (Krisztian Kasa, reviewed by Jesus Camacho Rodriguez)
---
 .../java/org/apache/hadoop/hive/conf/HiveConf.java |   2 +-
 .../HiveCardinalityPreservingJoinOptimization.java | 268 +++++++-------
 .../rules/HiveCardinalityPreservingJoinRule.java   |  18 +
 .../cardinality_preserving_join_opt.q              | 127 +++++++
 .../llap/cardinality_preserving_join_opt.q.out     | 391 +++++++++++++++++++++
 .../llap/constraints_optimization.q.out            |  12 +-
 .../perf/tez/constraints/cbo_query11.q.out         |  26 +-
 .../perf/tez/constraints/cbo_query4.q.out          |  38 +-
 .../perf/tez/constraints/cbo_query74.q.out         |  26 +-
 9 files changed, 736 insertions(+), 172 deletions(-)

diff --git a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
index f6649f5..679962c 100644
--- a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
+++ b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
@@ -1788,7 +1788,7 @@ public class HiveConf extends Configuration {
         "Original plan cost multiplier for rewriting when query has tables joined multiple time on primary/unique key and " +
             "projected the majority of columns from these table. This optimization trims fields at root of tree and " +
             "then joins back affected tables at top of tree to get rest of columns. " +
-            "Set this to 0.0 to disable this optimization or increase it for more agressive optimization."),
+            "Set this to 0.0 to disable this optimization or increase it for more aggressive optimization."),
     AGGR_JOIN_TRANSPOSE("hive.transpose.aggr.join", false, "push aggregates through join"),
     SEMIJOIN_CONVERSION("hive.optimize.semijoin.conversion", true, "convert group by followed by inner equi join into semijoin"),
     HIVE_COLUMN_ALIGNMENT("hive.order.columnalignment", true, "Flag to control whether we want to try to align" +
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveCardinalityPreservingJoinOptimization.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveCardinalityPreservingJoinOptimization.java
index 6ad7724..d4b796a 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveCardinalityPreservingJoinOptimization.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveCardinalityPreservingJoinOptimization.java
@@ -17,10 +17,10 @@
  */
 package org.apache.hadoop.hive.ql.optimizer.calcite.rules;
 
-import static java.util.Arrays.asList;
 import static java.util.Collections.singletonList;
 
 import java.util.ArrayList;
+import java.util.BitSet;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -39,9 +39,11 @@ import org.apache.calcite.rel.type.RelDataTypeField;
 import org.apache.calcite.rex.RexBuilder;
 import org.apache.calcite.rex.RexInputRef;
 import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexShuttle;
 import org.apache.calcite.rex.RexTableInputRef;
 import org.apache.calcite.rex.RexUtil;
-import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.rex.RexVisitor;
+import org.apache.calcite.rex.RexVisitorImpl;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.tools.RelBuilder;
 import org.apache.calcite.util.ImmutableBitSet;
@@ -103,7 +105,7 @@ public class HiveCardinalityPreservingJoinOptimization extends HiveRelFieldTrimm
   public RelNode trim(RelBuilder relBuilder, RelNode root) {
     try {
       if (root.getInputs().size() != 1) {
-        LOG.debug("Only plans where root has one input are supported. Root: " + root);
+        LOG.debug("Only plans where root has one input are supported. Root: {}", root);
         return root;
       }
 
@@ -112,34 +114,45 @@ public class HiveCardinalityPreservingJoinOptimization extends HiveRelFieldTrimm
       RexBuilder rexBuilder = relBuilder.getRexBuilder();
       RelNode rootInput = root.getInput(0);
 
-      // Build the list of projected fields from root's input RowType
+      // Build the list of RexInputRef from root input RowType
       List<RexInputRef> rootFieldList = new ArrayList<>(rootInput.getRowType().getFieldCount());
+      List<String> newColumnNames = new ArrayList<>();
       for (int i = 0; i < rootInput.getRowType().getFieldList().size(); ++i) {
         RelDataTypeField relDataTypeField = rootInput.getRowType().getFieldList().get(i);
         rootFieldList.add(rexBuilder.makeInputRef(relDataTypeField.getType(), i));
+        newColumnNames.add(relDataTypeField.getName());
       }
 
-      List<ProjectedFields> lineages = getExpressionLineageOf(rootFieldList, rootInput);
+      List<JoinedBackFields> lineages = getExpressionLineageOf(rootFieldList, rootInput);
       if (lineages == null) {
         LOG.debug("Some projected field lineage can not be determined");
         return root;
       }
 
-      // 1. Collect candidate tables for join back
-      // 2. Collect all used fields from original plan
+      // 1. Collect candidate tables for join back and map RexNodes coming from those tables to their index in the
+      // rootInput row type
+      // Collect all used fields from original plan
       ImmutableBitSet fieldsUsed = ImmutableBitSet.of();
-      List<TableToJoinBack> tableToJoinBackList = new ArrayList<>();
-      for (ProjectedFields projectedFields : lineages) {
-        Optional<ImmutableBitSet> projectedKeys = projectedFields.relOptHiveTable.getNonNullableKeys().stream()
-            .filter(projectedFields.fieldsInSourceTable::contains)
+      List<TableToJoinBack> tableToJoinBackList = new ArrayList<>(lineages.size());
+      Map<Integer, RexNode> rexNodesToShuttle = new HashMap<>(rootInput.getRowType().getFieldCount());
+
+      for (JoinedBackFields joinedBackFields : lineages) {
+        Optional<ImmutableBitSet> projectedKeys = joinedBackFields.relOptHiveTable.getNonNullableKeys().stream()
+            .filter(joinedBackFields.fieldsInSourceTable::contains)
             .findFirst();
 
-        if (projectedKeys.isPresent()) {
-          TableToJoinBack tableToJoinBack = new TableToJoinBack(projectedKeys.get(), projectedFields);
+        if (projectedKeys.isPresent() && !projectedKeys.get().equals(joinedBackFields.fieldsInSourceTable)) {
+          TableToJoinBack tableToJoinBack = new TableToJoinBack(projectedKeys.get(), joinedBackFields);
           tableToJoinBackList.add(tableToJoinBack);
-          fieldsUsed = fieldsUsed.union(projectedFields.getSource(projectedKeys.get()));
+          fieldsUsed = fieldsUsed.union(joinedBackFields.getSource(projectedKeys.get()));
+
+          for (TableInputRefHolder mapping : joinedBackFields.mapping) {
+            if (!fieldsUsed.get(mapping.indexInOriginalRowType)) {
+              rexNodesToShuttle.put(mapping.indexInOriginalRowType, mapping.rexNode);
+            }
+          }
         } else {
-          fieldsUsed = fieldsUsed.union(projectedFields.fieldsInRootProject);
+          fieldsUsed = fieldsUsed.union(joinedBackFields.fieldsInOriginalRowType);
         }
       }
 
@@ -148,7 +161,7 @@ public class HiveCardinalityPreservingJoinOptimization extends HiveRelFieldTrimm
         return root;
       }
 
-      // 3. Trim out non-key fields of joined back tables
+      // 2. Trim out non-key fields of joined back tables
       Set<RelDataTypeField> extraFields = Collections.emptySet();
       TrimResult trimResult = dispatchTrimFields(rootInput, fieldsUsed, extraFields);
       RelNode newInput = trimResult.left;
@@ -157,62 +170,70 @@ public class HiveCardinalityPreservingJoinOptimization extends HiveRelFieldTrimm
         return root;
       }
 
-      // 4. Collect fields for new Project on the top of Join backs
+      // 3. Join back tables to the top of original plan
       Mapping newInputMapping = trimResult.right;
-      RexNode[] newProjects = new RexNode[rootFieldList.size()];
-      String[] newColumnNames = new String[rootFieldList.size()];
-      projectsFromOriginalPlan(rexBuilder, newInput.getRowType().getFieldCount(), newInput, newInputMapping,
-          newProjects, newColumnNames);
+      Map<RexTableInputRef, Integer> tableInputRefMapping = new HashMap<>();
 
-      // 5. Join back tables to the top of original plan
       for (TableToJoinBack tableToJoinBack : tableToJoinBackList) {
-        LOG.debug("Joining back table " + tableToJoinBack.projectedFields.relOptHiveTable.getName());
+        LOG.debug("Joining back table {}", tableToJoinBack.joinedBackFields.relOptHiveTable.getName());
 
-        // 5.1 Create new TableScan of tables to join back
-        RelOptHiveTable relOptTable = tableToJoinBack.projectedFields.relOptHiveTable;
+        // 3.1. Create new TableScan of tables to join back
+        RelOptHiveTable relOptTable = tableToJoinBack.joinedBackFields.relOptHiveTable;
         RelOptCluster cluster = relBuilder.getCluster();
         HiveTableScan tableScan = new HiveTableScan(cluster, cluster.traitSetOf(HiveRelNode.CONVENTION),
             relOptTable, relOptTable.getHiveTableMD().getTableName(), null, false, false);
-        // 5.2 Project only required fields from this table
+        // 3.2. Create Project with the required fields from this table
         RelNode projectTableAccessRel = tableScan.project(
-            tableToJoinBack.projectedFields.fieldsInSourceTable, new HashSet<>(0), REL_BUILDER.get());
+            tableToJoinBack.joinedBackFields.fieldsInSourceTable, new HashSet<>(0), REL_BUILDER.get());
 
-        Mapping keyMapping = Mappings.create(MappingType.INVERSE_SURJECTION,
-            tableScan.getRowType().getFieldCount(), tableToJoinBack.keys.cardinality());
+        // 3.3. Create mapping between the Project and TableScan
+        Mapping projectMapping = Mappings.create(MappingType.INVERSE_SURJECTION,
+            tableScan.getRowType().getFieldCount(),
+            tableToJoinBack.joinedBackFields.fieldsInSourceTable.cardinality());
         int projectIndex = 0;
+        for (int i : tableToJoinBack.joinedBackFields.fieldsInSourceTable) {
+          projectMapping.set(i, projectIndex);
+          ++projectIndex;
+        }
+
         int offset = newInput.getRowType().getFieldCount();
 
-        for (int source : tableToJoinBack.projectedFields.fieldsInSourceTable) {
-          if (tableToJoinBack.keys.get(source)) {
-            // 5.3 Map key field to it's index in the Project on the TableScan
-            keyMapping.set(source, projectIndex);
-          } else {
-            // 5.4 if this is not a key field then we need it in the new Project on the top of Join backs
-            ProjectMapping currentProjectMapping =
-                tableToJoinBack.projectedFields.mapping.stream()
-                    .filter(projectMapping -> projectMapping.indexInSourceTable == source)
-                    .findFirst().get();
-            addToProject(projectTableAccessRel, projectIndex, rexBuilder,
-                offset + projectIndex,
-                currentProjectMapping.indexInRootProject,
-                newProjects, newColumnNames);
+        // 3.4. Map rexTableInputRef to the index where it can be found in the new Input row type
+        for (TableInputRefHolder mapping : tableToJoinBack.joinedBackFields.mapping) {
+          int indexInSourceTable = mapping.tableInputRef.getIndex();
+          if (!tableToJoinBack.keys.get(indexInSourceTable)) {
+            // 3.5. if this is not a key field it is shifted by the left input field count
+            tableInputRefMapping.put(mapping.tableInputRef, offset + projectMapping.getTarget(indexInSourceTable));
           }
-          ++projectIndex;
         }
 
-        // 5.5 Create Join
+        // 3.7. Create Join
         relBuilder.push(newInput);
         relBuilder.push(projectTableAccessRel);
 
         RexNode joinCondition = joinCondition(
-            newInput, newInputMapping, tableToJoinBack, projectTableAccessRel, keyMapping, rexBuilder);
+            newInput, newInputMapping, tableToJoinBack, projectTableAccessRel, projectMapping, rexBuilder);
 
         newInput = relBuilder.join(JoinRelType.INNER, joinCondition).build();
       }
 
-      // 6 Create Project on top of all Join backs
+      // 4. Collect rexNodes for Project
+      TableInputRefMapper mapper = new TableInputRefMapper(tableInputRefMapping, rexBuilder, newInput);
+      List<RexNode> rexNodeList = new ArrayList<>(rootInput.getRowType().getFieldCount());
+      for (int i = 0; i < rootInput.getRowType().getFieldCount(); i++) {
+        RexNode rexNode = rexNodesToShuttle.get(i);
+        if (rexNode != null) {
+          rexNodeList.add(mapper.apply(rexNode));
+        } else {
+          int target = newInputMapping.getTarget(i);
+          rexNodeList.add(
+              rexBuilder.makeInputRef(newInput.getRowType().getFieldList().get(target).getType(), target));
+        }
+      }
+
+      // 5. Create Project on top of all Join backs
       relBuilder.push(newInput);
-      relBuilder.project(asList(newProjects), asList(newColumnNames));
+      relBuilder.project(rexNodeList, newColumnNames);
 
       return root.copy(root.getTraitSet(), singletonList(relBuilder.build()));
     } finally {
@@ -220,32 +241,28 @@ public class HiveCardinalityPreservingJoinOptimization extends HiveRelFieldTrimm
     }
   }
 
-  private List<ProjectedFields> getExpressionLineageOf(
+  private List<JoinedBackFields> getExpressionLineageOf(
       List<RexInputRef> projectExpressions, RelNode projectInput) {
     RelMetadataQuery relMetadataQuery = RelMetadataQuery.instance();
-    Map<RexTableInputRef.RelTableRef, ProjectedFieldsBuilder> fieldMappingBuilders = new HashMap<>();
+    Map<RexTableInputRef.RelTableRef, JoinedBackFieldsBuilder> fieldMappingBuilders = new HashMap<>();
     List<RexTableInputRef.RelTableRef> tablesOrdered = new ArrayList<>(); // use this list to keep the order of tables
     for (RexInputRef expr : projectExpressions) {
       Set<RexNode> expressionLineage = relMetadataQuery.getExpressionLineage(projectInput, expr);
       if (expressionLineage == null || expressionLineage.size() != 1) {
-        LOG.debug("Lineage can not be determined of expression: " + expr);
+        LOG.debug("Lineage of expression in node {} can not be determined: {}", projectInput, expr);
         return null;
       }
 
       RexNode rexNode = expressionLineage.iterator().next();
-      RexTableInputRef rexTableInputRef = rexTableInputRef(rexNode);
-      if (rexTableInputRef == null) {
-        LOG.debug("Unable determine expression lineage " + rexNode);
-        return null;
+      for (RexTableInputRef rexTableInputRef : rexTableInputRef(rexNode)) {
+        RexTableInputRef.RelTableRef tableRef = rexTableInputRef.getTableRef();
+        JoinedBackFieldsBuilder joinedBackFieldsBuilder = fieldMappingBuilders.computeIfAbsent(
+            tableRef, k -> {
+              tablesOrdered.add(tableRef);
+              return new JoinedBackFieldsBuilder(tableRef);
+            });
+        joinedBackFieldsBuilder.add(expr, rexNode, rexTableInputRef);
       }
-
-      RexTableInputRef.RelTableRef tableRef = rexTableInputRef.getTableRef();
-      ProjectedFieldsBuilder projectedFieldsBuilder = fieldMappingBuilders.computeIfAbsent(
-          tableRef, k -> {
-            tablesOrdered.add(tableRef);
-            return new ProjectedFieldsBuilder(tableRef);
-          });
-      projectedFieldsBuilder.add(expr, rexTableInputRef);
     }
 
     return tablesOrdered.stream()
@@ -253,31 +270,18 @@ public class HiveCardinalityPreservingJoinOptimization extends HiveRelFieldTrimm
         .collect(Collectors.toList());
   }
 
-  public RexTableInputRef rexTableInputRef(RexNode rexNode) {
-    if (rexNode.getKind() == SqlKind.TABLE_INPUT_REF) {
-      return (RexTableInputRef) rexNode;
-    }
-    LOG.debug("Unable determine expression lineage " + rexNode);
-    return null;
-  }
-
-  private void projectsFromOriginalPlan(RexBuilder rexBuilder, int count, RelNode newInput, Mapping newInputMapping,
-                                        RexNode[] newProjects, String[] newColumnNames) {
-    for (int newProjectIndex = 0; newProjectIndex < count; ++newProjectIndex) {
-      addToProject(newInput, newProjectIndex, rexBuilder, newProjectIndex, newInputMapping.getSource(newProjectIndex),
-          newProjects, newColumnNames);
-    }
-  }
+  public List<RexTableInputRef> rexTableInputRef(RexNode rexNode) {
+    List<RexTableInputRef> rexTableInputRefList = new ArrayList<>();
+    RexVisitor<RexTableInputRef> visitor = new RexVisitorImpl<RexTableInputRef>(true) {
+      @Override
+      public RexTableInputRef visitTableInputRef(RexTableInputRef ref) {
+        rexTableInputRefList.add(ref);
+        return ref;
+      }
+    };
 
-  private void addToProject(RelNode relNode, int projectSourceIndex, RexBuilder rexBuilder,
-                             int targetIndex, int index,
-                             RexNode[] newProjects, String[] newColumnNames) {
-    RelDataTypeField relDataTypeField =
-        relNode.getRowType().getFieldList().get(projectSourceIndex);
-    newProjects[index] = rexBuilder.makeInputRef(
-        relDataTypeField.getType(),
-        targetIndex);
-    newColumnNames[index] = relDataTypeField.getName();
+    rexNode.accept(visitor);
+    return rexTableInputRefList;
   }
 
   private RexNode joinCondition(
@@ -286,14 +290,18 @@ public class HiveCardinalityPreservingJoinOptimization extends HiveRelFieldTrimm
       RexBuilder rexBuilder) {
 
     List<RexNode> equalsConditions = new ArrayList<>(tableToJoinBack.keys.size());
-    for (ProjectMapping projectMapping : tableToJoinBack.projectedFields.mapping) {
-      if (!tableToJoinBack.keys.get(projectMapping.indexInSourceTable)) {
+    BitSet usedKeys = new BitSet(0);
+    for (TableInputRefHolder tableInputRefHolder : tableToJoinBack.joinedBackFields.mapping) {
+      if (usedKeys.get(tableInputRefHolder.tableInputRef.getIndex()) ||
+          !tableToJoinBack.keys.get(tableInputRefHolder.tableInputRef.getIndex())) {
         continue;
       }
 
-      int leftKeyIndex = leftInputMapping.getTarget(projectMapping.indexInRootProject);
+      usedKeys.set(tableInputRefHolder.tableInputRef.getIndex());
+
+      int leftKeyIndex = leftInputMapping.getTarget(tableInputRefHolder.indexInOriginalRowType);
       RelDataTypeField leftKeyField = leftInput.getRowType().getFieldList().get(leftKeyIndex);
-      int rightKeyIndex = rightInputKeyMapping.getTarget(projectMapping.indexInSourceTable);
+      int rightKeyIndex = rightInputKeyMapping.getTarget(tableInputRefHolder.tableInputRef.getIndex());
       RelDataTypeField rightKeyField = rightInput.getRowType().getFieldList().get(rightKeyIndex);
 
       equalsConditions.add(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
@@ -304,74 +312,94 @@ public class HiveCardinalityPreservingJoinOptimization extends HiveRelFieldTrimm
     return RexUtil.composeConjunction(rexBuilder, equalsConditions);
   }
 
-  private static final class ProjectMapping {
-    private final int indexInRootProject;
-    private final int indexInSourceTable;
+  private static final class TableInputRefHolder {
+    private final RexTableInputRef tableInputRef;
+    private final RexNode rexNode;
+    private final int indexInOriginalRowType;
 
-    private ProjectMapping(int indexInRootProject, RexTableInputRef rexTableInputRef) {
-      this.indexInRootProject = indexInRootProject;
-      this.indexInSourceTable = rexTableInputRef.getIndex();
+    private TableInputRefHolder(RexInputRef inputRef, RexNode rexNode, RexTableInputRef sourceTableRef) {
+      this.indexInOriginalRowType = inputRef.getIndex();
+      this.rexNode = rexNode;
+      this.tableInputRef = sourceTableRef;
     }
   }
 
-  private static final class ProjectedFields {
+  private static final class JoinedBackFields {
     private final RelOptHiveTable relOptHiveTable;
-    private final ImmutableBitSet fieldsInRootProject;
+    private final ImmutableBitSet fieldsInOriginalRowType;
     private final ImmutableBitSet fieldsInSourceTable;
-    private final List<ProjectMapping> mapping;
+    private final List<TableInputRefHolder> mapping;
 
-    private ProjectedFields(RexTableInputRef.RelTableRef relTableRef,
-                            ImmutableBitSet fieldsInRootProject, ImmutableBitSet fieldsInSourceTable,
-                            List<ProjectMapping> mapping) {
+    private JoinedBackFields(RexTableInputRef.RelTableRef relTableRef,
+                             ImmutableBitSet fieldsInOriginalRowType, ImmutableBitSet fieldsInSourceTable,
+                             List<TableInputRefHolder> mapping) {
       this.relOptHiveTable = (RelOptHiveTable) relTableRef.getTable();
-      this.fieldsInRootProject = fieldsInRootProject;
+      this.fieldsInOriginalRowType = fieldsInOriginalRowType;
       this.fieldsInSourceTable = fieldsInSourceTable;
       this.mapping = mapping;
     }
 
     public ImmutableBitSet getSource(ImmutableBitSet fields) {
       ImmutableBitSet.Builder targetFieldsBuilder = ImmutableBitSet.builder();
-      for (ProjectMapping fieldMapping : mapping) {
-        if (fields.get(fieldMapping.indexInSourceTable)) {
-          targetFieldsBuilder.set(fieldMapping.indexInRootProject);
+      for (TableInputRefHolder fieldMapping : mapping) {
+        if (fields.get(fieldMapping.tableInputRef.getIndex())) {
+          targetFieldsBuilder.set(fieldMapping.indexInOriginalRowType);
         }
       }
       return targetFieldsBuilder.build();
     }
   }
 
-  private static class ProjectedFieldsBuilder {
+  private static class JoinedBackFieldsBuilder {
     private final RexTableInputRef.RelTableRef relTableRef;
-    private final ImmutableBitSet.Builder fieldsInRootProjectBuilder = ImmutableBitSet.builder();
+    private final ImmutableBitSet.Builder fieldsInOriginalRowTypeBuilder = ImmutableBitSet.builder();
     private final ImmutableBitSet.Builder fieldsInSourceTableBuilder = ImmutableBitSet.builder();
-    private final List<ProjectMapping> mapping = new ArrayList<>();
+    private final List<TableInputRefHolder> mapping = new ArrayList<>();
 
-    private ProjectedFieldsBuilder(RexTableInputRef.RelTableRef relTableRef) {
+    private JoinedBackFieldsBuilder(RexTableInputRef.RelTableRef relTableRef) {
       this.relTableRef = relTableRef;
     }
 
-    public void add(RexInputRef rexInputRef, RexTableInputRef sourceTableInputRef) {
-      fieldsInRootProjectBuilder.set(rexInputRef.getIndex());
+    public void add(RexInputRef rexInputRef, RexNode rexNode, RexTableInputRef sourceTableInputRef) {
+      fieldsInOriginalRowTypeBuilder.set(rexInputRef.getIndex());
       fieldsInSourceTableBuilder.set(sourceTableInputRef.getIndex());
-      mapping.add(new ProjectMapping(rexInputRef.getIndex(), sourceTableInputRef));
+      mapping.add(new TableInputRefHolder(rexInputRef, rexNode, sourceTableInputRef));
     }
 
-    public ProjectedFields build() {
-      return new ProjectedFields(relTableRef,
-          fieldsInRootProjectBuilder.build(),
+    public JoinedBackFields build() {
+      return new JoinedBackFields(relTableRef,
+          fieldsInOriginalRowTypeBuilder.build(),
           fieldsInSourceTableBuilder.build(),
           mapping);
     }
   }
 
   private static final class TableToJoinBack {
-    private final ProjectedFields projectedFields;
+    private final JoinedBackFields joinedBackFields;
     private final ImmutableBitSet keys;
 
-    private TableToJoinBack(ImmutableBitSet keys, ProjectedFields projectedFields) {
-      this.projectedFields = projectedFields;
+    private TableToJoinBack(ImmutableBitSet keys, JoinedBackFields joinedBackFields) {
+      this.joinedBackFields = joinedBackFields;
       this.keys = keys;
     }
   }
+
+  private static final class TableInputRefMapper extends RexShuttle {
+    private final Map<RexTableInputRef, Integer> tableInputRefMapping;
+    private final RexBuilder rexBuilder;
+    private final RelNode newInput;
+
+    private TableInputRefMapper(Map<RexTableInputRef, Integer> tableInputRefMapping, RexBuilder rexBuilder, RelNode newInput) {
+      this.tableInputRefMapping = tableInputRefMapping;
+      this.rexBuilder = rexBuilder;
+      this.newInput = newInput;
+    }
+
+    @Override
+    public RexNode visitTableInputRef(RexTableInputRef ref) {
+      int source = tableInputRefMapping.get(ref);
+      return rexBuilder.makeInputRef(newInput.getRowType().getFieldList().get(source).getType(), source);
+    }
+  }
 }
 
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveCardinalityPreservingJoinRule.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveCardinalityPreservingJoinRule.java
index c49270a..f3d2082 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveCardinalityPreservingJoinRule.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveCardinalityPreservingJoinRule.java
@@ -24,6 +24,9 @@ import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rel.metadata.JaninoRelMetadataProvider;
 import org.apache.calcite.rel.metadata.RelMetadataQuery;
 import org.apache.hadoop.hive.ql.optimizer.calcite.HiveTezModelRelMetadataProvider;
+import org.apache.hadoop.hive.ql.optimizer.calcite.HiveRelShuttleImpl;
+import org.apache.hadoop.hive.ql.optimizer.calcite.cost.HiveDefaultCostModel;
+import org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveJoin;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -47,10 +50,17 @@ public class HiveCardinalityPreservingJoinRule extends HiveFieldTrimmerRule {
       return node;
     }
 
+    RelNode chosen = choosePlan(node, optimized);
+    new JoinAlgorithmSetter().visit(chosen);
+    return chosen;
+  }
+
+  private RelNode choosePlan(RelNode node, RelNode optimized) {
     JaninoRelMetadataProvider original = RelMetadataQuery.THREAD_PROVIDERS.get();
     try {
       RelMetadataQuery.THREAD_PROVIDERS.set(
           HiveTezModelRelMetadataProvider.DEFAULT);
+      node.getCluster().invalidateMetadataQuery();
       RelMetadataQuery metadataQuery = RelMetadataQuery.instance();
 
       RelOptCost optimizedCost = metadataQuery.getCumulativeCost(optimized);
@@ -67,8 +77,16 @@ public class HiveCardinalityPreservingJoinRule extends HiveFieldTrimmerRule {
       return node;
     }
     finally {
+      node.getCluster().invalidateMetadataQuery();
       RelMetadataQuery.THREAD_PROVIDERS.set(original);
     }
   }
 
+  private static class JoinAlgorithmSetter extends HiveRelShuttleImpl {
+    @Override
+    public RelNode visit(HiveJoin join) {
+      join.setJoinAlgorithm(HiveDefaultCostModel.DefaultJoinAlgorithm.INSTANCE);
+      return super.visit(join);
+    }
+  }
 }
diff --git a/ql/src/test/queries/clientpositive/cardinality_preserving_join_opt.q b/ql/src/test/queries/clientpositive/cardinality_preserving_join_opt.q
new file mode 100644
index 0000000..037620c
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/cardinality_preserving_join_opt.q
@@ -0,0 +1,127 @@
+create table if not exists customer
+(
+    c_first_name            string,
+    c_last_name             string,
+    c_customer_sk           bigint,
+    c_discount              float
+);
+
+create table store_sales
+(
+    ss_quantity            float,
+    ss_customer_sk         int,
+    ss_list_price          float
+);
+
+insert into customer(c_customer_sk, c_first_name, c_last_name, c_discount) values (1, 'John', 'Doe', 0.15);
+insert into store_sales(ss_customer_sk, ss_quantity, ss_list_price) values (1, 10.0, 2.5);
+
+-- Turn off optimization to have a reference
+set hive.cardinality.preserving.join.optimization.factor=0.0;
+
+explain cbo
+select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk;
+
+select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk;
+
+-- Force optimization
+set hive.cardinality.preserving.join.optimization.factor=10.0;
+
+-- Only store_sales table should be joined back
+alter table store_sales add constraint pk_c primary key (ss_customer_sk) disable novalidate rely;
+
+explain cbo
+select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk;
+
+select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk;
+
+
+-- Only customer table should be joined back
+alter table store_sales drop constraint pk_c;
+alter table customer add constraint pk_c primary key (c_customer_sk) disable novalidate rely;
+
+explain cbo
+select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk;
+
+select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk;
+
+
+-- Both tables should be joined back
+alter table store_sales add constraint pk_c primary key (ss_customer_sk) disable novalidate rely;
+
+explain cbo
+select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk;
+
+select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk;
+
+-- Table store_sales is not joined back: only the key is projected
+explain cbo
+select
+    c_first_name,
+    ss_customer_sk,
+    c_customer_sk
+from store_sales ss
+join customer on c_customer_sk = ss_customer_sk;
+
+select
+    c_first_name,
+    ss_customer_sk,
+    c_customer_sk
+from store_sales ss
+join customer on c_customer_sk = ss_customer_sk;
diff --git a/ql/src/test/results/clientpositive/llap/cardinality_preserving_join_opt.q.out b/ql/src/test/results/clientpositive/llap/cardinality_preserving_join_opt.q.out
new file mode 100644
index 0000000..28a1c83
--- /dev/null
+++ b/ql/src/test/results/clientpositive/llap/cardinality_preserving_join_opt.q.out
@@ -0,0 +1,391 @@
+PREHOOK: query: create table if not exists customer
+(
+    c_first_name            string,
+    c_last_name             string,
+    c_customer_sk           bigint,
+    c_discount              float
+)
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@customer
+POSTHOOK: query: create table if not exists customer
+(
+    c_first_name            string,
+    c_last_name             string,
+    c_customer_sk           bigint,
+    c_discount              float
+)
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@customer
+PREHOOK: query: create table store_sales
+(
+    ss_quantity            float,
+    ss_customer_sk         int,
+    ss_list_price          float
+)
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@store_sales
+POSTHOOK: query: create table store_sales
+(
+    ss_quantity            float,
+    ss_customer_sk         int,
+    ss_list_price          float
+)
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@store_sales
+PREHOOK: query: insert into customer(c_customer_sk, c_first_name, c_last_name, c_discount) values (1, 'John', 'Doe', 0.15)
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+PREHOOK: Output: default@customer
+POSTHOOK: query: insert into customer(c_customer_sk, c_first_name, c_last_name, c_discount) values (1, 'John', 'Doe', 0.15)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+POSTHOOK: Output: default@customer
+POSTHOOK: Lineage: customer.c_customer_sk SCRIPT []
+POSTHOOK: Lineage: customer.c_discount SCRIPT []
+POSTHOOK: Lineage: customer.c_first_name SCRIPT []
+POSTHOOK: Lineage: customer.c_last_name SCRIPT []
+PREHOOK: query: insert into store_sales(ss_customer_sk, ss_quantity, ss_list_price) values (1, 10.0, 2.5)
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+PREHOOK: Output: default@store_sales
+POSTHOOK: query: insert into store_sales(ss_customer_sk, ss_quantity, ss_list_price) values (1, 10.0, 2.5)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+POSTHOOK: Output: default@store_sales
+POSTHOOK: Lineage: store_sales.ss_customer_sk SCRIPT []
+POSTHOOK: Lineage: store_sales.ss_list_price SCRIPT []
+POSTHOOK: Lineage: store_sales.ss_quantity SCRIPT []
+PREHOOK: query: explain cbo
+select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk
+PREHOOK: type: QUERY
+PREHOOK: Input: default@customer
+PREHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+POSTHOOK: query: explain cbo
+select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@customer
+POSTHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+CBO PLAN:
+HiveProject(c_first_name=[$3], _o__c1=[$5], _o__c2=[*($1, $6)], c_customer_sk=[$4], ss_customer_sk=[$0])
+  HiveJoin(condition=[=($2, $4)], joinType=[inner], algorithm=[none], cost=[not available])
+    HiveProject(ss_customer_sk=[$1], *=[*(+($0, $0), $2)], CAST=[CAST($1):BIGINT])
+      HiveFilter(condition=[IS NOT NULL(CAST($1):BIGINT)])
+        HiveTableScan(table=[[default, store_sales]], table:alias=[ss])
+    HiveProject(c_first_name=[$0], c_customer_sk=[$2], ||=[||(||(||(||($0, _UTF-16LE' '), $1), _UTF-16LE' '), $1)], -=[-(1, $3)])
+      HiveFilter(condition=[IS NOT NULL($2)])
+        HiveTableScan(table=[[default, customer]], table:alias=[c])
+
+PREHOOK: query: select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk
+PREHOOK: type: QUERY
+PREHOOK: Input: default@customer
+PREHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+POSTHOOK: query: select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@customer
+POSTHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+John	John Doe Doe	42.5	1	1
+PREHOOK: query: alter table store_sales add constraint pk_c primary key (ss_customer_sk) disable novalidate rely
+PREHOOK: type: ALTERTABLE_ADDCONSTRAINT
+POSTHOOK: query: alter table store_sales add constraint pk_c primary key (ss_customer_sk) disable novalidate rely
+POSTHOOK: type: ALTERTABLE_ADDCONSTRAINT
+PREHOOK: query: explain cbo
+select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk
+PREHOOK: type: QUERY
+PREHOOK: Input: default@customer
+PREHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+POSTHOOK: query: explain cbo
+select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@customer
+POSTHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+CBO PLAN:
+HiveProject(c_first_name=[$2], _o__c1=[$4], _o__c2=[*(*(+($6, $6), $8), $5)], c_customer_sk=[$3], ss_customer_sk=[$0])
+  HiveJoin(condition=[=($0, $7)], joinType=[inner], algorithm=[none], cost=[not available])
+    HiveJoin(condition=[=($1, $3)], joinType=[inner], algorithm=[none], cost=[not available])
+      HiveProject(ss_customer_sk=[$0], CAST=[CAST($0):BIGINT])
+        HiveFilter(condition=[IS NOT NULL(CAST($0):BIGINT)])
+          HiveProject(ss_customer_sk=[$1])
+            HiveTableScan(table=[[default, store_sales]], table:alias=[ss])
+      HiveProject(c_first_name=[$0], c_customer_sk=[$2], ||=[||(||(||(||($0, _UTF-16LE' '), $1), _UTF-16LE' '), $1)], -=[-(1, $3)])
+        HiveFilter(condition=[IS NOT NULL($2)])
+          HiveProject(c_first_name=[$0], c_last_name=[$1], c_customer_sk=[$2], c_discount=[$3])
+            HiveTableScan(table=[[default, customer]], table:alias=[c])
+    HiveProject(ss_quantity=[$0], ss_customer_sk=[$1], ss_list_price=[$2])
+      HiveTableScan(table=[[default, store_sales]], table:alias=[store_sales])
+
+PREHOOK: query: select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk
+PREHOOK: type: QUERY
+PREHOOK: Input: default@customer
+PREHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+POSTHOOK: query: select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@customer
+POSTHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+John	John Doe Doe	42.5	1	1
+PREHOOK: query: alter table store_sales drop constraint pk_c
+PREHOOK: type: ALTERTABLE_DROPCONSTRAINT
+POSTHOOK: query: alter table store_sales drop constraint pk_c
+POSTHOOK: type: ALTERTABLE_DROPCONSTRAINT
+PREHOOK: query: alter table customer add constraint pk_c primary key (c_customer_sk) disable novalidate rely
+PREHOOK: type: ALTERTABLE_ADDCONSTRAINT
+POSTHOOK: query: alter table customer add constraint pk_c primary key (c_customer_sk) disable novalidate rely
+POSTHOOK: type: ALTERTABLE_ADDCONSTRAINT
+PREHOOK: query: explain cbo
+select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk
+PREHOOK: type: QUERY
+PREHOOK: Input: default@customer
+PREHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+POSTHOOK: query: explain cbo
+select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@customer
+POSTHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+CBO PLAN:
+HiveProject(c_first_name=[$4], _o__c1=[||(||(||(||($4, _UTF-16LE' '), $5), _UTF-16LE' '), $5)], _o__c2=[*($1, -(1, $7))], c_customer_sk=[$3], ss_customer_sk=[$0])
+  HiveJoin(condition=[=($3, $6)], joinType=[inner], algorithm=[none], cost=[not available])
+    HiveJoin(condition=[=($2, $3)], joinType=[inner], algorithm=[none], cost=[not available])
+      HiveProject(ss_customer_sk=[$1], *=[*(+($0, $0), $2)], CAST=[CAST($1):BIGINT])
+        HiveFilter(condition=[IS NOT NULL(CAST($1):BIGINT)])
+          HiveProject(ss_quantity=[$0], ss_customer_sk=[$1], ss_list_price=[$2])
+            HiveTableScan(table=[[default, store_sales]], table:alias=[ss])
+      HiveProject(c_customer_sk=[$2])
+        HiveTableScan(table=[[default, customer]], table:alias=[c])
+    HiveProject(c_first_name=[$0], c_last_name=[$1], c_customer_sk=[$2], c_discount=[$3])
+      HiveTableScan(table=[[default, customer]], table:alias=[customer])
+
+PREHOOK: query: select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk
+PREHOOK: type: QUERY
+PREHOOK: Input: default@customer
+PREHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+POSTHOOK: query: select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@customer
+POSTHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+John	John Doe Doe	42.5	1	1
+PREHOOK: query: alter table store_sales add constraint pk_c primary key (ss_customer_sk) disable novalidate rely
+PREHOOK: type: ALTERTABLE_ADDCONSTRAINT
+POSTHOOK: query: alter table store_sales add constraint pk_c primary key (ss_customer_sk) disable novalidate rely
+POSTHOOK: type: ALTERTABLE_ADDCONSTRAINT
+PREHOOK: query: explain cbo
+select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk
+PREHOOK: type: QUERY
+PREHOOK: Input: default@customer
+PREHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+POSTHOOK: query: explain cbo
+select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@customer
+POSTHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+CBO PLAN:
+HiveProject(c_first_name=[$6], _o__c1=[||(||(||(||($6, _UTF-16LE' '), $7), _UTF-16LE' '), $7)], _o__c2=[*(*(+($3, $3), $5), -(1, $9))], c_customer_sk=[$2], ss_customer_sk=[$0])
+  HiveJoin(condition=[=($2, $8)], joinType=[inner], algorithm=[none], cost=[not available])
+    HiveJoin(condition=[=($0, $4)], joinType=[inner], algorithm=[none], cost=[not available])
+      HiveJoin(condition=[=($1, $2)], joinType=[inner], algorithm=[none], cost=[not available])
+        HiveProject(ss_customer_sk=[$0], CAST=[CAST($0):BIGINT])
+          HiveFilter(condition=[IS NOT NULL(CAST($0):BIGINT)])
+            HiveProject(ss_customer_sk=[$1])
+              HiveTableScan(table=[[default, store_sales]], table:alias=[ss])
+        HiveProject(c_customer_sk=[$2])
+          HiveTableScan(table=[[default, customer]], table:alias=[c])
+      HiveProject(ss_quantity=[$0], ss_customer_sk=[$1], ss_list_price=[$2])
+        HiveTableScan(table=[[default, store_sales]], table:alias=[store_sales])
+    HiveProject(c_first_name=[$0], c_last_name=[$1], c_customer_sk=[$2], c_discount=[$3])
+      HiveTableScan(table=[[default, customer]], table:alias=[customer])
+
+PREHOOK: query: select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk
+PREHOOK: type: QUERY
+PREHOOK: Input: default@customer
+PREHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+POSTHOOK: query: select
+    c_first_name,
+    c_first_name || ' ' || c_last_name || ' ' || c_last_name,
+    ((ss_quantity + ss_quantity) * ss_list_price) * (1.0 - c_discount),
+    c_customer_sk,
+    ss_customer_sk
+from store_sales ss
+join customer c on ss_customer_sk = c_customer_sk
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@customer
+POSTHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+John	John Doe Doe	42.5	1	1
+PREHOOK: query: explain cbo
+select
+    c_first_name,
+    ss_customer_sk,
+    c_customer_sk
+from store_sales ss
+join customer on c_customer_sk = ss_customer_sk
+PREHOOK: type: QUERY
+PREHOOK: Input: default@customer
+PREHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+POSTHOOK: query: explain cbo
+select
+    c_first_name,
+    ss_customer_sk,
+    c_customer_sk
+from store_sales ss
+join customer on c_customer_sk = ss_customer_sk
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@customer
+POSTHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+CBO PLAN:
+HiveProject(c_first_name=[$3], ss_customer_sk=[$0], c_customer_sk=[$2])
+  HiveJoin(condition=[=($2, $4)], joinType=[inner], algorithm=[none], cost=[not available])
+    HiveJoin(condition=[=($2, $1)], joinType=[inner], algorithm=[none], cost=[not available])
+      HiveProject(ss_customer_sk=[$0], CAST=[CAST($0):BIGINT])
+        HiveFilter(condition=[IS NOT NULL(CAST($0):BIGINT)])
+          HiveProject(ss_customer_sk=[$1])
+            HiveTableScan(table=[[default, store_sales]], table:alias=[ss])
+      HiveProject(c_customer_sk=[$2])
+        HiveTableScan(table=[[default, customer]], table:alias=[customer])
+    HiveProject(c_first_name=[$0], c_customer_sk=[$2])
+      HiveTableScan(table=[[default, customer]], table:alias=[customer])
+
+PREHOOK: query: select
+    c_first_name,
+    ss_customer_sk,
+    c_customer_sk
+from store_sales ss
+join customer on c_customer_sk = ss_customer_sk
+PREHOOK: type: QUERY
+PREHOOK: Input: default@customer
+PREHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+POSTHOOK: query: select
+    c_first_name,
+    ss_customer_sk,
+    c_customer_sk
+from store_sales ss
+join customer on c_customer_sk = ss_customer_sk
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@customer
+POSTHOOK: Input: default@store_sales
+#### A masked pattern was here ####
+John	1	1
diff --git a/ql/src/test/results/clientpositive/llap/constraints_optimization.q.out b/ql/src/test/results/clientpositive/llap/constraints_optimization.q.out
index dd07139..c890e93 100644
--- a/ql/src/test/results/clientpositive/llap/constraints_optimization.q.out
+++ b/ql/src/test/results/clientpositive/llap/constraints_optimization.q.out
@@ -2212,7 +2212,7 @@ POSTHOOK: Input: default@store_sales
 #### A masked pattern was here ####
 CBO PLAN:
 HiveAggregate(group=[{1}])
-  HiveJoin(condition=[=($0, $8)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+  HiveJoin(condition=[=($0, $8)], joinType=[inner], algorithm=[none], cost=[not available])
     HiveProject(c_customer_sk=[$0], c_customer_id=[$1], c_first_name=[$8], c_last_name=[$9], c_preferred_cust_flag=[$10], c_birth_country=[$14], c_login=[$15], c_email_address=[$16])
       HiveTableScan(table=[[default, customer]], table:alias=[customer])
     HiveProject(ss_customer_sk=[$3])
@@ -2253,7 +2253,7 @@ POSTHOOK: Input: default@store_sales
 #### A masked pattern was here ####
 CBO PLAN:
 HiveAggregate(group=[{2}])
-  HiveJoin(condition=[=($1, $0)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+  HiveJoin(condition=[=($1, $0)], joinType=[inner], algorithm=[none], cost=[not available])
     HiveProject(ss_customer_sk=[$3])
       HiveFilter(condition=[IS NOT NULL($3)])
         HiveTableScan(table=[[default, store_sales]], table:alias=[store_sales])
@@ -2632,7 +2632,7 @@ POSTHOOK: Input: default@store_sales
 #### A masked pattern was here ####
 CBO PLAN:
 HiveAggregate(group=[{0}])
-  HiveJoin(condition=[=($0, $8)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+  HiveJoin(condition=[=($0, $8)], joinType=[inner], algorithm=[none], cost=[not available])
     HiveProject(c_customer_sk=[$0], c_customer_id=[$1], c_first_name=[$8], c_last_name=[$9], c_preferred_cust_flag=[$10], c_birth_country=[$14], c_login=[$15], c_email_address=[$16])
       HiveTableScan(table=[[default, customer]], table:alias=[customer])
     HiveProject(ss_customer_sk=[$3])
@@ -2687,7 +2687,7 @@ HiveProject(c_customer_id=[$1])
     HiveProject(c_customer_sk=[$0], c_customer_id=[$1])
       HiveTableScan(table=[[default, customer]], table:alias=[customer])
     HiveProject(c_customer_sk=[$0])
-      HiveJoin(condition=[=($0, $2)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+      HiveJoin(condition=[=($0, $2)], joinType=[inner], algorithm=[none], cost=[not available])
         HiveProject(c_customer_sk=[$0], c_customer_id=[$1])
           HiveTableScan(table=[[default, customer]], table:alias=[customer])
         HiveProject(ss_customer_sk=[$0])
@@ -2741,7 +2741,7 @@ HiveProject(c_first_name=[$1])
     HiveProject(c_customer_sk=[$0], c_first_name=[$8])
       HiveTableScan(table=[[default, customer]], table:alias=[customer])
     HiveProject(c_customer_sk=[$0])
-      HiveJoin(condition=[=($0, $2)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+      HiveJoin(condition=[=($0, $2)], joinType=[inner], algorithm=[none], cost=[not available])
         HiveProject(c_customer_sk=[$0], c_first_name=[$8])
           HiveTableScan(table=[[default, customer]], table:alias=[customer])
         HiveProject(ss_customer_sk=[$0])
@@ -2791,7 +2791,7 @@ POSTHOOK: Input: default@store_sales
 #### A masked pattern was here ####
 CBO PLAN:
 HiveAggregate(group=[{1}])
-  HiveJoin(condition=[=($0, $8)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+  HiveJoin(condition=[=($0, $8)], joinType=[inner], algorithm=[none], cost=[not available])
     HiveProject(c_customer_sk=[$0], c_customer_id=[$1], c_first_name=[$8], c_last_name=[$9], c_preferred_cust_flag=[$10], c_birth_country=[$14], c_login=[$15], c_email_address=[$16])
       HiveTableScan(table=[[default, customer]], table:alias=[customer])
     HiveProject(ss_customer_sk=[$3])
diff --git a/ql/src/test/results/clientpositive/perf/tez/constraints/cbo_query11.q.out b/ql/src/test/results/clientpositive/perf/tez/constraints/cbo_query11.q.out
index f57b728..6077fe9 100644
--- a/ql/src/test/results/clientpositive/perf/tez/constraints/cbo_query11.q.out
+++ b/ql/src/test/results/clientpositive/perf/tez/constraints/cbo_query11.q.out
@@ -170,18 +170,18 @@ POSTHOOK: Input: default@web_sales
 POSTHOOK: Output: hdfs://### HDFS PATH ###
 CBO PLAN:
 HiveSortLimit(sort0=[$0], sort1=[$1], sort2=[$2], sort3=[$3], dir0=[ASC], dir1=[ASC], dir2=[ASC], dir3=[ASC], fetch=[100])
-  HiveProject($f00=[$0], c_first_name=[$2], c_last_name=[$3], c_birth_country=[$4])
-    HiveJoin(condition=[=($0, $1)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+  HiveProject(customer_id=[$0], customer_first_name=[$2], customer_last_name=[$3], customer_birth_country=[$4])
+    HiveJoin(condition=[=($0, $1)], joinType=[inner], algorithm=[none], cost=[not available])
       HiveProject($f00=[$0])
-        HiveJoin(condition=[AND(CASE(IS NOT NULL($4), CASE($9, >(/($6, $8), /($2, $4)), >(0:DECIMAL(1, 0), /($2, $4))), CASE($9, >(/($6, $8), 0:DECIMAL(1, 0)), false)), =($0, $7))], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
-          HiveJoin(condition=[=($0, $5)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
-            HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[SMBJoin], cost=[not available])
+        HiveJoin(condition=[AND(CASE(IS NOT NULL($4), CASE($9, >(/($6, $8), /($2, $4)), >(0:DECIMAL(1, 0), /($2, $4))), CASE($9, >(/($6, $8), 0:DECIMAL(1, 0)), false)), =($0, $7))], joinType=[inner], algorithm=[none], cost=[not available])
+          HiveJoin(condition=[=($0, $5)], joinType=[inner], algorithm=[none], cost=[not available])
+            HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
               HiveProject(c_customer_id=[$0], c_birth_country=[$1], $f2=[$2])
                 HiveAggregate(group=[{1, 4}], agg#0=[sum($7)])
-                  HiveJoin(condition=[=($0, $6)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+                  HiveJoin(condition=[=($0, $6)], joinType=[inner], algorithm=[none], cost=[not available])
                     HiveProject(c_customer_sk=[$0], c_customer_id=[$1], c_first_name=[$8], c_last_name=[$9], c_birth_country=[$14])
                       HiveTableScan(table=[[default, customer]], table:alias=[customer])
-                    HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[MapJoin], cost=[not available])
+                    HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                       HiveProject(ss_sold_date_sk=[$0], ss_customer_sk=[$1], -=[-($3, $2)])
                         HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))])
                           HiveProject(ss_sold_date_sk=[$0], ss_customer_sk=[$3], ss_ext_discount_amt=[$14], ss_ext_list_price=[$17])
@@ -193,10 +193,10 @@ HiveSortLimit(sort0=[$0], sort1=[$1], sort2=[$2], sort3=[$3], dir0=[ASC], dir1=[
               HiveProject($f0=[$0], $f1=[$1])
                 HiveFilter(condition=[>($1, 0)])
                   HiveAggregate(group=[{1}], agg#0=[sum($4)])
-                    HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+                    HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                       HiveProject(c_customer_sk=[$0], c_customer_id=[$1])
                         HiveTableScan(table=[[default, customer]], table:alias=[customer])
-                      HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[MapJoin], cost=[not available])
+                      HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                         HiveProject(ss_sold_date_sk=[$0], ss_customer_sk=[$1], -=[-($3, $2)])
                           HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))])
                             HiveProject(ss_sold_date_sk=[$0], ss_customer_sk=[$3], ss_ext_discount_amt=[$14], ss_ext_list_price=[$17])
@@ -207,10 +207,10 @@ HiveSortLimit(sort0=[$0], sort1=[$1], sort2=[$2], sort3=[$3], dir0=[ASC], dir1=[
                               HiveTableScan(table=[[default, date_dim]], table:alias=[date_dim])
             HiveProject(c_customer_id=[$0], $f1=[$1])
               HiveAggregate(group=[{1}], agg#0=[sum($4)])
-                HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+                HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                   HiveProject(c_customer_sk=[$0], c_customer_id=[$1])
                     HiveTableScan(table=[[default, customer]], table:alias=[customer])
-                  HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[MapJoin], cost=[not available])
+                  HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                     HiveProject(ws_sold_date_sk=[$0], ws_bill_customer_sk=[$1], -=[-($3, $2)])
                       HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))])
                         HiveProject(ws_sold_date_sk=[$0], ws_bill_customer_sk=[$4], ws_ext_discount_amt=[$22], ws_ext_list_price=[$25])
@@ -222,10 +222,10 @@ HiveSortLimit(sort0=[$0], sort1=[$1], sort2=[$2], sort3=[$3], dir0=[ASC], dir1=[
           HiveProject(customer_id=[$0], year_total=[$1], CAST=[CAST(IS NOT NULL($1)):BOOLEAN])
             HiveFilter(condition=[>($1, 0)])
               HiveAggregate(group=[{1}], agg#0=[sum($4)])
-                HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+                HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                   HiveProject(c_customer_sk=[$0], c_customer_id=[$1])
                     HiveTableScan(table=[[default, customer]], table:alias=[customer])
-                  HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[MapJoin], cost=[not available])
+                  HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                     HiveProject(ws_sold_date_sk=[$0], ws_bill_customer_sk=[$1], -=[-($3, $2)])
                       HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))])
                         HiveProject(ws_sold_date_sk=[$0], ws_bill_customer_sk=[$4], ws_ext_discount_amt=[$22], ws_ext_list_price=[$25])
diff --git a/ql/src/test/results/clientpositive/perf/tez/constraints/cbo_query4.q.out b/ql/src/test/results/clientpositive/perf/tez/constraints/cbo_query4.q.out
index 6d5114b..8de33d6 100644
--- a/ql/src/test/results/clientpositive/perf/tez/constraints/cbo_query4.q.out
+++ b/ql/src/test/results/clientpositive/perf/tez/constraints/cbo_query4.q.out
@@ -242,17 +242,17 @@ POSTHOOK: Input: default@web_sales
 POSTHOOK: Output: hdfs://### HDFS PATH ###
 CBO PLAN:
 HiveSortLimit(sort0=[$0], sort1=[$1], sort2=[$2], sort3=[$3], dir0=[ASC], dir1=[ASC], dir2=[ASC], dir3=[ASC], fetch=[100])
-  HiveProject($f00=[$0], c_first_name=[$2], c_last_name=[$3], c_birth_country=[$4])
-    HiveJoin(condition=[=($0, $1)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+  HiveProject(customer_id=[$0], customer_first_name=[$2], customer_last_name=[$3], customer_birth_country=[$4])
+    HiveJoin(condition=[=($0, $1)], joinType=[inner], algorithm=[none], cost=[not available])
       HiveProject($f00=[$2])
-        HiveJoin(condition=[AND(=($2, $12), CASE($14, CASE($11, >(/($8, $10), /($1, $13)), false), false))], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
-          HiveJoin(condition=[=($2, $0)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+        HiveJoin(condition=[AND(=($2, $12), CASE($14, CASE($11, >(/($8, $10), /($1, $13)), false), false))], joinType=[inner], algorithm=[none], cost=[not available])
+          HiveJoin(condition=[=($2, $0)], joinType=[inner], algorithm=[none], cost=[not available])
             HiveProject(c_customer_id=[$0], $f1=[$1])
               HiveAggregate(group=[{1}], agg#0=[sum($4)])
-                HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+                HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                   HiveProject(c_customer_sk=[$0], c_customer_id=[$1])
                     HiveTableScan(table=[[default, customer]], table:alias=[customer])
-                  HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[MapJoin], cost=[not available])
+                  HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                     HiveProject(ws_sold_date_sk=[$0], ws_bill_customer_sk=[$1], /=[/(+(-(-($5, $4), $2), $3), 2:DECIMAL(10, 0))])
                       HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))])
                         HiveProject(ws_sold_date_sk=[$0], ws_bill_customer_sk=[$4], ws_ext_discount_amt=[$22], ws_ext_sales_price=[$23], ws_ext_wholesale_cost=[$24], ws_ext_list_price=[$25])
@@ -261,15 +261,15 @@ HiveSortLimit(sort0=[$0], sort1=[$1], sort2=[$2], sort3=[$3], dir0=[ASC], dir1=[
                       HiveFilter(condition=[=($1, 2000)])
                         HiveProject(d_date_sk=[$0], d_year=[$6])
                           HiveTableScan(table=[[default, date_dim]], table:alias=[date_dim])
-            HiveJoin(condition=[AND(CASE(IS NOT NULL($4), CASE($9, >(/($6, $8), /($2, $4)), false), false), =($0, $7))], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
-              HiveJoin(condition=[=($0, $5)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
-                HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[SMBJoin], cost=[not available])
+            HiveJoin(condition=[AND(CASE(IS NOT NULL($4), CASE($9, >(/($6, $8), /($2, $4)), false), false), =($0, $7))], joinType=[inner], algorithm=[none], cost=[not available])
+              HiveJoin(condition=[=($0, $5)], joinType=[inner], algorithm=[none], cost=[not available])
+                HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                   HiveProject(c_customer_id=[$0], c_birth_country=[$1], $f2=[$2])
                     HiveAggregate(group=[{1, 4}], agg#0=[sum($7)])
-                      HiveJoin(condition=[=($0, $6)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+                      HiveJoin(condition=[=($0, $6)], joinType=[inner], algorithm=[none], cost=[not available])
                         HiveProject(c_customer_sk=[$0], c_customer_id=[$1], c_first_name=[$8], c_last_name=[$9], c_birth_country=[$14])
                           HiveTableScan(table=[[default, customer]], table:alias=[customer])
-                        HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[MapJoin], cost=[not available])
+                        HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                           HiveProject(ss_sold_date_sk=[$0], ss_customer_sk=[$1], /=[/(+(-(-($5, $4), $2), $3), 2:DECIMAL(10, 0))])
                             HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))])
                               HiveProject(ss_sold_date_sk=[$0], ss_customer_sk=[$3], ss_ext_discount_amt=[$14], ss_ext_sales_price=[$15], ss_ext_wholesale_cost=[$16], ss_ext_list_price=[$17])
@@ -281,10 +281,10 @@ HiveSortLimit(sort0=[$0], sort1=[$1], sort2=[$2], sort3=[$3], dir0=[ASC], dir1=[
                   HiveProject($f0=[$0], $f1=[$1])
                     HiveFilter(condition=[>($1, 0)])
                       HiveAggregate(group=[{1}], agg#0=[sum($4)])
-                        HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+                        HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                           HiveProject(c_customer_sk=[$0], c_customer_id=[$1])
                             HiveTableScan(table=[[default, customer]], table:alias=[customer])
-                          HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[MapJoin], cost=[not available])
+                          HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                             HiveProject(ss_sold_date_sk=[$0], ss_customer_sk=[$1], /=[/(+(-(-($5, $4), $2), $3), 2:DECIMAL(10, 0))])
                               HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))])
                                 HiveProject(ss_sold_date_sk=[$0], ss_customer_sk=[$3], ss_ext_discount_amt=[$14], ss_ext_sales_price=[$15], ss_ext_wholesale_cost=[$16], ss_ext_list_price=[$17])
@@ -295,10 +295,10 @@ HiveSortLimit(sort0=[$0], sort1=[$1], sort2=[$2], sort3=[$3], dir0=[ASC], dir1=[
                                   HiveTableScan(table=[[default, date_dim]], table:alias=[date_dim])
                 HiveProject(c_customer_id=[$0], $f1=[$1])
                   HiveAggregate(group=[{1}], agg#0=[sum($4)])
-                    HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+                    HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                       HiveProject(c_customer_sk=[$0], c_customer_id=[$1])
                         HiveTableScan(table=[[default, customer]], table:alias=[customer])
-                      HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[MapJoin], cost=[not available])
+                      HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                         HiveProject(cs_sold_date_sk=[$0], cs_bill_customer_sk=[$1], /=[/(+(-(-($5, $4), $2), $3), 2:DECIMAL(10, 0))])
                           HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))])
                             HiveProject(cs_sold_date_sk=[$0], cs_bill_customer_sk=[$3], cs_ext_discount_amt=[$22], cs_ext_sales_price=[$23], cs_ext_wholesale_cost=[$24], cs_ext_list_price=[$25])
@@ -310,10 +310,10 @@ HiveSortLimit(sort0=[$0], sort1=[$1], sort2=[$2], sort3=[$3], dir0=[ASC], dir1=[
               HiveProject(customer_id=[$0], year_total=[$1], CAST=[CAST(IS NOT NULL($1)):BOOLEAN])
                 HiveFilter(condition=[>($1, 0)])
                   HiveAggregate(group=[{1}], agg#0=[sum($4)])
-                    HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+                    HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                       HiveProject(c_customer_sk=[$0], c_customer_id=[$1])
                         HiveTableScan(table=[[default, customer]], table:alias=[customer])
-                      HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[MapJoin], cost=[not available])
+                      HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                         HiveProject(cs_sold_date_sk=[$0], cs_bill_customer_sk=[$1], /=[/(+(-(-($5, $4), $2), $3), 2:DECIMAL(10, 0))])
                           HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))])
                             HiveProject(cs_sold_date_sk=[$0], cs_bill_customer_sk=[$3], cs_ext_discount_amt=[$22], cs_ext_sales_price=[$23], cs_ext_wholesale_cost=[$24], cs_ext_list_price=[$25])
@@ -325,10 +325,10 @@ HiveSortLimit(sort0=[$0], sort1=[$1], sort2=[$2], sort3=[$3], dir0=[ASC], dir1=[
           HiveProject(customer_id=[$0], year_total=[$1], CAST=[CAST(IS NOT NULL($1)):BOOLEAN])
             HiveFilter(condition=[>($1, 0)])
               HiveAggregate(group=[{1}], agg#0=[sum($4)])
-                HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+                HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                   HiveProject(c_customer_sk=[$0], c_customer_id=[$1])
                     HiveTableScan(table=[[default, customer]], table:alias=[customer])
-                  HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[MapJoin], cost=[not available])
+                  HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                     HiveProject(ws_sold_date_sk=[$0], ws_bill_customer_sk=[$1], /=[/(+(-(-($5, $4), $2), $3), 2:DECIMAL(10, 0))])
                       HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))])
                         HiveProject(ws_sold_date_sk=[$0], ws_bill_customer_sk=[$4], ws_ext_discount_amt=[$22], ws_ext_sales_price=[$23], ws_ext_wholesale_cost=[$24], ws_ext_list_price=[$25])
diff --git a/ql/src/test/results/clientpositive/perf/tez/constraints/cbo_query74.q.out b/ql/src/test/results/clientpositive/perf/tez/constraints/cbo_query74.q.out
index bf43fb3..2574a76 100644
--- a/ql/src/test/results/clientpositive/perf/tez/constraints/cbo_query74.q.out
+++ b/ql/src/test/results/clientpositive/perf/tez/constraints/cbo_query74.q.out
@@ -130,18 +130,18 @@ POSTHOOK: Input: default@web_sales
 POSTHOOK: Output: hdfs://### HDFS PATH ###
 CBO PLAN:
 HiveSortLimit(sort0=[$2], sort1=[$0], sort2=[$1], dir0=[ASC], dir1=[ASC], dir2=[ASC], fetch=[100])
-  HiveProject($f00=[$0], c_first_name=[$2], c_last_name=[$3])
-    HiveJoin(condition=[=($0, $1)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+  HiveProject(customer_id=[$0], customer_first_name=[$2], customer_last_name=[$3])
+    HiveJoin(condition=[=($0, $1)], joinType=[inner], algorithm=[none], cost=[not available])
       HiveProject($f00=[$0])
-        HiveJoin(condition=[AND(CASE(IS NOT NULL($3), CASE($8, >(/($5, $7), /($1, $3)), false), false), =($0, $6))], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
-          HiveJoin(condition=[=($0, $4)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
-            HiveJoin(condition=[=($0, $2)], joinType=[inner], algorithm=[SMBJoin], cost=[not available])
+        HiveJoin(condition=[AND(CASE(IS NOT NULL($3), CASE($8, >(/($5, $7), /($1, $3)), false), false), =($0, $6))], joinType=[inner], algorithm=[none], cost=[not available])
+          HiveJoin(condition=[=($0, $4)], joinType=[inner], algorithm=[none], cost=[not available])
+            HiveJoin(condition=[=($0, $2)], joinType=[inner], algorithm=[none], cost=[not available])
               HiveProject(c_customer_id=[$0], $f1=[$1])
                 HiveAggregate(group=[{1}], agg#0=[sum($6)])
-                  HiveJoin(condition=[=($0, $5)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+                  HiveJoin(condition=[=($0, $5)], joinType=[inner], algorithm=[none], cost=[not available])
                     HiveProject(c_customer_sk=[$0], c_customer_id=[$1], c_first_name=[$8], c_last_name=[$9])
                       HiveTableScan(table=[[default, customer]], table:alias=[customer])
-                    HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[MapJoin], cost=[not available])
+                    HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                       HiveProject(ss_sold_date_sk=[$0], ss_customer_sk=[$1], ss_net_paid=[$2])
                         HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))])
                           HiveProject(ss_sold_date_sk=[$0], ss_customer_sk=[$3], ss_net_paid=[$20])
@@ -153,10 +153,10 @@ HiveSortLimit(sort0=[$2], sort1=[$0], sort2=[$1], dir0=[ASC], dir1=[ASC], dir2=[
               HiveProject($f0=[$0], $f1=[$1])
                 HiveFilter(condition=[>($1, 0)])
                   HiveAggregate(group=[{1}], agg#0=[sum($4)])
-                    HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+                    HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                       HiveProject(c_customer_sk=[$0], c_customer_id=[$1])
                         HiveTableScan(table=[[default, customer]], table:alias=[customer])
-                      HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[MapJoin], cost=[not available])
+                      HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                         HiveProject(ss_sold_date_sk=[$0], ss_customer_sk=[$1], ss_net_paid=[$2])
                           HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))])
                             HiveProject(ss_sold_date_sk=[$0], ss_customer_sk=[$3], ss_net_paid=[$20])
@@ -167,10 +167,10 @@ HiveSortLimit(sort0=[$2], sort1=[$0], sort2=[$1], dir0=[ASC], dir1=[ASC], dir2=[
                               HiveTableScan(table=[[default, date_dim]], table:alias=[date_dim])
             HiveProject(c_customer_id=[$0], $f1=[$1])
               HiveAggregate(group=[{1}], agg#0=[sum($4)])
-                HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+                HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                   HiveProject(c_customer_sk=[$0], c_customer_id=[$1])
                     HiveTableScan(table=[[default, customer]], table:alias=[customer])
-                  HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[MapJoin], cost=[not available])
+                  HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                     HiveProject(ws_sold_date_sk=[$0], ws_bill_customer_sk=[$1], ws_net_paid=[$2])
                       HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))])
                         HiveProject(ws_sold_date_sk=[$0], ws_bill_customer_sk=[$4], ws_net_paid=[$29])
@@ -182,10 +182,10 @@ HiveSortLimit(sort0=[$2], sort1=[$0], sort2=[$1], dir0=[ASC], dir1=[ASC], dir2=[
           HiveProject(customer_id=[$0], year_total=[$1], CAST=[CAST(IS NOT NULL($1)):BOOLEAN])
             HiveFilter(condition=[>($1, 0)])
               HiveAggregate(group=[{1}], agg#0=[sum($4)])
-                HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[CommonJoin], cost=[not available])
+                HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                   HiveProject(c_customer_sk=[$0], c_customer_id=[$1])
                     HiveTableScan(table=[[default, customer]], table:alias=[customer])
-                  HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[MapJoin], cost=[not available])
+                  HiveJoin(condition=[=($0, $3)], joinType=[inner], algorithm=[none], cost=[not available])
                     HiveProject(ws_sold_date_sk=[$0], ws_bill_customer_sk=[$1], ws_net_paid=[$2])
                       HiveFilter(condition=[AND(IS NOT NULL($0), IS NOT NULL($1))])
                         HiveProject(ws_sold_date_sk=[$0], ws_bill_customer_sk=[$4], ws_net_paid=[$29])