You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by cw...@apache.org on 2012/03/07 11:11:04 UTC

svn commit: r1297919 [1/2] - in /hive/trunk: data/files/ ql/src/java/org/apache/hadoop/hive/ql/exec/ ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/ ql/src/java/org/apache/hadoop/hive/ql/optimizer/ ql/src/java/org/apache/hadoop/hive/ql/optimize...

Author: cws
Date: Wed Mar  7 10:11:03 2012
New Revision: 1297919

URL: http://svn.apache.org/viewvc?rev=1297919&view=rev
Log:
HIVE-2827 [jira] Implement nullsafe equi-join
(Navis Ryu via Carl Steinbach)

Summary:
DPAL-873 Implement nullsafe equi-join

was part of HIVE-2810, but separated because it affected more classes than
expected.

SELECT * FROM a JOIN b ON a.key <=> b.key

Test Plan: EMPTY

Reviewers: JIRA, cwsteinbach

Reviewed By: cwsteinbach

Differential Revision: https://reviews.facebook.net/D1971

Added:
    hive/trunk/data/files/in8.txt   (with props)
    hive/trunk/data/files/in9.txt   (with props)
    hive/trunk/ql/src/test/queries/clientpositive/join_nullsafe.q
    hive/trunk/ql/src/test/results/clientpositive/join_nullsafe.q.out
Modified:
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/AbstractMapJoinOperator.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonJoinOperator.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/JoinOperator.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/MapJoinOperator.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/SMBMapJoinOperator.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/AbstractMapJoinKey.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/MapJoinDoubleKeys.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/MapJoinObjectKey.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/MapJoinSingleKey.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/optimizer/MapJoinProcessor.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/optimizer/physical/GenMRSkewJoinProcessor.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/QBJoinTree.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/plan/JoinDesc.java
    hive/trunk/ql/src/test/results/compiler/plan/join1.q.xml
    hive/trunk/ql/src/test/results/compiler/plan/join2.q.xml
    hive/trunk/ql/src/test/results/compiler/plan/join3.q.xml
    hive/trunk/ql/src/test/results/compiler/plan/join4.q.xml
    hive/trunk/ql/src/test/results/compiler/plan/join5.q.xml
    hive/trunk/ql/src/test/results/compiler/plan/join6.q.xml
    hive/trunk/ql/src/test/results/compiler/plan/join7.q.xml
    hive/trunk/ql/src/test/results/compiler/plan/join8.q.xml
    hive/trunk/serde/src/java/org/apache/hadoop/hive/serde2/SerDeUtils.java

Added: hive/trunk/data/files/in8.txt
URL: http://svn.apache.org/viewvc/hive/trunk/data/files/in8.txt?rev=1297919&view=auto
==============================================================================
--- hive/trunk/data/files/in8.txt (added)
+++ hive/trunk/data/files/in8.txt Wed Mar  7 10:11:03 2012
@@ -0,0 +1,6 @@
+
+10
+10
+35
+48
+100100

Propchange: hive/trunk/data/files/in8.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: hive/trunk/data/files/in9.txt
URL: http://svn.apache.org/viewvc/hive/trunk/data/files/in9.txt?rev=1297919&view=auto
==============================================================================
--- hive/trunk/data/files/in9.txt (added)
+++ hive/trunk/data/files/in9.txt Wed Mar  7 10:11:03 2012
@@ -0,0 +1,6 @@
+
+110
+110
+135
+148
+200200

Propchange: hive/trunk/data/files/in9.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/AbstractMapJoinOperator.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/AbstractMapJoinOperator.java?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/AbstractMapJoinOperator.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/AbstractMapJoinOperator.java Wed Mar  7 10:11:03 2012
@@ -139,8 +139,8 @@ public abstract class AbstractMapJoinOpe
   // returns true if there are elements in key list and any of them is null
   protected boolean hasAnyNulls(ArrayList<Object> key) {
     if (key != null && key.size() > 0) {
-      for (Object k : key) {
-        if (k == null) {
+      for (int i = 0; i < key.size(); i++) {
+        if (key.get(i) == null && (nullsafes == null || !nullsafes[i])) {
           return true;
         }
       }
@@ -151,8 +151,8 @@ public abstract class AbstractMapJoinOpe
   // returns true if there are elements in key list and any of them is null
   protected boolean hasAnyNulls(Object[] key) {
     if (key != null && key.length> 0) {
-      for (Object k : key) {
-        if (k == null) {
+      for (int i = 0; i < key.length; i++) {
+        if (key[i] == null && (nullsafes == null || !nullsafes[i])) {
           return true;
         }
       }
@@ -162,7 +162,7 @@ public abstract class AbstractMapJoinOpe
 
   // returns true if there are elements in key list and any of them is null
   protected boolean hasAnyNulls(AbstractMapJoinKey key) {
-    return key.hasAnyNulls();
+    return key.hasAnyNulls(nullsafes);
   }
 
 }

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonJoinOperator.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonJoinOperator.java?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonJoinOperator.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonJoinOperator.java Wed Mar  7 10:11:03 2012
@@ -121,6 +121,8 @@ public abstract class CommonJoinOperator
   protected transient Byte[] order; // order in which the results should
   // be output
   protected transient JoinCondDesc[] condn;
+  protected transient boolean[] nullsafes;
+
   public transient boolean noOuterJoin;
   protected transient Object[] dummyObj; // for outer joins, contains the
   // potential nulls for the concerned
@@ -240,6 +242,7 @@ public abstract class CommonJoinOperator
 
     order = conf.getTagOrder();
     condn = conf.getConds();
+    nullsafes = conf.getNullSafes();
     noOuterJoin = conf.isNoOuterJoin();
 
     totalSz = JoinUtil.populateJoinKeyValue(joinValues, conf.getExprs(),

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/JoinOperator.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/JoinOperator.java?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/JoinOperator.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/JoinOperator.java Wed Mar  7 10:11:03 2012
@@ -21,6 +21,7 @@ package org.apache.hadoop.hive.ql.exec;
 import java.io.IOException;
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.commons.logging.Log;
 import org.apache.hadoop.conf.Configuration;
@@ -31,6 +32,7 @@ import org.apache.hadoop.hive.ql.metadat
 import org.apache.hadoop.hive.ql.plan.JoinDesc;
 import org.apache.hadoop.hive.ql.plan.api.OperatorType;
 import org.apache.hadoop.hive.serde2.SerDeUtils;
+import org.apache.hadoop.hive.serde2.objectinspector.StandardStructObjectInspector;
 import org.apache.hadoop.hive.serde2.objectinspector.StructField;
 import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
 import org.apache.hadoop.io.LongWritable;
@@ -93,8 +95,7 @@ public class JoinOperator extends Common
       StructObjectInspector soi = (StructObjectInspector) inputObjInspectors[tag];
       StructField sf = soi.getStructFieldRef(Utilities.ReduceField.KEY
           .toString());
-      Object keyObject = soi.getStructFieldData(row, sf);
-
+      List keyObject = (List) soi.getStructFieldData(row, sf);
       // Are we consuming too much memory
       if (alias == numAliases - 1 && !(handleSkewJoin && skewJoinKeyContext.currBigKeyTag >= 0)) {
         if (sz == joinEmitInterval) {
@@ -119,12 +120,14 @@ public class JoinOperator extends Common
       }
 
       // Add the value to the vector
-      storage.get(alias).add(nr);
       // if join-key is null, process each row in different group.
-      if (SerDeUtils.hasAnyNullObject(keyObject, sf.getFieldObjectInspector())) {
+      StandardStructObjectInspector inspector =
+          (StandardStructObjectInspector) sf.getFieldObjectInspector();
+      if (SerDeUtils.hasAnyNullObject(keyObject, inspector, nullsafes)) {
         endGroup();
         startGroup();
       }
+      storage.get(alias).add(nr);
     } catch (Exception e) {
       e.printStackTrace();
       throw new HiveException(e);

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/MapJoinOperator.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/MapJoinOperator.java?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/MapJoinOperator.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/MapJoinOperator.java Wed Mar  7 10:11:03 2012
@@ -252,7 +252,7 @@ public class MapJoinOperator extends Abs
           MapJoinRowContainer<ArrayList<Object>> rowContainer = rowContainerMap.get(pos);
 
           // there is no join-value or join-key has all null elements
-          if (o == null || key.hasAnyNulls()) {
+          if (o == null || key.hasAnyNulls(nullsafes)) {
             if (noOuterJoin) {
               storage.put(pos, emptyList);
             } else {

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/SMBMapJoinOperator.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/SMBMapJoinOperator.java?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/SMBMapJoinOperator.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/SMBMapJoinOperator.java Wed Mar  7 10:11:03 2012
@@ -419,7 +419,7 @@ public class SMBMapJoinOperator extends 
       WritableComparable key_1 = (WritableComparable) k1.get(i);
       WritableComparable key_2 = (WritableComparable) k2.get(i);
       if (key_1 == null && key_2 == null) {
-        return -1; // just return k1 is smaller than k2
+        return nullsafes != null && nullsafes[i] ? 0 : -1; // just return k1 is smaller than k2
       } else if (key_1 == null) {
         return -1;
       } else if (key_2 == null) {

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/AbstractMapJoinKey.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/AbstractMapJoinKey.java?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/AbstractMapJoinKey.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/AbstractMapJoinKey.java Wed Mar  7 10:11:03 2012
@@ -43,6 +43,6 @@ public abstract class AbstractMapJoinKey
 
   public abstract void writeExternal(ObjectOutput out) throws IOException;
 
-  public abstract boolean hasAnyNulls();
+  public abstract boolean hasAnyNulls(boolean[] nullsafes);
 
 }

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/MapJoinDoubleKeys.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/MapJoinDoubleKeys.java?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/MapJoinDoubleKeys.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/MapJoinDoubleKeys.java Wed Mar  7 10:11:03 2012
@@ -172,11 +172,11 @@ public class MapJoinDoubleKeys extends A
 
 
   @Override
-  public boolean hasAnyNulls() {
-    if (obj1 == null) {
+  public boolean hasAnyNulls(boolean[] nullsafes) {
+    if (obj1 == null && (nullsafes == null || !nullsafes[0])) {
       return true;
     }
-    if (obj2 == null) {
+    if (obj2 == null && (nullsafes == null || !nullsafes[1])) {
       return true;
     }
     return false;

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/MapJoinObjectKey.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/MapJoinObjectKey.java?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/MapJoinObjectKey.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/MapJoinObjectKey.java Wed Mar  7 10:11:03 2012
@@ -148,10 +148,10 @@ public class MapJoinObjectKey  extends A
   }
 
   @Override
-  public boolean hasAnyNulls(){
+  public boolean hasAnyNulls(boolean[] nullsafes){
     if (obj != null && obj.length> 0) {
-      for (Object k : obj) {
-        if (k == null) {
+      for (int i = 0; i < obj.length; i++) {
+        if (obj[i] == null && (nullsafes == null || !nullsafes[i])) {
           return true;
         }
       }

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/MapJoinSingleKey.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/MapJoinSingleKey.java?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/MapJoinSingleKey.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/persistence/MapJoinSingleKey.java Wed Mar  7 10:11:03 2012
@@ -139,8 +139,8 @@ public class MapJoinSingleKey extends Ab
   }
 
   @Override
-  public boolean hasAnyNulls() {
-    if (obj == null) {
+  public boolean hasAnyNulls(boolean[] nullsafes) {
+    if (obj == null && (nullsafes == null || !nullsafes[0])) {
       return true;
     }
     return false;

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/optimizer/MapJoinProcessor.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/optimizer/MapJoinProcessor.java?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/optimizer/MapJoinProcessor.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/optimizer/MapJoinProcessor.java Wed Mar  7 10:11:03 2012
@@ -445,6 +445,7 @@ public class MapJoinProcessor implements
         valueTableDescs, valueFiltedTableDescs, outputColumnNames, mapJoinPos, joinCondns,
         filterMap, op.getConf().getNoOuterJoin(), dumpFilePrefix);
     mapJoinDescriptor.setTagOrder(tagOrder);
+    mapJoinDescriptor.setNullSafes(desc.getNullSafes());
 
     MapJoinOperator mapJoinOp = (MapJoinOperator) OperatorFactory.getAndMakeChild(
         mapJoinDescriptor, new RowSchema(outputRS.getColumnInfos()), newPar);

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/optimizer/physical/GenMRSkewJoinProcessor.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/optimizer/physical/GenMRSkewJoinProcessor.java?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/optimizer/physical/GenMRSkewJoinProcessor.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/optimizer/physical/GenMRSkewJoinProcessor.java Wed Mar  7 10:11:03 2012
@@ -286,6 +286,7 @@ public final class GenMRSkewJoinProcesso
           joinDescriptor.getFilters(), joinDescriptor.getNoOuterJoin(), dumpFilePrefix);
       mapJoinDescriptor.setTagOrder(tags);
       mapJoinDescriptor.setHandleSkewJoin(false);
+      mapJoinDescriptor.setNullSafes(joinDescriptor.getNullSafes());
 
       MapredLocalWork localPlan = new MapredLocalWork(
           new LinkedHashMap<String, Operator<? extends Serializable>>(),

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/QBJoinTree.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/QBJoinTree.java?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/QBJoinTree.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/QBJoinTree.java Wed Mar  7 10:11:03 2012
@@ -47,6 +47,9 @@ public class QBJoinTree implements Seria
   // join conditions
   private ArrayList<ArrayList<ASTNode>> expressions;
 
+  // key index to nullsafe join flag
+  private ArrayList<Boolean> nullsafes;
+
   // filters
   private ArrayList<ArrayList<ASTNode>> filters;
 
@@ -294,4 +297,12 @@ public class QBJoinTree implements Seria
       }
     }
   }
+
+  public ArrayList<Boolean> getNullSafes() {
+    return nullsafes;
+  }
+
+  public void setNullSafes(ArrayList<Boolean> nullSafes) {
+    this.nullsafes = nullSafes;
+  }
 }

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java Wed Mar  7 10:11:03 2012
@@ -1336,6 +1336,7 @@ public class SemanticAnalyzer extends Ba
       parseJoinCondition(joinTree, (ASTNode) joinCond.getChild(1), leftSrc);
       break;
 
+    case HiveParser.EQUAL_NS:
     case HiveParser.EQUAL:
       ASTNode leftCondn = (ASTNode) joinCond.getChild(0);
       ArrayList<String> leftCondAl1 = new ArrayList<String>();
@@ -1380,6 +1381,8 @@ public class SemanticAnalyzer extends Ba
               leftSrc);
           populateAliases(rightCondAl1, rightCondAl2, rightCondn, joinTree,
               leftSrc);
+          boolean nullsafe = joinCond.getToken().getType() == HiveParser.EQUAL_NS;
+          joinTree.getNullSafes().add(nullsafe);
         }
       } else if (leftCondAl2.size() != 0) {
         if ((rightCondAl2.size() != 0)
@@ -1400,6 +1403,8 @@ public class SemanticAnalyzer extends Ba
               leftSrc);
           populateAliases(rightCondAl1, rightCondAl2, rightCondn, joinTree,
               leftSrc);
+          boolean nullsafe = joinCond.getToken().getType() == HiveParser.EQUAL_NS;
+          joinTree.getNullSafes().add(nullsafe);
         }
       } else if (rightCondAl1.size() != 0) {
         if (type.equals(JoinType.LEFTOUTER)
@@ -4934,6 +4939,14 @@ public class SemanticAnalyzer extends Ba
         new RowSchema(outputRS.getColumnInfos()), rightOps);
     joinOp.setColumnExprMap(colExprMap);
     joinOp.setPosToAliasMap(posToAliasMap);
+
+    if (join.getNullSafes() != null) {
+      boolean[] nullsafes = new boolean[join.getNullSafes().size()];
+      for (int i = 0; i < nullsafes.length; i++) {
+        nullsafes[i] = join.getNullSafes().get(i);
+      }
+      desc.setNullSafes(nullsafes);
+    }
     return putOpInsertMap(joinOp, outputRS);
   }
 
@@ -5436,6 +5449,9 @@ public class SemanticAnalyzer extends Ba
     expressions.add(new ArrayList<ASTNode>());
     joinTree.setExpressions(expressions);
 
+    ArrayList<Boolean> nullsafes = new ArrayList<Boolean>();
+    joinTree.setNullSafes(nullsafes);
+
     ArrayList<ArrayList<ASTNode>> filters = new ArrayList<ArrayList<ASTNode>>();
     filters.add(new ArrayList<ASTNode>());
     filters.add(new ArrayList<ASTNode>());
@@ -5541,6 +5557,12 @@ public class SemanticAnalyzer extends Ba
       expr.add(node.getExpressions().get(i + 1));
     }
 
+    ArrayList<Boolean> nns = node.getNullSafes();
+    ArrayList<Boolean> tns = target.getNullSafes();
+    for (int i = 0; i < tns.size(); i++) {
+      tns.set(i, tns.get(i) & nns.get(i));   // any of condition contains non-NS, non-NS
+    }
+
     ArrayList<ArrayList<ASTNode>> filters = target.getFilters();
     for (int i = 0; i < nodeRightAliases.length; i++) {
       filters.add(node.getFilters().get(i + 1));

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/plan/JoinDesc.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/plan/JoinDesc.java?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/plan/JoinDesc.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/plan/JoinDesc.java Wed Mar  7 10:11:03 2012
@@ -20,6 +20,7 @@ package org.apache.hadoop.hive.ql.plan;
 
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -51,6 +52,9 @@ public class JoinDesc implements Seriali
   // alias to filter mapping
   private Map<Byte, List<ExprNodeDesc>> filters;
 
+  // key index to nullsafe join flag
+  private boolean[] nullsafes;
+
   // used for create joinOutputObjectInspector
   protected List<String> outputColumnNames;
 
@@ -103,6 +107,7 @@ public class JoinDesc implements Seriali
     this.bigKeysDirMap = clone.bigKeysDirMap;
     this.conds = clone.conds;
     this.exprs = clone.exprs;
+    this.nullsafes = clone.nullsafes;
     this.handleSkewJoin = clone.handleSkewJoin;
     this.keyTableDesc = clone.keyTableDesc;
     this.noOuterJoin = clone.noOuterJoin;
@@ -362,4 +367,24 @@ public class JoinDesc implements Seriali
   public TableDesc getKeyTableDesc() {
     return keyTableDesc;
   }
+
+  public boolean[] getNullSafes() {
+    return nullsafes;
+  }
+
+  public void setNullSafes(boolean[] nullSafes) {
+    this.nullsafes = nullSafes;
+  }
+
+  @Explain(displayName = "nullSafes")
+  public String getNullSafeString() {
+    if (nullsafes == null) {
+      return null;
+    }
+    boolean hasNS = false;
+    for (boolean ns : nullsafes) {
+      hasNS |= ns;
+    }
+    return hasNS ? Arrays.toString(nullsafes) : null;
+  }
 }

Added: hive/trunk/ql/src/test/queries/clientpositive/join_nullsafe.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientpositive/join_nullsafe.q?rev=1297919&view=auto
==============================================================================
--- hive/trunk/ql/src/test/queries/clientpositive/join_nullsafe.q (added)
+++ hive/trunk/ql/src/test/queries/clientpositive/join_nullsafe.q Wed Mar  7 10:11:03 2012
@@ -0,0 +1,57 @@
+set hive.nullsafe.equijoin=true;
+
+CREATE TABLE myinput1(key int, value int);
+LOAD DATA LOCAL INPATH '../data/files/in8.txt' INTO TABLE myinput1;
+
+-- merging
+explain select * from myinput1 a join myinput1 b on a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value;
+select * from myinput1 a join myinput1 b on a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value;
+
+explain select * from myinput1 a join myinput1 b on a.key<=>b.value join myinput1 c on a.key=c.key ORDER BY a.key, a.value, b.key, b.value, c.key, c.value;
+select * from myinput1 a join myinput1 b on a.key<=>b.value join myinput1 c on a.key=c.key ORDER BY a.key, a.value, b.key, b.value, c.key, c.value;
+
+explain select * from myinput1 a join myinput1 b on a.key<=>b.value join myinput1 c on a.key<=>c.key ORDER BY a.key, a.value, b.key, b.value, c.key, c.value;
+select * from myinput1 a join myinput1 b on a.key<=>b.value join myinput1 c on a.key<=>c.key ORDER BY a.key, a.value, b.key, b.value, c.key, c.value;
+
+explain select * from myinput1 a join myinput1 b on a.key<=>b.value AND a.value=b.key join myinput1 c on a.key<=>c.key AND a.value=c.value ORDER BY a.key, a.value, b.key, b.value, c.key, c.value;
+select * from myinput1 a join myinput1 b on a.key<=>b.value AND a.value=b.key join myinput1 c on a.key<=>c.key AND a.value=c.value ORDER BY a.key, a.value, b.key, b.value, c.key, c.value;
+
+explain select * from myinput1 a join myinput1 b on a.key<=>b.value AND a.value<=>b.key join myinput1 c on a.key<=>c.key AND a.value<=>c.value ORDER BY a.key, a.value, b.key, b.value, c.key, c.value;
+select * from myinput1 a join myinput1 b on a.key<=>b.value AND a.value<=>b.key join myinput1 c on a.key<=>c.key AND a.value<=>c.value ORDER BY a.key, a.value, b.key, b.value, c.key, c.value;
+
+-- outer joins
+SELECT * FROM myinput1 a LEFT OUTER JOIN myinput1 b ON a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value;
+SELECT * FROM myinput1 a RIGHT OUTER JOIN myinput1 b ON a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value;
+SELECT * FROM myinput1 a FULL OUTER JOIN myinput1 b ON a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value;
+
+-- map joins
+SELECT /*+ MAPJOIN(a) */ * FROM myinput1 a JOIN myinput1 b ON a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value;
+SELECT /*+ MAPJOIN(b) */ * FROM myinput1 a JOIN myinput1 b ON a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value;
+
+-- smbs
+CREATE TABLE smb_input1(key int, value int) CLUSTERED BY (key) SORTED BY (key) INTO 2 BUCKETS;
+CREATE TABLE smb_input2(key int, value int) CLUSTERED BY (value) SORTED BY (value) INTO 2 BUCKETS;
+LOAD DATA LOCAL INPATH '../data/files/in8.txt' into table smb_input1;
+LOAD DATA LOCAL INPATH '../data/files/in9.txt' into table smb_input1;
+LOAD DATA LOCAL INPATH '../data/files/in8.txt' into table smb_input2;
+LOAD DATA LOCAL INPATH '../data/files/in9.txt' into table smb_input2;
+
+SET hive.optimize.bucketmapJOIN = true;
+SET hive.optimize.bucketmapJOIN.sortedmerge = true;
+SET hive.input.format = org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;
+
+SELECT /*+ MAPJOIN(a) */ * FROM smb_input1 a JOIN smb_input1 b ON a.key <=> b.key ORDER BY a.key, a.value, b.key, b.value;
+SELECT /*+ MAPJOIN(a) */ * FROM smb_input1 a JOIN smb_input1 b ON a.key <=> b.key AND a.value <=> b.value ORDER BY a.key, a.value, b.key, b.value;
+SELECT /*+ MAPJOIN(a) */ * FROM smb_input1 a RIGHT OUTER JOIN smb_input1 b ON a.key <=> b.key ORDER BY a.key, a.value, b.key, b.value;
+SELECT /*+ MAPJOIN(b) */ * FROM smb_input1 a JOIN smb_input1 b ON a.key <=> b.key ORDER BY a.key, a.value, b.key, b.value;
+SELECT /*+ MAPJOIN(b) */ * FROM smb_input1 a LEFT OUTER JOIN smb_input1 b ON a.key <=> b.key ORDER BY a.key, a.value, b.key, b.value;
+
+SELECT /*+ MAPJOIN(a) */ * FROM smb_input1 a JOIN smb_input2 b ON a.key <=> b.value ORDER BY a.key, a.value, b.key, b.value;
+SELECT /*+ MAPJOIN(b) */ * FROM smb_input1 a JOIN smb_input2 b ON a.key <=> b.value ORDER BY a.key, a.value, b.key, b.value;
+SELECT /*+ MAPJOIN(b) */ * FROM smb_input1 a LEFT OUTER JOIN smb_input2 b ON a.key <=> b.value ORDER BY a.key, a.value, b.key, b.value;
+SELECT /*+ MAPJOIN(a) */ * FROM smb_input1 a RIGHT OUTER JOIN smb_input2 b ON a.key <=> b.value ORDER BY a.key, a.value, b.key, b.value;
+
+SELECT /*+ MAPJOIN(a) */ * FROM smb_input2 a JOIN smb_input2 b ON a.value <=> b.value ORDER BY a.key, a.value, b.key, b.value;
+SELECT /*+ MAPJOIN(a) */ * FROM smb_input2 a RIGHT OUTER JOIN smb_input2 b ON a.value <=> b.value ORDER BY a.key, a.value, b.key, b.value;
+SELECT /*+ MAPJOIN(b) */ * FROM smb_input2 a JOIN smb_input2 b ON a.value <=> b.value ORDER BY a.key, a.value, b.key, b.value;
+SELECT /*+ MAPJOIN(b) */ * FROM smb_input2 a LEFT OUTER JOIN smb_input2 b ON a.value <=> b.value ORDER BY a.key, a.value, b.key, b.value;

Added: hive/trunk/ql/src/test/results/clientpositive/join_nullsafe.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientpositive/join_nullsafe.q.out?rev=1297919&view=auto
==============================================================================
--- hive/trunk/ql/src/test/results/clientpositive/join_nullsafe.q.out (added)
+++ hive/trunk/ql/src/test/results/clientpositive/join_nullsafe.q.out Wed Mar  7 10:11:03 2012
@@ -0,0 +1,1590 @@
+PREHOOK: query: CREATE TABLE myinput1(key int, value int)
+PREHOOK: type: CREATETABLE
+POSTHOOK: query: CREATE TABLE myinput1(key int, value int)
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: default@myinput1
+PREHOOK: query: LOAD DATA LOCAL INPATH '../data/files/in8.txt' INTO TABLE myinput1
+PREHOOK: type: LOAD
+PREHOOK: Output: default@myinput1
+POSTHOOK: query: LOAD DATA LOCAL INPATH '../data/files/in8.txt' INTO TABLE myinput1
+POSTHOOK: type: LOAD
+POSTHOOK: Output: default@myinput1
+PREHOOK: query: -- merging
+explain select * from myinput1 a join myinput1 b on a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+POSTHOOK: query: -- merging
+explain select * from myinput1 a join myinput1 b on a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+ABSTRACT SYNTAX TREE:
+  (TOK_QUERY (TOK_FROM (TOK_JOIN (TOK_TABREF (TOK_TABNAME myinput1) a) (TOK_TABREF (TOK_TABNAME myinput1) b) (<=> (. (TOK_TABLE_OR_COL a) key) (. (TOK_TABLE_OR_COL b) value)))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR TOK_ALLCOLREF)) (TOK_ORDERBY (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL a) key)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL a) value)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL b) key)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL b) value)))))
+
+STAGE DEPENDENCIES:
+  Stage-1 is a root stage
+  Stage-2 depends on stages: Stage-1
+  Stage-0 is a root stage
+
+STAGE PLANS:
+  Stage: Stage-1
+    Map Reduce
+      Alias -> Map Operator Tree:
+        a 
+          TableScan
+            alias: a
+            Reduce Output Operator
+              key expressions:
+                    expr: key
+                    type: int
+              sort order: +
+              Map-reduce partition columns:
+                    expr: key
+                    type: int
+              tag: 0
+              value expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+        b 
+          TableScan
+            alias: b
+            Reduce Output Operator
+              key expressions:
+                    expr: value
+                    type: int
+              sort order: +
+              Map-reduce partition columns:
+                    expr: value
+                    type: int
+              tag: 1
+              value expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+      Reduce Operator Tree:
+        Join Operator
+          condition map:
+               Inner Join 0 to 1
+          condition expressions:
+            0 {VALUE._col0} {VALUE._col1}
+            1 {VALUE._col0} {VALUE._col1}
+          handleSkewJoin: false
+          nullSafes: [true]
+          outputColumnNames: _col0, _col1, _col4, _col5
+          Select Operator
+            expressions:
+                  expr: _col0
+                  type: int
+                  expr: _col1
+                  type: int
+                  expr: _col4
+                  type: int
+                  expr: _col5
+                  type: int
+            outputColumnNames: _col0, _col1, _col2, _col3
+            File Output Operator
+              compressed: false
+              GlobalTableId: 0
+              table:
+                  input format: org.apache.hadoop.mapred.SequenceFileInputFormat
+                  output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat
+
+  Stage: Stage-2
+    Map Reduce
+      Alias -> Map Operator Tree:
+#### A masked pattern was here ####
+            Reduce Output Operator
+              key expressions:
+                    expr: _col0
+                    type: int
+                    expr: _col1
+                    type: int
+                    expr: _col2
+                    type: int
+                    expr: _col3
+                    type: int
+              sort order: ++++
+              tag: -1
+              value expressions:
+                    expr: _col0
+                    type: int
+                    expr: _col1
+                    type: int
+                    expr: _col2
+                    type: int
+                    expr: _col3
+                    type: int
+      Reduce Operator Tree:
+        Extract
+          File Output Operator
+            compressed: false
+            GlobalTableId: 0
+            table:
+                input format: org.apache.hadoop.mapred.TextInputFormat
+                output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
+
+  Stage: Stage-0
+    Fetch Operator
+      limit: -1
+
+
+PREHOOK: query: select * from myinput1 a join myinput1 b on a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+POSTHOOK: query: select * from myinput1 a join myinput1 b on a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	10	NULL
+NULL	NULL	48	NULL
+NULL	10	NULL	NULL
+NULL	10	10	NULL
+NULL	10	48	NULL
+NULL	35	NULL	NULL
+NULL	35	10	NULL
+NULL	35	48	NULL
+10	NULL	NULL	10
+100	100	100	100
+PREHOOK: query: explain select * from myinput1 a join myinput1 b on a.key<=>b.value join myinput1 c on a.key=c.key ORDER BY a.key, a.value, b.key, b.value, c.key, c.value
+PREHOOK: type: QUERY
+POSTHOOK: query: explain select * from myinput1 a join myinput1 b on a.key<=>b.value join myinput1 c on a.key=c.key ORDER BY a.key, a.value, b.key, b.value, c.key, c.value
+POSTHOOK: type: QUERY
+ABSTRACT SYNTAX TREE:
+  (TOK_QUERY (TOK_FROM (TOK_JOIN (TOK_JOIN (TOK_TABREF (TOK_TABNAME myinput1) a) (TOK_TABREF (TOK_TABNAME myinput1) b) (<=> (. (TOK_TABLE_OR_COL a) key) (. (TOK_TABLE_OR_COL b) value))) (TOK_TABREF (TOK_TABNAME myinput1) c) (= (. (TOK_TABLE_OR_COL a) key) (. (TOK_TABLE_OR_COL c) key)))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR TOK_ALLCOLREF)) (TOK_ORDERBY (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL a) key)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL a) value)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL b) key)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL b) value)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL c) key)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL c) value)))))
+
+STAGE DEPENDENCIES:
+  Stage-1 is a root stage
+  Stage-2 depends on stages: Stage-1
+  Stage-0 is a root stage
+
+STAGE PLANS:
+  Stage: Stage-1
+    Map Reduce
+      Alias -> Map Operator Tree:
+        a 
+          TableScan
+            alias: a
+            Reduce Output Operator
+              key expressions:
+                    expr: key
+                    type: int
+              sort order: +
+              Map-reduce partition columns:
+                    expr: key
+                    type: int
+              tag: 0
+              value expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+        b 
+          TableScan
+            alias: b
+            Reduce Output Operator
+              key expressions:
+                    expr: value
+                    type: int
+              sort order: +
+              Map-reduce partition columns:
+                    expr: value
+                    type: int
+              tag: 1
+              value expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+        c 
+          TableScan
+            alias: c
+            Reduce Output Operator
+              key expressions:
+                    expr: key
+                    type: int
+              sort order: +
+              Map-reduce partition columns:
+                    expr: key
+                    type: int
+              tag: 2
+              value expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+      Reduce Operator Tree:
+        Join Operator
+          condition map:
+               Inner Join 0 to 1
+               Inner Join 0 to 2
+          condition expressions:
+            0 {VALUE._col0} {VALUE._col1}
+            1 {VALUE._col0} {VALUE._col1}
+            2 {VALUE._col0} {VALUE._col1}
+          handleSkewJoin: false
+          outputColumnNames: _col0, _col1, _col4, _col5, _col8, _col9
+          Select Operator
+            expressions:
+                  expr: _col0
+                  type: int
+                  expr: _col1
+                  type: int
+                  expr: _col4
+                  type: int
+                  expr: _col5
+                  type: int
+                  expr: _col8
+                  type: int
+                  expr: _col9
+                  type: int
+            outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5
+            File Output Operator
+              compressed: false
+              GlobalTableId: 0
+              table:
+                  input format: org.apache.hadoop.mapred.SequenceFileInputFormat
+                  output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat
+
+  Stage: Stage-2
+    Map Reduce
+      Alias -> Map Operator Tree:
+#### A masked pattern was here ####
+            Reduce Output Operator
+              key expressions:
+                    expr: _col0
+                    type: int
+                    expr: _col1
+                    type: int
+                    expr: _col2
+                    type: int
+                    expr: _col3
+                    type: int
+                    expr: _col4
+                    type: int
+                    expr: _col5
+                    type: int
+              sort order: ++++++
+              tag: -1
+              value expressions:
+                    expr: _col0
+                    type: int
+                    expr: _col1
+                    type: int
+                    expr: _col2
+                    type: int
+                    expr: _col3
+                    type: int
+                    expr: _col4
+                    type: int
+                    expr: _col5
+                    type: int
+      Reduce Operator Tree:
+        Extract
+          File Output Operator
+            compressed: false
+            GlobalTableId: 0
+            table:
+                input format: org.apache.hadoop.mapred.TextInputFormat
+                output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
+
+  Stage: Stage-0
+    Fetch Operator
+      limit: -1
+
+
+PREHOOK: query: select * from myinput1 a join myinput1 b on a.key<=>b.value join myinput1 c on a.key=c.key ORDER BY a.key, a.value, b.key, b.value, c.key, c.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+POSTHOOK: query: select * from myinput1 a join myinput1 b on a.key<=>b.value join myinput1 c on a.key=c.key ORDER BY a.key, a.value, b.key, b.value, c.key, c.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+10	NULL	NULL	10	10	NULL
+100	100	100	100	100	100
+PREHOOK: query: explain select * from myinput1 a join myinput1 b on a.key<=>b.value join myinput1 c on a.key<=>c.key ORDER BY a.key, a.value, b.key, b.value, c.key, c.value
+PREHOOK: type: QUERY
+POSTHOOK: query: explain select * from myinput1 a join myinput1 b on a.key<=>b.value join myinput1 c on a.key<=>c.key ORDER BY a.key, a.value, b.key, b.value, c.key, c.value
+POSTHOOK: type: QUERY
+ABSTRACT SYNTAX TREE:
+  (TOK_QUERY (TOK_FROM (TOK_JOIN (TOK_JOIN (TOK_TABREF (TOK_TABNAME myinput1) a) (TOK_TABREF (TOK_TABNAME myinput1) b) (<=> (. (TOK_TABLE_OR_COL a) key) (. (TOK_TABLE_OR_COL b) value))) (TOK_TABREF (TOK_TABNAME myinput1) c) (<=> (. (TOK_TABLE_OR_COL a) key) (. (TOK_TABLE_OR_COL c) key)))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR TOK_ALLCOLREF)) (TOK_ORDERBY (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL a) key)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL a) value)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL b) key)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL b) value)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL c) key)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL c) value)))))
+
+STAGE DEPENDENCIES:
+  Stage-1 is a root stage
+  Stage-2 depends on stages: Stage-1
+  Stage-0 is a root stage
+
+STAGE PLANS:
+  Stage: Stage-1
+    Map Reduce
+      Alias -> Map Operator Tree:
+        a 
+          TableScan
+            alias: a
+            Reduce Output Operator
+              key expressions:
+                    expr: key
+                    type: int
+              sort order: +
+              Map-reduce partition columns:
+                    expr: key
+                    type: int
+              tag: 0
+              value expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+        b 
+          TableScan
+            alias: b
+            Reduce Output Operator
+              key expressions:
+                    expr: value
+                    type: int
+              sort order: +
+              Map-reduce partition columns:
+                    expr: value
+                    type: int
+              tag: 1
+              value expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+        c 
+          TableScan
+            alias: c
+            Reduce Output Operator
+              key expressions:
+                    expr: key
+                    type: int
+              sort order: +
+              Map-reduce partition columns:
+                    expr: key
+                    type: int
+              tag: 2
+              value expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+      Reduce Operator Tree:
+        Join Operator
+          condition map:
+               Inner Join 0 to 1
+               Inner Join 0 to 2
+          condition expressions:
+            0 {VALUE._col0} {VALUE._col1}
+            1 {VALUE._col0} {VALUE._col1}
+            2 {VALUE._col0} {VALUE._col1}
+          handleSkewJoin: false
+          nullSafes: [true]
+          outputColumnNames: _col0, _col1, _col4, _col5, _col8, _col9
+          Select Operator
+            expressions:
+                  expr: _col0
+                  type: int
+                  expr: _col1
+                  type: int
+                  expr: _col4
+                  type: int
+                  expr: _col5
+                  type: int
+                  expr: _col8
+                  type: int
+                  expr: _col9
+                  type: int
+            outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5
+            File Output Operator
+              compressed: false
+              GlobalTableId: 0
+              table:
+                  input format: org.apache.hadoop.mapred.SequenceFileInputFormat
+                  output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat
+
+  Stage: Stage-2
+    Map Reduce
+      Alias -> Map Operator Tree:
+#### A masked pattern was here ####
+            Reduce Output Operator
+              key expressions:
+                    expr: _col0
+                    type: int
+                    expr: _col1
+                    type: int
+                    expr: _col2
+                    type: int
+                    expr: _col3
+                    type: int
+                    expr: _col4
+                    type: int
+                    expr: _col5
+                    type: int
+              sort order: ++++++
+              tag: -1
+              value expressions:
+                    expr: _col0
+                    type: int
+                    expr: _col1
+                    type: int
+                    expr: _col2
+                    type: int
+                    expr: _col3
+                    type: int
+                    expr: _col4
+                    type: int
+                    expr: _col5
+                    type: int
+      Reduce Operator Tree:
+        Extract
+          File Output Operator
+            compressed: false
+            GlobalTableId: 0
+            table:
+                input format: org.apache.hadoop.mapred.TextInputFormat
+                output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
+
+  Stage: Stage-0
+    Fetch Operator
+      limit: -1
+
+
+PREHOOK: query: select * from myinput1 a join myinput1 b on a.key<=>b.value join myinput1 c on a.key<=>c.key ORDER BY a.key, a.value, b.key, b.value, c.key, c.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+POSTHOOK: query: select * from myinput1 a join myinput1 b on a.key<=>b.value join myinput1 c on a.key<=>c.key ORDER BY a.key, a.value, b.key, b.value, c.key, c.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL	NULL	10
+NULL	NULL	NULL	NULL	NULL	35
+NULL	NULL	10	NULL	NULL	NULL
+NULL	NULL	10	NULL	NULL	10
+NULL	NULL	10	NULL	NULL	35
+NULL	NULL	48	NULL	NULL	NULL
+NULL	NULL	48	NULL	NULL	10
+NULL	NULL	48	NULL	NULL	35
+NULL	10	NULL	NULL	NULL	NULL
+NULL	10	NULL	NULL	NULL	10
+NULL	10	NULL	NULL	NULL	35
+NULL	10	10	NULL	NULL	NULL
+NULL	10	10	NULL	NULL	10
+NULL	10	10	NULL	NULL	35
+NULL	10	48	NULL	NULL	NULL
+NULL	10	48	NULL	NULL	10
+NULL	10	48	NULL	NULL	35
+NULL	35	NULL	NULL	NULL	NULL
+NULL	35	NULL	NULL	NULL	10
+NULL	35	NULL	NULL	NULL	35
+NULL	35	10	NULL	NULL	NULL
+NULL	35	10	NULL	NULL	10
+NULL	35	10	NULL	NULL	35
+NULL	35	48	NULL	NULL	NULL
+NULL	35	48	NULL	NULL	10
+NULL	35	48	NULL	NULL	35
+10	NULL	NULL	10	10	NULL
+100	100	100	100	100	100
+PREHOOK: query: explain select * from myinput1 a join myinput1 b on a.key<=>b.value AND a.value=b.key join myinput1 c on a.key<=>c.key AND a.value=c.value ORDER BY a.key, a.value, b.key, b.value, c.key, c.value
+PREHOOK: type: QUERY
+POSTHOOK: query: explain select * from myinput1 a join myinput1 b on a.key<=>b.value AND a.value=b.key join myinput1 c on a.key<=>c.key AND a.value=c.value ORDER BY a.key, a.value, b.key, b.value, c.key, c.value
+POSTHOOK: type: QUERY
+ABSTRACT SYNTAX TREE:
+  (TOK_QUERY (TOK_FROM (TOK_JOIN (TOK_JOIN (TOK_TABREF (TOK_TABNAME myinput1) a) (TOK_TABREF (TOK_TABNAME myinput1) b) (AND (<=> (. (TOK_TABLE_OR_COL a) key) (. (TOK_TABLE_OR_COL b) value)) (= (. (TOK_TABLE_OR_COL a) value) (. (TOK_TABLE_OR_COL b) key)))) (TOK_TABREF (TOK_TABNAME myinput1) c) (AND (<=> (. (TOK_TABLE_OR_COL a) key) (. (TOK_TABLE_OR_COL c) key)) (= (. (TOK_TABLE_OR_COL a) value) (. (TOK_TABLE_OR_COL c) value))))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR TOK_ALLCOLREF)) (TOK_ORDERBY (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL a) key)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL a) value)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL b) key)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL b) value)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL c) key)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL c) value)))))
+
+STAGE DEPENDENCIES:
+  Stage-1 is a root stage
+  Stage-2 depends on stages: Stage-1
+  Stage-0 is a root stage
+
+STAGE PLANS:
+  Stage: Stage-1
+    Map Reduce
+      Alias -> Map Operator Tree:
+        a 
+          TableScan
+            alias: a
+            Reduce Output Operator
+              key expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+              sort order: ++
+              Map-reduce partition columns:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+              tag: 0
+              value expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+        b 
+          TableScan
+            alias: b
+            Reduce Output Operator
+              key expressions:
+                    expr: value
+                    type: int
+                    expr: key
+                    type: int
+              sort order: ++
+              Map-reduce partition columns:
+                    expr: value
+                    type: int
+                    expr: key
+                    type: int
+              tag: 1
+              value expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+        c 
+          TableScan
+            alias: c
+            Reduce Output Operator
+              key expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+              sort order: ++
+              Map-reduce partition columns:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+              tag: 2
+              value expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+      Reduce Operator Tree:
+        Join Operator
+          condition map:
+               Inner Join 0 to 1
+               Inner Join 0 to 2
+          condition expressions:
+            0 {VALUE._col0} {VALUE._col1}
+            1 {VALUE._col0} {VALUE._col1}
+            2 {VALUE._col0} {VALUE._col1}
+          handleSkewJoin: false
+          nullSafes: [true, false]
+          outputColumnNames: _col0, _col1, _col4, _col5, _col8, _col9
+          Select Operator
+            expressions:
+                  expr: _col0
+                  type: int
+                  expr: _col1
+                  type: int
+                  expr: _col4
+                  type: int
+                  expr: _col5
+                  type: int
+                  expr: _col8
+                  type: int
+                  expr: _col9
+                  type: int
+            outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5
+            File Output Operator
+              compressed: false
+              GlobalTableId: 0
+              table:
+                  input format: org.apache.hadoop.mapred.SequenceFileInputFormat
+                  output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat
+
+  Stage: Stage-2
+    Map Reduce
+      Alias -> Map Operator Tree:
+#### A masked pattern was here ####
+            Reduce Output Operator
+              key expressions:
+                    expr: _col0
+                    type: int
+                    expr: _col1
+                    type: int
+                    expr: _col2
+                    type: int
+                    expr: _col3
+                    type: int
+                    expr: _col4
+                    type: int
+                    expr: _col5
+                    type: int
+              sort order: ++++++
+              tag: -1
+              value expressions:
+                    expr: _col0
+                    type: int
+                    expr: _col1
+                    type: int
+                    expr: _col2
+                    type: int
+                    expr: _col3
+                    type: int
+                    expr: _col4
+                    type: int
+                    expr: _col5
+                    type: int
+      Reduce Operator Tree:
+        Extract
+          File Output Operator
+            compressed: false
+            GlobalTableId: 0
+            table:
+                input format: org.apache.hadoop.mapred.TextInputFormat
+                output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
+
+  Stage: Stage-0
+    Fetch Operator
+      limit: -1
+
+
+PREHOOK: query: select * from myinput1 a join myinput1 b on a.key<=>b.value AND a.value=b.key join myinput1 c on a.key<=>c.key AND a.value=c.value ORDER BY a.key, a.value, b.key, b.value, c.key, c.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+POSTHOOK: query: select * from myinput1 a join myinput1 b on a.key<=>b.value AND a.value=b.key join myinput1 c on a.key<=>c.key AND a.value=c.value ORDER BY a.key, a.value, b.key, b.value, c.key, c.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+NULL	10	10	NULL	NULL	10
+100	100	100	100	100	100
+PREHOOK: query: explain select * from myinput1 a join myinput1 b on a.key<=>b.value AND a.value<=>b.key join myinput1 c on a.key<=>c.key AND a.value<=>c.value ORDER BY a.key, a.value, b.key, b.value, c.key, c.value
+PREHOOK: type: QUERY
+POSTHOOK: query: explain select * from myinput1 a join myinput1 b on a.key<=>b.value AND a.value<=>b.key join myinput1 c on a.key<=>c.key AND a.value<=>c.value ORDER BY a.key, a.value, b.key, b.value, c.key, c.value
+POSTHOOK: type: QUERY
+ABSTRACT SYNTAX TREE:
+  (TOK_QUERY (TOK_FROM (TOK_JOIN (TOK_JOIN (TOK_TABREF (TOK_TABNAME myinput1) a) (TOK_TABREF (TOK_TABNAME myinput1) b) (AND (<=> (. (TOK_TABLE_OR_COL a) key) (. (TOK_TABLE_OR_COL b) value)) (<=> (. (TOK_TABLE_OR_COL a) value) (. (TOK_TABLE_OR_COL b) key)))) (TOK_TABREF (TOK_TABNAME myinput1) c) (AND (<=> (. (TOK_TABLE_OR_COL a) key) (. (TOK_TABLE_OR_COL c) key)) (<=> (. (TOK_TABLE_OR_COL a) value) (. (TOK_TABLE_OR_COL c) value))))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR TOK_ALLCOLREF)) (TOK_ORDERBY (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL a) key)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL a) value)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL b) key)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL b) value)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL c) key)) (TOK_TABSORTCOLNAMEASC (. (TOK_TABLE_OR_COL c) value)))))
+
+STAGE DEPENDENCIES:
+  Stage-1 is a root stage
+  Stage-2 depends on stages: Stage-1
+  Stage-0 is a root stage
+
+STAGE PLANS:
+  Stage: Stage-1
+    Map Reduce
+      Alias -> Map Operator Tree:
+        a 
+          TableScan
+            alias: a
+            Reduce Output Operator
+              key expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+              sort order: ++
+              Map-reduce partition columns:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+              tag: 0
+              value expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+        b 
+          TableScan
+            alias: b
+            Reduce Output Operator
+              key expressions:
+                    expr: value
+                    type: int
+                    expr: key
+                    type: int
+              sort order: ++
+              Map-reduce partition columns:
+                    expr: value
+                    type: int
+                    expr: key
+                    type: int
+              tag: 1
+              value expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+        c 
+          TableScan
+            alias: c
+            Reduce Output Operator
+              key expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+              sort order: ++
+              Map-reduce partition columns:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+              tag: 2
+              value expressions:
+                    expr: key
+                    type: int
+                    expr: value
+                    type: int
+      Reduce Operator Tree:
+        Join Operator
+          condition map:
+               Inner Join 0 to 1
+               Inner Join 0 to 2
+          condition expressions:
+            0 {VALUE._col0} {VALUE._col1}
+            1 {VALUE._col0} {VALUE._col1}
+            2 {VALUE._col0} {VALUE._col1}
+          handleSkewJoin: false
+          nullSafes: [true, true]
+          outputColumnNames: _col0, _col1, _col4, _col5, _col8, _col9
+          Select Operator
+            expressions:
+                  expr: _col0
+                  type: int
+                  expr: _col1
+                  type: int
+                  expr: _col4
+                  type: int
+                  expr: _col5
+                  type: int
+                  expr: _col8
+                  type: int
+                  expr: _col9
+                  type: int
+            outputColumnNames: _col0, _col1, _col2, _col3, _col4, _col5
+            File Output Operator
+              compressed: false
+              GlobalTableId: 0
+              table:
+                  input format: org.apache.hadoop.mapred.SequenceFileInputFormat
+                  output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat
+
+  Stage: Stage-2
+    Map Reduce
+      Alias -> Map Operator Tree:
+#### A masked pattern was here ####
+            Reduce Output Operator
+              key expressions:
+                    expr: _col0
+                    type: int
+                    expr: _col1
+                    type: int
+                    expr: _col2
+                    type: int
+                    expr: _col3
+                    type: int
+                    expr: _col4
+                    type: int
+                    expr: _col5
+                    type: int
+              sort order: ++++++
+              tag: -1
+              value expressions:
+                    expr: _col0
+                    type: int
+                    expr: _col1
+                    type: int
+                    expr: _col2
+                    type: int
+                    expr: _col3
+                    type: int
+                    expr: _col4
+                    type: int
+                    expr: _col5
+                    type: int
+      Reduce Operator Tree:
+        Extract
+          File Output Operator
+            compressed: false
+            GlobalTableId: 0
+            table:
+                input format: org.apache.hadoop.mapred.TextInputFormat
+                output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
+
+  Stage: Stage-0
+    Fetch Operator
+      limit: -1
+
+
+PREHOOK: query: select * from myinput1 a join myinput1 b on a.key<=>b.value AND a.value<=>b.key join myinput1 c on a.key<=>c.key AND a.value<=>c.value ORDER BY a.key, a.value, b.key, b.value, c.key, c.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+POSTHOOK: query: select * from myinput1 a join myinput1 b on a.key<=>b.value AND a.value<=>b.key join myinput1 c on a.key<=>c.key AND a.value<=>c.value ORDER BY a.key, a.value, b.key, b.value, c.key, c.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL	NULL	NULL
+NULL	10	10	NULL	NULL	10
+10	NULL	NULL	10	10	NULL
+100	100	100	100	100	100
+PREHOOK: query: -- outer joins
+SELECT * FROM myinput1 a LEFT OUTER JOIN myinput1 b ON a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+POSTHOOK: query: -- outer joins
+SELECT * FROM myinput1 a LEFT OUTER JOIN myinput1 b ON a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	10	NULL
+NULL	NULL	48	NULL
+NULL	10	NULL	NULL
+NULL	10	10	NULL
+NULL	10	48	NULL
+NULL	35	NULL	NULL
+NULL	35	10	NULL
+NULL	35	48	NULL
+10	NULL	NULL	10
+48	NULL	NULL	NULL
+100	100	100	100
+PREHOOK: query: SELECT * FROM myinput1 a RIGHT OUTER JOIN myinput1 b ON a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM myinput1 a RIGHT OUTER JOIN myinput1 b ON a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	35
+NULL	NULL	10	NULL
+NULL	NULL	48	NULL
+NULL	10	NULL	NULL
+NULL	10	10	NULL
+NULL	10	48	NULL
+NULL	35	NULL	NULL
+NULL	35	10	NULL
+NULL	35	48	NULL
+10	NULL	NULL	10
+100	100	100	100
+PREHOOK: query: SELECT * FROM myinput1 a FULL OUTER JOIN myinput1 b ON a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM myinput1 a FULL OUTER JOIN myinput1 b ON a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	35
+NULL	NULL	10	NULL
+NULL	NULL	48	NULL
+NULL	10	NULL	NULL
+NULL	10	10	NULL
+NULL	10	48	NULL
+NULL	35	NULL	NULL
+NULL	35	10	NULL
+NULL	35	48	NULL
+10	NULL	NULL	10
+48	NULL	NULL	NULL
+100	100	100	100
+PREHOOK: query: -- map joins
+SELECT /*+ MAPJOIN(a) */ * FROM myinput1 a JOIN myinput1 b ON a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+POSTHOOK: query: -- map joins
+SELECT /*+ MAPJOIN(a) */ * FROM myinput1 a JOIN myinput1 b ON a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	10	NULL
+NULL	NULL	48	NULL
+NULL	10	NULL	NULL
+NULL	10	10	NULL
+NULL	10	48	NULL
+NULL	35	NULL	NULL
+NULL	35	10	NULL
+NULL	35	48	NULL
+10	NULL	NULL	10
+100	100	100	100
+PREHOOK: query: SELECT /*+ MAPJOIN(b) */ * FROM myinput1 a JOIN myinput1 b ON a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT /*+ MAPJOIN(b) */ * FROM myinput1 a JOIN myinput1 b ON a.key<=>b.value ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@myinput1
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	10	NULL
+NULL	NULL	48	NULL
+NULL	10	NULL	NULL
+NULL	10	10	NULL
+NULL	10	48	NULL
+NULL	35	NULL	NULL
+NULL	35	10	NULL
+NULL	35	48	NULL
+10	NULL	NULL	10
+100	100	100	100
+PREHOOK: query: -- smbs
+CREATE TABLE smb_input1(key int, value int) CLUSTERED BY (key) SORTED BY (key) INTO 2 BUCKETS
+PREHOOK: type: CREATETABLE
+POSTHOOK: query: -- smbs
+CREATE TABLE smb_input1(key int, value int) CLUSTERED BY (key) SORTED BY (key) INTO 2 BUCKETS
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: default@smb_input1
+PREHOOK: query: CREATE TABLE smb_input2(key int, value int) CLUSTERED BY (value) SORTED BY (value) INTO 2 BUCKETS
+PREHOOK: type: CREATETABLE
+POSTHOOK: query: CREATE TABLE smb_input2(key int, value int) CLUSTERED BY (value) SORTED BY (value) INTO 2 BUCKETS
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: default@smb_input2
+PREHOOK: query: LOAD DATA LOCAL INPATH '../data/files/in8.txt' into table smb_input1
+PREHOOK: type: LOAD
+PREHOOK: Output: default@smb_input1
+POSTHOOK: query: LOAD DATA LOCAL INPATH '../data/files/in8.txt' into table smb_input1
+POSTHOOK: type: LOAD
+POSTHOOK: Output: default@smb_input1
+PREHOOK: query: LOAD DATA LOCAL INPATH '../data/files/in9.txt' into table smb_input1
+PREHOOK: type: LOAD
+PREHOOK: Output: default@smb_input1
+POSTHOOK: query: LOAD DATA LOCAL INPATH '../data/files/in9.txt' into table smb_input1
+POSTHOOK: type: LOAD
+POSTHOOK: Output: default@smb_input1
+PREHOOK: query: LOAD DATA LOCAL INPATH '../data/files/in8.txt' into table smb_input2
+PREHOOK: type: LOAD
+PREHOOK: Output: default@smb_input2
+POSTHOOK: query: LOAD DATA LOCAL INPATH '../data/files/in8.txt' into table smb_input2
+POSTHOOK: type: LOAD
+POSTHOOK: Output: default@smb_input2
+PREHOOK: query: LOAD DATA LOCAL INPATH '../data/files/in9.txt' into table smb_input2
+PREHOOK: type: LOAD
+PREHOOK: Output: default@smb_input2
+POSTHOOK: query: LOAD DATA LOCAL INPATH '../data/files/in9.txt' into table smb_input2
+POSTHOOK: type: LOAD
+POSTHOOK: Output: default@smb_input2
+PREHOOK: query: SELECT /*+ MAPJOIN(a) */ * FROM smb_input1 a JOIN smb_input1 b ON a.key <=> b.key ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@smb_input1
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT /*+ MAPJOIN(a) */ * FROM smb_input1 a JOIN smb_input1 b ON a.key <=> b.key ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@smb_input1
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	10
+NULL	NULL	NULL	10
+NULL	NULL	NULL	35
+NULL	NULL	NULL	35
+NULL	NULL	NULL	110
+NULL	NULL	NULL	110
+NULL	NULL	NULL	135
+NULL	NULL	NULL	135
+NULL	10	NULL	NULL
+NULL	10	NULL	NULL
+NULL	10	NULL	10
+NULL	10	NULL	35
+NULL	10	NULL	110
+NULL	10	NULL	135
+NULL	35	NULL	NULL
+NULL	35	NULL	NULL
+NULL	35	NULL	10
+NULL	35	NULL	35
+NULL	35	NULL	110
+NULL	35	NULL	135
+NULL	110	NULL	NULL
+NULL	110	NULL	NULL
+NULL	110	NULL	10
+NULL	110	NULL	35
+NULL	110	NULL	110
+NULL	110	NULL	135
+NULL	135	NULL	NULL
+NULL	135	NULL	NULL
+NULL	135	NULL	10
+NULL	135	NULL	35
+NULL	135	NULL	110
+NULL	135	NULL	135
+10	NULL	10	NULL
+48	NULL	48	NULL
+100	100	100	100
+110	NULL	110	NULL
+148	NULL	148	NULL
+200	200	200	200
+PREHOOK: query: SELECT /*+ MAPJOIN(a) */ * FROM smb_input1 a JOIN smb_input1 b ON a.key <=> b.key AND a.value <=> b.value ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@smb_input1
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT /*+ MAPJOIN(a) */ * FROM smb_input1 a JOIN smb_input1 b ON a.key <=> b.key AND a.value <=> b.value ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@smb_input1
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+100	100	100	100
+200	200	200	200
+PREHOOK: query: SELECT /*+ MAPJOIN(a) */ * FROM smb_input1 a RIGHT OUTER JOIN smb_input1 b ON a.key <=> b.key ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@smb_input1
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT /*+ MAPJOIN(a) */ * FROM smb_input1 a RIGHT OUTER JOIN smb_input1 b ON a.key <=> b.key ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@smb_input1
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	10
+NULL	NULL	NULL	10
+NULL	NULL	NULL	35
+NULL	NULL	NULL	35
+NULL	NULL	NULL	110
+NULL	NULL	NULL	110
+NULL	NULL	NULL	135
+NULL	NULL	NULL	135
+NULL	10	NULL	NULL
+NULL	10	NULL	NULL
+NULL	10	NULL	10
+NULL	10	NULL	35
+NULL	10	NULL	110
+NULL	10	NULL	135
+NULL	35	NULL	NULL
+NULL	35	NULL	NULL
+NULL	35	NULL	10
+NULL	35	NULL	35
+NULL	35	NULL	110
+NULL	35	NULL	135
+NULL	110	NULL	NULL
+NULL	110	NULL	NULL
+NULL	110	NULL	10
+NULL	110	NULL	35
+NULL	110	NULL	110
+NULL	110	NULL	135
+NULL	135	NULL	NULL
+NULL	135	NULL	NULL
+NULL	135	NULL	10
+NULL	135	NULL	35
+NULL	135	NULL	110
+NULL	135	NULL	135
+10	NULL	10	NULL
+48	NULL	48	NULL
+100	100	100	100
+110	NULL	110	NULL
+148	NULL	148	NULL
+200	200	200	200
+PREHOOK: query: SELECT /*+ MAPJOIN(b) */ * FROM smb_input1 a JOIN smb_input1 b ON a.key <=> b.key ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@smb_input1
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT /*+ MAPJOIN(b) */ * FROM smb_input1 a JOIN smb_input1 b ON a.key <=> b.key ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@smb_input1
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	10
+NULL	NULL	NULL	10
+NULL	NULL	NULL	35
+NULL	NULL	NULL	35
+NULL	NULL	NULL	110
+NULL	NULL	NULL	110
+NULL	NULL	NULL	135
+NULL	NULL	NULL	135
+NULL	10	NULL	NULL
+NULL	10	NULL	NULL
+NULL	10	NULL	10
+NULL	10	NULL	35
+NULL	10	NULL	110
+NULL	10	NULL	135
+NULL	35	NULL	NULL
+NULL	35	NULL	NULL
+NULL	35	NULL	10
+NULL	35	NULL	35
+NULL	35	NULL	110
+NULL	35	NULL	135
+NULL	110	NULL	NULL
+NULL	110	NULL	NULL
+NULL	110	NULL	10
+NULL	110	NULL	35
+NULL	110	NULL	110
+NULL	110	NULL	135
+NULL	135	NULL	NULL
+NULL	135	NULL	NULL
+NULL	135	NULL	10
+NULL	135	NULL	35
+NULL	135	NULL	110
+NULL	135	NULL	135
+10	NULL	10	NULL
+48	NULL	48	NULL
+100	100	100	100
+110	NULL	110	NULL
+148	NULL	148	NULL
+200	200	200	200
+PREHOOK: query: SELECT /*+ MAPJOIN(b) */ * FROM smb_input1 a LEFT OUTER JOIN smb_input1 b ON a.key <=> b.key ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@smb_input1
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT /*+ MAPJOIN(b) */ * FROM smb_input1 a LEFT OUTER JOIN smb_input1 b ON a.key <=> b.key ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@smb_input1
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	10
+NULL	NULL	NULL	10
+NULL	NULL	NULL	35
+NULL	NULL	NULL	35
+NULL	NULL	NULL	110
+NULL	NULL	NULL	110
+NULL	NULL	NULL	135
+NULL	NULL	NULL	135
+NULL	10	NULL	NULL
+NULL	10	NULL	NULL
+NULL	10	NULL	10
+NULL	10	NULL	35
+NULL	10	NULL	110
+NULL	10	NULL	135
+NULL	35	NULL	NULL
+NULL	35	NULL	NULL
+NULL	35	NULL	10
+NULL	35	NULL	35
+NULL	35	NULL	110
+NULL	35	NULL	135
+NULL	110	NULL	NULL
+NULL	110	NULL	NULL
+NULL	110	NULL	10
+NULL	110	NULL	35
+NULL	110	NULL	110
+NULL	110	NULL	135
+NULL	135	NULL	NULL
+NULL	135	NULL	NULL
+NULL	135	NULL	10
+NULL	135	NULL	35
+NULL	135	NULL	110
+NULL	135	NULL	135
+10	NULL	10	NULL
+48	NULL	48	NULL
+100	100	100	100
+110	NULL	110	NULL
+148	NULL	148	NULL
+200	200	200	200
+PREHOOK: query: SELECT /*+ MAPJOIN(a) */ * FROM smb_input1 a JOIN smb_input2 b ON a.key <=> b.value ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@smb_input1
+PREHOOK: Input: default@smb_input2
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT /*+ MAPJOIN(a) */ * FROM smb_input1 a JOIN smb_input2 b ON a.key <=> b.value ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@smb_input1
+POSTHOOK: Input: default@smb_input2
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	10	NULL
+NULL	NULL	10	NULL
+NULL	NULL	48	NULL
+NULL	NULL	48	NULL
+NULL	NULL	110	NULL
+NULL	NULL	110	NULL
+NULL	NULL	148	NULL
+NULL	NULL	148	NULL
+NULL	10	NULL	NULL
+NULL	10	NULL	NULL
+NULL	10	10	NULL
+NULL	10	48	NULL
+NULL	10	110	NULL
+NULL	10	148	NULL
+NULL	35	NULL	NULL
+NULL	35	NULL	NULL
+NULL	35	10	NULL
+NULL	35	48	NULL
+NULL	35	110	NULL
+NULL	35	148	NULL
+NULL	110	NULL	NULL
+NULL	110	NULL	NULL
+NULL	110	10	NULL
+NULL	110	48	NULL
+NULL	110	110	NULL
+NULL	110	148	NULL
+NULL	135	NULL	NULL
+NULL	135	NULL	NULL
+NULL	135	10	NULL
+NULL	135	48	NULL
+NULL	135	110	NULL
+NULL	135	148	NULL
+10	NULL	NULL	10
+100	100	100	100
+110	NULL	NULL	110
+200	200	200	200
+PREHOOK: query: SELECT /*+ MAPJOIN(b) */ * FROM smb_input1 a JOIN smb_input2 b ON a.key <=> b.value ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@smb_input1
+PREHOOK: Input: default@smb_input2
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT /*+ MAPJOIN(b) */ * FROM smb_input1 a JOIN smb_input2 b ON a.key <=> b.value ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@smb_input1
+POSTHOOK: Input: default@smb_input2
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	10	NULL
+NULL	NULL	10	NULL
+NULL	NULL	48	NULL
+NULL	NULL	48	NULL
+NULL	NULL	110	NULL
+NULL	NULL	110	NULL
+NULL	NULL	148	NULL
+NULL	NULL	148	NULL
+NULL	10	NULL	NULL
+NULL	10	NULL	NULL
+NULL	10	10	NULL
+NULL	10	48	NULL
+NULL	10	110	NULL
+NULL	10	148	NULL
+NULL	35	NULL	NULL
+NULL	35	NULL	NULL
+NULL	35	10	NULL
+NULL	35	48	NULL
+NULL	35	110	NULL
+NULL	35	148	NULL
+NULL	110	NULL	NULL
+NULL	110	NULL	NULL
+NULL	110	10	NULL
+NULL	110	48	NULL
+NULL	110	110	NULL
+NULL	110	148	NULL
+NULL	135	NULL	NULL
+NULL	135	NULL	NULL
+NULL	135	10	NULL
+NULL	135	48	NULL
+NULL	135	110	NULL
+NULL	135	148	NULL
+10	NULL	NULL	10
+100	100	100	100
+110	NULL	NULL	110
+200	200	200	200
+PREHOOK: query: SELECT /*+ MAPJOIN(b) */ * FROM smb_input1 a LEFT OUTER JOIN smb_input2 b ON a.key <=> b.value ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@smb_input1
+PREHOOK: Input: default@smb_input2
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT /*+ MAPJOIN(b) */ * FROM smb_input1 a LEFT OUTER JOIN smb_input2 b ON a.key <=> b.value ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@smb_input1
+POSTHOOK: Input: default@smb_input2
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	10	NULL
+NULL	NULL	10	NULL
+NULL	NULL	48	NULL
+NULL	NULL	48	NULL
+NULL	NULL	110	NULL
+NULL	NULL	110	NULL
+NULL	NULL	148	NULL
+NULL	NULL	148	NULL
+NULL	10	NULL	NULL
+NULL	10	NULL	NULL
+NULL	10	10	NULL
+NULL	10	48	NULL
+NULL	10	110	NULL
+NULL	10	148	NULL
+NULL	35	NULL	NULL
+NULL	35	NULL	NULL
+NULL	35	10	NULL
+NULL	35	48	NULL
+NULL	35	110	NULL
+NULL	35	148	NULL
+NULL	110	NULL	NULL
+NULL	110	NULL	NULL
+NULL	110	10	NULL
+NULL	110	48	NULL
+NULL	110	110	NULL
+NULL	110	148	NULL
+NULL	135	NULL	NULL
+NULL	135	NULL	NULL
+NULL	135	10	NULL
+NULL	135	48	NULL
+NULL	135	110	NULL
+NULL	135	148	NULL
+10	NULL	NULL	10
+48	NULL	NULL	NULL
+100	100	100	100
+110	NULL	NULL	110
+148	NULL	NULL	NULL
+200	200	200	200
+PREHOOK: query: SELECT /*+ MAPJOIN(a) */ * FROM smb_input1 a RIGHT OUTER JOIN smb_input2 b ON a.key <=> b.value ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@smb_input1
+PREHOOK: Input: default@smb_input2
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT /*+ MAPJOIN(a) */ * FROM smb_input1 a RIGHT OUTER JOIN smb_input2 b ON a.key <=> b.value ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@smb_input1
+POSTHOOK: Input: default@smb_input2
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	35
+NULL	NULL	NULL	135
+NULL	NULL	10	NULL
+NULL	NULL	10	NULL
+NULL	NULL	48	NULL
+NULL	NULL	48	NULL
+NULL	NULL	110	NULL
+NULL	NULL	110	NULL
+NULL	NULL	148	NULL
+NULL	NULL	148	NULL
+NULL	10	NULL	NULL
+NULL	10	NULL	NULL
+NULL	10	10	NULL
+NULL	10	48	NULL
+NULL	10	110	NULL
+NULL	10	148	NULL
+NULL	35	NULL	NULL
+NULL	35	NULL	NULL
+NULL	35	10	NULL
+NULL	35	48	NULL
+NULL	35	110	NULL
+NULL	35	148	NULL
+NULL	110	NULL	NULL
+NULL	110	NULL	NULL
+NULL	110	10	NULL
+NULL	110	48	NULL
+NULL	110	110	NULL
+NULL	110	148	NULL
+NULL	135	NULL	NULL
+NULL	135	NULL	NULL
+NULL	135	10	NULL
+NULL	135	48	NULL
+NULL	135	110	NULL
+NULL	135	148	NULL
+10	NULL	NULL	10
+100	100	100	100
+110	NULL	NULL	110
+200	200	200	200
+PREHOOK: query: SELECT /*+ MAPJOIN(a) */ * FROM smb_input2 a JOIN smb_input2 b ON a.value <=> b.value ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@smb_input2
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT /*+ MAPJOIN(a) */ * FROM smb_input2 a JOIN smb_input2 b ON a.value <=> b.value ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@smb_input2
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	10	NULL
+NULL	NULL	10	NULL
+NULL	NULL	48	NULL
+NULL	NULL	48	NULL
+NULL	NULL	110	NULL
+NULL	NULL	110	NULL
+NULL	NULL	148	NULL
+NULL	NULL	148	NULL
+NULL	10	NULL	10
+NULL	35	NULL	35
+NULL	110	NULL	110
+NULL	135	NULL	135
+10	NULL	NULL	NULL
+10	NULL	NULL	NULL
+10	NULL	10	NULL
+10	NULL	48	NULL
+10	NULL	110	NULL
+10	NULL	148	NULL
+48	NULL	NULL	NULL
+48	NULL	NULL	NULL
+48	NULL	10	NULL
+48	NULL	48	NULL
+48	NULL	110	NULL
+48	NULL	148	NULL
+100	100	100	100
+110	NULL	NULL	NULL
+110	NULL	NULL	NULL
+110	NULL	10	NULL
+110	NULL	48	NULL
+110	NULL	110	NULL
+110	NULL	148	NULL
+148	NULL	NULL	NULL
+148	NULL	NULL	NULL
+148	NULL	10	NULL
+148	NULL	48	NULL
+148	NULL	110	NULL
+148	NULL	148	NULL
+200	200	200	200
+PREHOOK: query: SELECT /*+ MAPJOIN(a) */ * FROM smb_input2 a RIGHT OUTER JOIN smb_input2 b ON a.value <=> b.value ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@smb_input2
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT /*+ MAPJOIN(a) */ * FROM smb_input2 a RIGHT OUTER JOIN smb_input2 b ON a.value <=> b.value ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@smb_input2
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	10	NULL
+NULL	NULL	10	NULL
+NULL	NULL	48	NULL
+NULL	NULL	48	NULL
+NULL	NULL	110	NULL
+NULL	NULL	110	NULL
+NULL	NULL	148	NULL
+NULL	NULL	148	NULL
+NULL	10	NULL	10
+NULL	35	NULL	35
+NULL	110	NULL	110
+NULL	135	NULL	135
+10	NULL	NULL	NULL
+10	NULL	NULL	NULL
+10	NULL	10	NULL
+10	NULL	48	NULL
+10	NULL	110	NULL
+10	NULL	148	NULL
+48	NULL	NULL	NULL
+48	NULL	NULL	NULL
+48	NULL	10	NULL
+48	NULL	48	NULL
+48	NULL	110	NULL
+48	NULL	148	NULL
+100	100	100	100
+110	NULL	NULL	NULL
+110	NULL	NULL	NULL
+110	NULL	10	NULL
+110	NULL	48	NULL
+110	NULL	110	NULL
+110	NULL	148	NULL
+148	NULL	NULL	NULL
+148	NULL	NULL	NULL
+148	NULL	10	NULL
+148	NULL	48	NULL
+148	NULL	110	NULL
+148	NULL	148	NULL
+200	200	200	200
+PREHOOK: query: SELECT /*+ MAPJOIN(b) */ * FROM smb_input2 a JOIN smb_input2 b ON a.value <=> b.value ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@smb_input2
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT /*+ MAPJOIN(b) */ * FROM smb_input2 a JOIN smb_input2 b ON a.value <=> b.value ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@smb_input2
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	10	NULL
+NULL	NULL	10	NULL
+NULL	NULL	48	NULL
+NULL	NULL	48	NULL
+NULL	NULL	110	NULL
+NULL	NULL	110	NULL
+NULL	NULL	148	NULL
+NULL	NULL	148	NULL
+NULL	10	NULL	10
+NULL	35	NULL	35
+NULL	110	NULL	110
+NULL	135	NULL	135
+10	NULL	NULL	NULL
+10	NULL	NULL	NULL
+10	NULL	10	NULL
+10	NULL	48	NULL
+10	NULL	110	NULL
+10	NULL	148	NULL
+48	NULL	NULL	NULL
+48	NULL	NULL	NULL
+48	NULL	10	NULL
+48	NULL	48	NULL
+48	NULL	110	NULL
+48	NULL	148	NULL
+100	100	100	100
+110	NULL	NULL	NULL
+110	NULL	NULL	NULL
+110	NULL	10	NULL
+110	NULL	48	NULL
+110	NULL	110	NULL
+110	NULL	148	NULL
+148	NULL	NULL	NULL
+148	NULL	NULL	NULL
+148	NULL	10	NULL
+148	NULL	48	NULL
+148	NULL	110	NULL
+148	NULL	148	NULL
+200	200	200	200
+PREHOOK: query: SELECT /*+ MAPJOIN(b) */ * FROM smb_input2 a LEFT OUTER JOIN smb_input2 b ON a.value <=> b.value ORDER BY a.key, a.value, b.key, b.value
+PREHOOK: type: QUERY
+PREHOOK: Input: default@smb_input2
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT /*+ MAPJOIN(b) */ * FROM smb_input2 a LEFT OUTER JOIN smb_input2 b ON a.value <=> b.value ORDER BY a.key, a.value, b.key, b.value
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@smb_input2
+#### A masked pattern was here ####
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	NULL	NULL
+NULL	NULL	10	NULL
+NULL	NULL	10	NULL
+NULL	NULL	48	NULL
+NULL	NULL	48	NULL
+NULL	NULL	110	NULL
+NULL	NULL	110	NULL
+NULL	NULL	148	NULL
+NULL	NULL	148	NULL
+NULL	10	NULL	10
+NULL	35	NULL	35
+NULL	110	NULL	110
+NULL	135	NULL	135
+10	NULL	NULL	NULL
+10	NULL	NULL	NULL
+10	NULL	10	NULL
+10	NULL	48	NULL
+10	NULL	110	NULL
+10	NULL	148	NULL
+48	NULL	NULL	NULL
+48	NULL	NULL	NULL
+48	NULL	10	NULL
+48	NULL	48	NULL
+48	NULL	110	NULL
+48	NULL	148	NULL
+100	100	100	100
+110	NULL	NULL	NULL
+110	NULL	NULL	NULL
+110	NULL	10	NULL
+110	NULL	48	NULL
+110	NULL	110	NULL
+110	NULL	148	NULL
+148	NULL	NULL	NULL
+148	NULL	NULL	NULL
+148	NULL	10	NULL
+148	NULL	48	NULL
+148	NULL	110	NULL
+148	NULL	148	NULL
+200	200	200	200

Modified: hive/trunk/ql/src/test/results/compiler/plan/join1.q.xml
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/compiler/plan/join1.q.xml?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/test/results/compiler/plan/join1.q.xml (original)
+++ hive/trunk/ql/src/test/results/compiler/plan/join1.q.xml Wed Mar  7 10:11:03 2012
@@ -1489,8 +1489,11 @@
         </void> 
         <void property="noOuterJoin"> 
          <boolean>true</boolean> 
-        </void> 
-        <void property="outputColumnNames"> 
+        </void>
+        <void property="nullSafes">
+         <array class="boolean" length="1"/>
+        </void>
+        <void property="outputColumnNames">
          <object class="java.util.ArrayList"> 
           <void method="add"> 
            <string>_col0</string> 

Modified: hive/trunk/ql/src/test/results/compiler/plan/join2.q.xml
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/compiler/plan/join2.q.xml?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/test/results/compiler/plan/join2.q.xml (original)
+++ hive/trunk/ql/src/test/results/compiler/plan/join2.q.xml Wed Mar  7 10:11:03 2012
@@ -1455,8 +1455,11 @@
             </void> 
             <void property="noOuterJoin"> 
              <boolean>true</boolean> 
-            </void> 
-            <void property="outputColumnNames"> 
+            </void>
+               <void property="nullSafes">
+              <array class="boolean" length="1"/>
+            </void>
+            <void property="outputColumnNames">
              <object class="java.util.ArrayList"> 
               <void method="add"> 
                <string>_col4</string> 
@@ -2796,8 +2799,11 @@
         </void> 
         <void property="noOuterJoin"> 
          <boolean>true</boolean> 
-        </void> 
-        <void property="outputColumnNames"> 
+        </void>
+        <void property="nullSafes">
+         <array class="boolean" length="1"/>
+        </void>
+        <void property="outputColumnNames">
          <object class="java.util.ArrayList"> 
           <void method="add"> 
            <string>_col0</string> 

Modified: hive/trunk/ql/src/test/results/compiler/plan/join3.q.xml
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/compiler/plan/join3.q.xml?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/test/results/compiler/plan/join3.q.xml (original)
+++ hive/trunk/ql/src/test/results/compiler/plan/join3.q.xml Wed Mar  7 10:11:03 2012
@@ -1912,8 +1912,11 @@
         </void> 
         <void property="noOuterJoin"> 
          <boolean>true</boolean> 
-        </void> 
-        <void property="outputColumnNames"> 
+        </void>
+        <void property="nullSafes">
+         <array class="boolean" length="1"/>
+        </void>
+        <void property="outputColumnNames">
          <object class="java.util.ArrayList"> 
           <void method="add"> 
            <string>_col0</string> 

Modified: hive/trunk/ql/src/test/results/compiler/plan/join4.q.xml
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/compiler/plan/join4.q.xml?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/test/results/compiler/plan/join4.q.xml (original)
+++ hive/trunk/ql/src/test/results/compiler/plan/join4.q.xml Wed Mar  7 10:11:03 2012
@@ -2227,8 +2227,11 @@
            <object class="java.util.ArrayList"/> 
           </void> 
          </object> 
-        </void> 
-        <void property="outputColumnNames"> 
+        </void>
+        <void property="nullSafes">
+         <array class="boolean" length="1"/>
+        </void>
+        <void property="outputColumnNames">
          <object class="java.util.ArrayList"> 
           <void method="add"> 
            <string>_col0</string> 

Modified: hive/trunk/ql/src/test/results/compiler/plan/join5.q.xml
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/compiler/plan/join5.q.xml?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/test/results/compiler/plan/join5.q.xml (original)
+++ hive/trunk/ql/src/test/results/compiler/plan/join5.q.xml Wed Mar  7 10:11:03 2012
@@ -2227,8 +2227,11 @@
            <object class="java.util.ArrayList"/> 
           </void> 
          </object> 
-        </void> 
-        <void property="outputColumnNames"> 
+        </void>
+        <void property="nullSafes">
+         <array class="boolean" length="1"/>
+        </void>
+        <void property="outputColumnNames">
          <object class="java.util.ArrayList"> 
           <void method="add"> 
            <string>_col0</string> 

Modified: hive/trunk/ql/src/test/results/compiler/plan/join6.q.xml
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/compiler/plan/join6.q.xml?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/test/results/compiler/plan/join6.q.xml (original)
+++ hive/trunk/ql/src/test/results/compiler/plan/join6.q.xml Wed Mar  7 10:11:03 2012
@@ -2227,8 +2227,11 @@
            <object class="java.util.ArrayList"/> 
           </void> 
          </object> 
-        </void> 
-        <void property="outputColumnNames"> 
+        </void>
+        <void property="nullSafes">
+         <array class="boolean" length="1"/>
+        </void>
+        <void property="outputColumnNames">
          <object class="java.util.ArrayList"> 
           <void method="add"> 
            <string>_col0</string> 

Modified: hive/trunk/ql/src/test/results/compiler/plan/join7.q.xml
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/compiler/plan/join7.q.xml?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/test/results/compiler/plan/join7.q.xml (original)
+++ hive/trunk/ql/src/test/results/compiler/plan/join7.q.xml Wed Mar  7 10:11:03 2012
@@ -3140,8 +3140,11 @@
            <object class="java.util.ArrayList"/> 
           </void> 
          </object> 
-        </void> 
-        <void property="outputColumnNames"> 
+        </void>
+        <void property="nullSafes">
+         <array class="boolean" length="1"/>
+        </void>
+        <void property="outputColumnNames">
          <object class="java.util.ArrayList"> 
           <void method="add"> 
            <string>_col0</string> 

Modified: hive/trunk/ql/src/test/results/compiler/plan/join8.q.xml
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/compiler/plan/join8.q.xml?rev=1297919&r1=1297918&r2=1297919&view=diff
==============================================================================
--- hive/trunk/ql/src/test/results/compiler/plan/join8.q.xml (original)
+++ hive/trunk/ql/src/test/results/compiler/plan/join8.q.xml Wed Mar  7 10:11:03 2012
@@ -2424,8 +2424,11 @@
            <object class="java.util.ArrayList"/> 
           </void> 
          </object> 
-        </void> 
-        <void property="outputColumnNames"> 
+        </void>
+        <void property="nullSafes">
+         <array class="boolean" length="1"/>
+        </void>
+        <void property="outputColumnNames">
          <object class="java.util.ArrayList"> 
           <void method="add"> 
            <string>_col0</string>