You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by ha...@apache.org on 2020/06/01 17:27:01 UTC

[hive] branch master updated: HIVE-23435 : Full outer join result is missing rows (Mustafa Iman via Ashutosh Chauhan)

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

hashutosh 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 779c42f  HIVE-23435 : Full outer join result is missing rows (Mustafa Iman via Ashutosh Chauhan)
779c42f is described below

commit 779c42fa3c73f41785eb3266f3438ab9e2a75032
Author: Mustafa Iman <mu...@gmail.com>
AuthorDate: Mon Jun 1 10:26:14 2020 -0700

    HIVE-23435 : Full outer join result is missing rows (Mustafa Iman via Ashutosh Chauhan)
    
    Signed-off-by: Ashutosh Chauhan <ha...@apache.org>
---
 .../hadoop/hive/ql/exec/CommonJoinOperator.java    |  18 +++-
 .../hive/ql/exec/CommonMergeJoinOperator.java      |   2 +-
 .../apache/hadoop/hive/ql/exec/JoinOperator.java   |   1 +
 .../hadoop/hive/ql/exec/MapJoinOperator.java       |   1 +
 .../hadoop/hive/ql/exec/SMBMapJoinOperator.java    |   1 +
 .../ql/exec/vector/VectorMapJoinBaseOperator.java  |   2 -
 .../ql/exec/vector/VectorSMBMapJoinOperator.java   |   1 -
 .../clientpositive/vector_full_outer_join2.q       |  28 +++++
 .../results/clientpositive/llap/join_1to1.q.out    |  84 ++++++++++++---
 .../llap/vector_full_outer_join2.q.out             | 113 +++++++++++++++++++++
 10 files changed, 233 insertions(+), 18 deletions(-)

diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonJoinOperator.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonJoinOperator.java
index 2d76848..7a7c8a5 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonJoinOperator.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonJoinOperator.java
@@ -341,6 +341,8 @@ public abstract class CommonJoinOperator<T extends JoinDesc> extends
     forwardCache = new Object[totalSz];
     aliasFilterTags = new short[numAliases];
     Arrays.fill(aliasFilterTags, (byte)0xff);
+    aliasFilterTagsNext = new short[numAliases];
+    Arrays.fill(aliasFilterTagsNext, (byte) 0xff);
 
     filterTags = new short[numAliases];
     skipVectors = new boolean[numAliases][];
@@ -478,6 +480,7 @@ public abstract class CommonJoinOperator<T extends JoinDesc> extends
    *   100, 30 :   N,  N
    */
   protected transient short[] aliasFilterTags;
+  protected transient short[] aliasFilterTagsNext;
 
   // all evaluation should be processed here for valid aliasFilterTags
   //
@@ -491,11 +494,21 @@ public abstract class CommonJoinOperator<T extends JoinDesc> extends
       short filterTag = JoinUtil.isFiltered(row, joinFilters[alias],
           joinFilterObjectInspectors[alias], filterMaps[alias]);
       nr.add(new ShortWritable(filterTag));
-      aliasFilterTags[alias] &= filterTag;
     }
     return nr;
   }
 
+  protected void addToAliasFilterTags(byte alias, List<Object> object, boolean isNextGroup) {
+    boolean hasFilter = hasFilter(alias);
+    if (hasFilter) {
+      if (isNextGroup) {
+        aliasFilterTagsNext[alias] &= ((ShortWritable) (object.get(object.size() - 1))).get();
+      } else {
+        aliasFilterTags[alias] &= ((ShortWritable) (object.get(object.size() - 1))).get();
+      }
+    }
+  }
+
   // fill forwardCache with skipvector
   // returns whether a record was forwarded
   private boolean createForwardJoinObject(boolean[] skip) throws HiveException {
@@ -961,7 +974,8 @@ public abstract class CommonJoinOperator<T extends JoinDesc> extends
         genJoinObject();
       }
     }
-    Arrays.fill(aliasFilterTags, (byte)0xff);
+    System.arraycopy(aliasFilterTagsNext, 0, aliasFilterTags, 0, aliasFilterTagsNext.length);
+    Arrays.fill(aliasFilterTagsNext, (byte) 0xff);
   }
 
   protected void reportProgress() {
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonMergeJoinOperator.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonMergeJoinOperator.java
index 581577e..0d9dc46 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonMergeJoinOperator.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/CommonMergeJoinOperator.java
@@ -46,7 +46,6 @@ import org.apache.hadoop.hive.ql.plan.OperatorDesc;
 import org.apache.hadoop.hive.ql.plan.api.OperatorType;
 import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils;
 import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils.ObjectInspectorCopyOption;
-import org.apache.hadoop.hive.serde2.objectinspector.StructField;
 import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
 import org.apache.hadoop.io.WritableComparable;
 import org.apache.hadoop.io.WritableComparator;
@@ -242,6 +241,7 @@ public class CommonMergeJoinOperator extends AbstractMapJoinOperator<CommonMerge
 
     //have we reached a new key group?
     boolean nextKeyGroup = processKey(alias, key);
+    addToAliasFilterTags(alias, value, nextKeyGroup);
     if (nextKeyGroup) {
       //assert this.nextGroupStorage[alias].size() == 0;
       this.nextGroupStorage[alias].addRow(value);
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/JoinOperator.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/JoinOperator.java
index 451ba1f..9661bc9 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/JoinOperator.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/JoinOperator.java
@@ -83,6 +83,7 @@ public class JoinOperator extends CommonJoinOperator<JoinDesc> implements Serial
       alias = (byte) tag;
 
       List<Object> nr = getFilteredValue(alias, row);
+      addToAliasFilterTags(alias, nr, false);
 
       if (handleSkewJoin) {
         skewJoinKeyContext.handleSkew(tag);
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/MapJoinOperator.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/MapJoinOperator.java
index 07b1fba..489d09f 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/MapJoinOperator.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/MapJoinOperator.java
@@ -582,6 +582,7 @@ public class MapJoinOperator extends AbstractMapJoinOperator<MapJoinDesc> implem
       }
       if (joinNeeded) {
         List<Object> value = getFilteredValue(alias, row);
+        addToAliasFilterTags(alias, value, false);
         // Add the value to the ArrayList
         storage[alias].addRow(value);
         // generate the output records
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/SMBMapJoinOperator.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/SMBMapJoinOperator.java
index c09bf53..55d6a6a 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/SMBMapJoinOperator.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/SMBMapJoinOperator.java
@@ -288,6 +288,7 @@ public class SMBMapJoinOperator extends AbstractMapJoinOperator<SMBJoinDesc> imp
 
     //have we reached a new key group?
     boolean nextKeyGroup = processKey(alias, key);
+    addToAliasFilterTags(alias, value, nextKeyGroup);
     if (nextKeyGroup) {
       //assert this.nextGroupStorage[alias].size() == 0;
       this.nextGroupStorage[alias].addRow(value);
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorMapJoinBaseOperator.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorMapJoinBaseOperator.java
index e80a3e2..b39f802 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorMapJoinBaseOperator.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorMapJoinBaseOperator.java
@@ -20,11 +20,9 @@ package org.apache.hadoop.hive.ql.exec.vector;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.Future;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorSMBMapJoinOperator.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorSMBMapJoinOperator.java
index bef1a79..b0a5138 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorSMBMapJoinOperator.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorSMBMapJoinOperator.java
@@ -37,7 +37,6 @@ import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
 import org.apache.hadoop.hive.ql.plan.OperatorDesc;
 import org.apache.hadoop.hive.ql.plan.SMBJoinDesc;
 import org.apache.hadoop.hive.ql.plan.VectorDesc;
-import org.apache.hadoop.hive.ql.plan.VectorMapJoinDesc;
 import org.apache.hadoop.hive.ql.plan.VectorSMBJoinDesc;
 import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
 import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils;
diff --git a/ql/src/test/queries/clientpositive/vector_full_outer_join2.q b/ql/src/test/queries/clientpositive/vector_full_outer_join2.q
new file mode 100644
index 0000000..fefd0e0
--- /dev/null
+++ b/ql/src/test/queries/clientpositive/vector_full_outer_join2.q
@@ -0,0 +1,28 @@
+create table t_letters (z char(12), x int, y int);
+
+insert into t_letters values
+('one', 1, 50),
+('two', 2, 30),
+('three', 3, 30),
+('four', 4, 60),
+('five', 5, 70),
+('six', 6, 80);
+
+create table t_roman (z char(12), x int, y int);
+
+insert into t_roman values
+('I', 1, 50),
+('II', 2, 30),
+('III', 3, 30),
+('IV', 4, 60),
+('V', 5, 70),
+('VI', 6, 80);
+
+
+select x1.`z`, x1.`x`, x1.`y`,
+       x2.`z`, x2.`x`, x2.`y`
+from t_letters x1 full outer join t_roman x2 on (x1.`x` > 3) and (x2.`x` < 4) and (x1.`x` = x2.`x`);
+
+select x1.`z`, x1.`x`, x1.`y`,
+       x2.`z`, x2.`x`, x2.`y`
+from t_letters x1 full outer join t_roman x2 on (x1.`x` > 2) and (x2.`x` < 4) and (x1.`x` = x2.`x`);
\ No newline at end of file
diff --git a/ql/src/test/results/clientpositive/llap/join_1to1.q.out b/ql/src/test/results/clientpositive/llap/join_1to1.q.out
index 5619687..8495894 100644
--- a/ql/src/test/results/clientpositive/llap/join_1to1.q.out
+++ b/ql/src/test/results/clientpositive/llap/join_1to1.q.out
@@ -132,7 +132,6 @@ POSTHOOK: Input: default@join_1to1_2
 30	10030	66	NULL	NULL	NULL
 35	10035	88	NULL	NULL	NULL
 40	10040	66	40	10040	66
-40	10040	66	NULL	NULL	NULL
 40	10040	88	NULL	NULL	NULL
 5	10005	66	5	10005	66
 50	10050	66	50	10050	66
@@ -143,17 +142,22 @@ POSTHOOK: Input: default@join_1to1_2
 60	10040	66	60	10040	66
 60	10040	66	60	10040	66
 60	10040	66	60	10040	66
+70	10040	66	NULL	NULL	NULL
+70	10040	66	NULL	NULL	NULL
 80	10040	88	NULL	NULL	NULL
 80	10040	88	NULL	NULL	NULL
 NULL	10050	66	NULL	NULL	NULL
 NULL	NULL	66	NULL	NULL	NULL
 NULL	NULL	NULL	10	10010	66
+NULL	NULL	NULL	25	10025	66
 NULL	NULL	NULL	30	10030	88
 NULL	NULL	NULL	35	10035	88
 NULL	NULL	NULL	40	10040	88
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	70	10040	88
 NULL	NULL	NULL	70	10040	88
+NULL	NULL	NULL	80	10040	66
+NULL	NULL	NULL	80	10040	66
 NULL	NULL	NULL	NULL	10050	66
 NULL	NULL	NULL	NULL	NULL	66
 PREHOOK: query: SELECT * FROM join_1to1_1 a full outer join join_1to1_2 b on a.key1 = b.key1 and a.key2 = b.key2
@@ -218,7 +222,6 @@ POSTHOOK: Input: default@join_1to1_2
 30	10030	66	NULL	NULL	NULL
 35	10035	88	NULL	NULL	NULL
 40	10040	66	40	10040	66
-40	10040	66	NULL	NULL	NULL
 40	10040	88	NULL	NULL	NULL
 5	10005	66	5	10005	66
 50	10050	66	50	10050	66
@@ -229,17 +232,22 @@ POSTHOOK: Input: default@join_1to1_2
 60	10040	66	60	10040	66
 60	10040	66	60	10040	66
 60	10040	66	60	10040	66
+70	10040	66	NULL	NULL	NULL
+70	10040	66	NULL	NULL	NULL
 80	10040	88	NULL	NULL	NULL
 80	10040	88	NULL	NULL	NULL
 NULL	10050	66	NULL	NULL	NULL
 NULL	NULL	66	NULL	NULL	NULL
 NULL	NULL	NULL	10	10010	66
+NULL	NULL	NULL	25	10025	66
 NULL	NULL	NULL	30	10030	88
 NULL	NULL	NULL	35	10035	88
 NULL	NULL	NULL	40	10040	88
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	70	10040	88
 NULL	NULL	NULL	70	10040	88
+NULL	NULL	NULL	80	10040	66
+NULL	NULL	NULL	80	10040	66
 NULL	NULL	NULL	NULL	10050	66
 NULL	NULL	NULL	NULL	NULL	66
 PREHOOK: query: SELECT * FROM join_1to1_1 a join join_1to1_2 b on a.key1 = b.key1
@@ -344,7 +352,6 @@ POSTHOOK: Input: default@join_1to1_2
 30	10030	66	NULL	NULL	NULL
 35	10035	88	NULL	NULL	NULL
 40	10040	66	40	10040	66
-40	10040	66	NULL	NULL	NULL
 40	10040	88	NULL	NULL	NULL
 5	10005	66	5	10005	66
 50	10050	66	50	10050	66
@@ -355,18 +362,25 @@ POSTHOOK: Input: default@join_1to1_2
 60	10040	66	60	10040	66
 60	10040	66	60	10040	66
 60	10040	66	60	10040	66
+70	10040	66	NULL	NULL	NULL
+70	10040	66	NULL	NULL	NULL
 80	10040	88	NULL	NULL	NULL
 80	10040	88	NULL	NULL	NULL
 NULL	10050	66	NULL	NULL	NULL
 NULL	NULL	66	NULL	NULL	NULL
 NULL	NULL	NULL	10	10010	66
+NULL	NULL	NULL	25	10025	66
 NULL	NULL	NULL	30	10030	88
 NULL	NULL	NULL	35	10035	88
 NULL	NULL	NULL	40	10040	88
+NULL	NULL	NULL	50	10050	66
+NULL	NULL	NULL	50	10050	66
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	70	10040	88
 NULL	NULL	NULL	70	10040	88
+NULL	NULL	NULL	80	10040	66
+NULL	NULL	NULL	80	10040	66
 NULL	NULL	NULL	NULL	10050	66
 NULL	NULL	NULL	NULL	NULL	66
 PREHOOK: query: SELECT * FROM join_1to1_1 a full outer join join_1to1_2 b on a.key1 = b.key1 and a.key2 = b.key2
@@ -431,7 +445,6 @@ POSTHOOK: Input: default@join_1to1_2
 30	10030	66	NULL	NULL	NULL
 35	10035	88	NULL	NULL	NULL
 40	10040	66	40	10040	66
-40	10040	66	NULL	NULL	NULL
 40	10040	88	NULL	NULL	NULL
 5	10005	66	5	10005	66
 50	10050	66	50	10050	66
@@ -442,18 +455,25 @@ POSTHOOK: Input: default@join_1to1_2
 60	10040	66	60	10040	66
 60	10040	66	60	10040	66
 60	10040	66	60	10040	66
+70	10040	66	NULL	NULL	NULL
+70	10040	66	NULL	NULL	NULL
 80	10040	88	NULL	NULL	NULL
 80	10040	88	NULL	NULL	NULL
 NULL	10050	66	NULL	NULL	NULL
 NULL	NULL	66	NULL	NULL	NULL
 NULL	NULL	NULL	10	10010	66
+NULL	NULL	NULL	25	10025	66
 NULL	NULL	NULL	30	10030	88
 NULL	NULL	NULL	35	10035	88
 NULL	NULL	NULL	40	10040	88
+NULL	NULL	NULL	50	10050	66
+NULL	NULL	NULL	50	10050	66
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	70	10040	88
 NULL	NULL	NULL	70	10040	88
+NULL	NULL	NULL	80	10040	66
+NULL	NULL	NULL	80	10040	66
 NULL	NULL	NULL	NULL	10050	66
 NULL	NULL	NULL	NULL	NULL	66
 PREHOOK: query: SELECT * FROM join_1to1_1 a join join_1to1_2 b on a.key1 = b.key1
@@ -558,7 +578,6 @@ POSTHOOK: Input: default@join_1to1_2
 30	10030	66	NULL	NULL	NULL
 35	10035	88	NULL	NULL	NULL
 40	10040	66	40	10040	66
-40	10040	66	NULL	NULL	NULL
 40	10040	88	NULL	NULL	NULL
 5	10005	66	5	10005	66
 50	10050	66	50	10050	66
@@ -575,12 +594,16 @@ POSTHOOK: Input: default@join_1to1_2
 NULL	10050	66	NULL	NULL	NULL
 NULL	NULL	66	NULL	NULL	NULL
 NULL	NULL	NULL	10	10010	66
+NULL	NULL	NULL	25	10025	66
 NULL	NULL	NULL	30	10030	88
 NULL	NULL	NULL	35	10035	88
+NULL	NULL	NULL	40	10040	66
 NULL	NULL	NULL	40	10040	88
 NULL	NULL	NULL	40	10040	88
 NULL	NULL	NULL	50	10050	66
 NULL	NULL	NULL	50	10050	66
+NULL	NULL	NULL	50	10050	66
+NULL	NULL	NULL	50	10050	66
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	50	10050	88
@@ -590,6 +613,8 @@ NULL	NULL	NULL	70	10040	88
 NULL	NULL	NULL	70	10040	88
 NULL	NULL	NULL	80	10040	66
 NULL	NULL	NULL	80	10040	66
+NULL	NULL	NULL	80	10040	66
+NULL	NULL	NULL	80	10040	66
 NULL	NULL	NULL	NULL	10050	66
 NULL	NULL	NULL	NULL	NULL	66
 PREHOOK: query: SELECT * FROM join_1to1_1 a full outer join join_1to1_2 b on a.key1 = b.key1 and a.key2 = b.key2
@@ -654,7 +679,6 @@ POSTHOOK: Input: default@join_1to1_2
 30	10030	66	NULL	NULL	NULL
 35	10035	88	NULL	NULL	NULL
 40	10040	66	40	10040	66
-40	10040	66	NULL	NULL	NULL
 40	10040	88	NULL	NULL	NULL
 5	10005	66	5	10005	66
 50	10050	66	50	10050	66
@@ -671,12 +695,16 @@ POSTHOOK: Input: default@join_1to1_2
 NULL	10050	66	NULL	NULL	NULL
 NULL	NULL	66	NULL	NULL	NULL
 NULL	NULL	NULL	10	10010	66
+NULL	NULL	NULL	25	10025	66
 NULL	NULL	NULL	30	10030	88
 NULL	NULL	NULL	35	10035	88
+NULL	NULL	NULL	40	10040	66
 NULL	NULL	NULL	40	10040	88
 NULL	NULL	NULL	40	10040	88
 NULL	NULL	NULL	50	10050	66
 NULL	NULL	NULL	50	10050	66
+NULL	NULL	NULL	50	10050	66
+NULL	NULL	NULL	50	10050	66
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	50	10050	88
@@ -686,6 +714,8 @@ NULL	NULL	NULL	70	10040	88
 NULL	NULL	NULL	70	10040	88
 NULL	NULL	NULL	80	10040	66
 NULL	NULL	NULL	80	10040	66
+NULL	NULL	NULL	80	10040	66
+NULL	NULL	NULL	80	10040	66
 NULL	NULL	NULL	NULL	10050	66
 NULL	NULL	NULL	NULL	NULL	66
 PREHOOK: query: SELECT * FROM join_1to1_1 a join join_1to1_2 b on a.key1 = b.key1
@@ -790,7 +820,6 @@ POSTHOOK: Input: default@join_1to1_2
 30	10030	66	NULL	NULL	NULL
 35	10035	88	NULL	NULL	NULL
 40	10040	66	40	10040	66
-40	10040	66	NULL	NULL	NULL
 40	10040	88	NULL	NULL	NULL
 5	10005	66	5	10005	66
 50	10050	66	50	10050	66
@@ -801,17 +830,22 @@ POSTHOOK: Input: default@join_1to1_2
 60	10040	66	60	10040	66
 60	10040	66	60	10040	66
 60	10040	66	60	10040	66
+70	10040	66	NULL	NULL	NULL
+70	10040	66	NULL	NULL	NULL
 80	10040	88	NULL	NULL	NULL
 80	10040	88	NULL	NULL	NULL
 NULL	10050	66	NULL	NULL	NULL
 NULL	NULL	66	NULL	NULL	NULL
 NULL	NULL	NULL	10	10010	66
+NULL	NULL	NULL	25	10025	66
 NULL	NULL	NULL	30	10030	88
 NULL	NULL	NULL	35	10035	88
 NULL	NULL	NULL	40	10040	88
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	70	10040	88
 NULL	NULL	NULL	70	10040	88
+NULL	NULL	NULL	80	10040	66
+NULL	NULL	NULL	80	10040	66
 NULL	NULL	NULL	NULL	10050	66
 NULL	NULL	NULL	NULL	NULL	66
 PREHOOK: query: SELECT * FROM join_1to1_1 a full outer join join_1to1_2 b on a.key1 = b.key1 and a.key2 = b.key2
@@ -876,7 +910,6 @@ POSTHOOK: Input: default@join_1to1_2
 30	10030	66	NULL	NULL	NULL
 35	10035	88	NULL	NULL	NULL
 40	10040	66	40	10040	66
-40	10040	66	NULL	NULL	NULL
 40	10040	88	NULL	NULL	NULL
 5	10005	66	5	10005	66
 50	10050	66	50	10050	66
@@ -887,17 +920,22 @@ POSTHOOK: Input: default@join_1to1_2
 60	10040	66	60	10040	66
 60	10040	66	60	10040	66
 60	10040	66	60	10040	66
+70	10040	66	NULL	NULL	NULL
+70	10040	66	NULL	NULL	NULL
 80	10040	88	NULL	NULL	NULL
 80	10040	88	NULL	NULL	NULL
 NULL	10050	66	NULL	NULL	NULL
 NULL	NULL	66	NULL	NULL	NULL
 NULL	NULL	NULL	10	10010	66
+NULL	NULL	NULL	25	10025	66
 NULL	NULL	NULL	30	10030	88
 NULL	NULL	NULL	35	10035	88
 NULL	NULL	NULL	40	10040	88
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	70	10040	88
 NULL	NULL	NULL	70	10040	88
+NULL	NULL	NULL	80	10040	66
+NULL	NULL	NULL	80	10040	66
 NULL	NULL	NULL	NULL	10050	66
 NULL	NULL	NULL	NULL	NULL	66
 PREHOOK: query: SELECT * FROM join_1to1_1 a join join_1to1_2 b on a.key1 = b.key1
@@ -1002,7 +1040,6 @@ POSTHOOK: Input: default@join_1to1_2
 30	10030	66	NULL	NULL	NULL
 35	10035	88	NULL	NULL	NULL
 40	10040	66	40	10040	66
-40	10040	66	NULL	NULL	NULL
 40	10040	88	NULL	NULL	NULL
 5	10005	66	5	10005	66
 50	10050	66	50	10050	66
@@ -1013,18 +1050,25 @@ POSTHOOK: Input: default@join_1to1_2
 60	10040	66	60	10040	66
 60	10040	66	60	10040	66
 60	10040	66	60	10040	66
+70	10040	66	NULL	NULL	NULL
+70	10040	66	NULL	NULL	NULL
 80	10040	88	NULL	NULL	NULL
 80	10040	88	NULL	NULL	NULL
 NULL	10050	66	NULL	NULL	NULL
 NULL	NULL	66	NULL	NULL	NULL
 NULL	NULL	NULL	10	10010	66
+NULL	NULL	NULL	25	10025	66
 NULL	NULL	NULL	30	10030	88
 NULL	NULL	NULL	35	10035	88
 NULL	NULL	NULL	40	10040	88
+NULL	NULL	NULL	50	10050	66
+NULL	NULL	NULL	50	10050	66
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	70	10040	88
 NULL	NULL	NULL	70	10040	88
+NULL	NULL	NULL	80	10040	66
+NULL	NULL	NULL	80	10040	66
 NULL	NULL	NULL	NULL	10050	66
 NULL	NULL	NULL	NULL	NULL	66
 PREHOOK: query: SELECT * FROM join_1to1_1 a full outer join join_1to1_2 b on a.key1 = b.key1 and a.key2 = b.key2
@@ -1089,7 +1133,6 @@ POSTHOOK: Input: default@join_1to1_2
 30	10030	66	NULL	NULL	NULL
 35	10035	88	NULL	NULL	NULL
 40	10040	66	40	10040	66
-40	10040	66	NULL	NULL	NULL
 40	10040	88	NULL	NULL	NULL
 5	10005	66	5	10005	66
 50	10050	66	50	10050	66
@@ -1100,18 +1143,25 @@ POSTHOOK: Input: default@join_1to1_2
 60	10040	66	60	10040	66
 60	10040	66	60	10040	66
 60	10040	66	60	10040	66
+70	10040	66	NULL	NULL	NULL
+70	10040	66	NULL	NULL	NULL
 80	10040	88	NULL	NULL	NULL
 80	10040	88	NULL	NULL	NULL
 NULL	10050	66	NULL	NULL	NULL
 NULL	NULL	66	NULL	NULL	NULL
 NULL	NULL	NULL	10	10010	66
+NULL	NULL	NULL	25	10025	66
 NULL	NULL	NULL	30	10030	88
 NULL	NULL	NULL	35	10035	88
 NULL	NULL	NULL	40	10040	88
+NULL	NULL	NULL	50	10050	66
+NULL	NULL	NULL	50	10050	66
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	70	10040	88
 NULL	NULL	NULL	70	10040	88
+NULL	NULL	NULL	80	10040	66
+NULL	NULL	NULL	80	10040	66
 NULL	NULL	NULL	NULL	10050	66
 NULL	NULL	NULL	NULL	NULL	66
 PREHOOK: query: SELECT * FROM join_1to1_1 a join join_1to1_2 b on a.key1 = b.key1
@@ -1216,7 +1266,6 @@ POSTHOOK: Input: default@join_1to1_2
 30	10030	66	NULL	NULL	NULL
 35	10035	88	NULL	NULL	NULL
 40	10040	66	40	10040	66
-40	10040	66	NULL	NULL	NULL
 40	10040	88	NULL	NULL	NULL
 5	10005	66	5	10005	66
 50	10050	66	50	10050	66
@@ -1233,12 +1282,16 @@ POSTHOOK: Input: default@join_1to1_2
 NULL	10050	66	NULL	NULL	NULL
 NULL	NULL	66	NULL	NULL	NULL
 NULL	NULL	NULL	10	10010	66
+NULL	NULL	NULL	25	10025	66
 NULL	NULL	NULL	30	10030	88
 NULL	NULL	NULL	35	10035	88
+NULL	NULL	NULL	40	10040	66
 NULL	NULL	NULL	40	10040	88
 NULL	NULL	NULL	40	10040	88
 NULL	NULL	NULL	50	10050	66
 NULL	NULL	NULL	50	10050	66
+NULL	NULL	NULL	50	10050	66
+NULL	NULL	NULL	50	10050	66
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	50	10050	88
@@ -1248,6 +1301,8 @@ NULL	NULL	NULL	70	10040	88
 NULL	NULL	NULL	70	10040	88
 NULL	NULL	NULL	80	10040	66
 NULL	NULL	NULL	80	10040	66
+NULL	NULL	NULL	80	10040	66
+NULL	NULL	NULL	80	10040	66
 NULL	NULL	NULL	NULL	10050	66
 NULL	NULL	NULL	NULL	NULL	66
 PREHOOK: query: SELECT * FROM join_1to1_1 a full outer join join_1to1_2 b on a.key1 = b.key1 and a.key2 = b.key2
@@ -1312,7 +1367,6 @@ POSTHOOK: Input: default@join_1to1_2
 30	10030	66	NULL	NULL	NULL
 35	10035	88	NULL	NULL	NULL
 40	10040	66	40	10040	66
-40	10040	66	NULL	NULL	NULL
 40	10040	88	NULL	NULL	NULL
 5	10005	66	5	10005	66
 50	10050	66	50	10050	66
@@ -1329,12 +1383,16 @@ POSTHOOK: Input: default@join_1to1_2
 NULL	10050	66	NULL	NULL	NULL
 NULL	NULL	66	NULL	NULL	NULL
 NULL	NULL	NULL	10	10010	66
+NULL	NULL	NULL	25	10025	66
 NULL	NULL	NULL	30	10030	88
 NULL	NULL	NULL	35	10035	88
+NULL	NULL	NULL	40	10040	66
 NULL	NULL	NULL	40	10040	88
 NULL	NULL	NULL	40	10040	88
 NULL	NULL	NULL	50	10050	66
 NULL	NULL	NULL	50	10050	66
+NULL	NULL	NULL	50	10050	66
+NULL	NULL	NULL	50	10050	66
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	50	10050	88
 NULL	NULL	NULL	50	10050	88
@@ -1344,5 +1402,7 @@ NULL	NULL	NULL	70	10040	88
 NULL	NULL	NULL	70	10040	88
 NULL	NULL	NULL	80	10040	66
 NULL	NULL	NULL	80	10040	66
+NULL	NULL	NULL	80	10040	66
+NULL	NULL	NULL	80	10040	66
 NULL	NULL	NULL	NULL	10050	66
 NULL	NULL	NULL	NULL	NULL	66
diff --git a/ql/src/test/results/clientpositive/llap/vector_full_outer_join2.q.out b/ql/src/test/results/clientpositive/llap/vector_full_outer_join2.q.out
new file mode 100644
index 0000000..b764fe5
--- /dev/null
+++ b/ql/src/test/results/clientpositive/llap/vector_full_outer_join2.q.out
@@ -0,0 +1,113 @@
+PREHOOK: query: create table t_letters (z char(12), x int, y int)
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@t_letters
+POSTHOOK: query: create table t_letters (z char(12), x int, y int)
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@t_letters
+PREHOOK: query: insert into t_letters values
+('one', 1, 50),
+('two', 2, 30),
+('three', 3, 30),
+('four', 4, 60),
+('five', 5, 70),
+('six', 6, 80)
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+PREHOOK: Output: default@t_letters
+POSTHOOK: query: insert into t_letters values
+('one', 1, 50),
+('two', 2, 30),
+('three', 3, 30),
+('four', 4, 60),
+('five', 5, 70),
+('six', 6, 80)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+POSTHOOK: Output: default@t_letters
+POSTHOOK: Lineage: t_letters.x SCRIPT []
+POSTHOOK: Lineage: t_letters.y SCRIPT []
+POSTHOOK: Lineage: t_letters.z SCRIPT []
+PREHOOK: query: create table t_roman (z char(12), x int, y int)
+PREHOOK: type: CREATETABLE
+PREHOOK: Output: database:default
+PREHOOK: Output: default@t_roman
+POSTHOOK: query: create table t_roman (z char(12), x int, y int)
+POSTHOOK: type: CREATETABLE
+POSTHOOK: Output: database:default
+POSTHOOK: Output: default@t_roman
+PREHOOK: query: insert into t_roman values
+('I', 1, 50),
+('II', 2, 30),
+('III', 3, 30),
+('IV', 4, 60),
+('V', 5, 70),
+('VI', 6, 80)
+PREHOOK: type: QUERY
+PREHOOK: Input: _dummy_database@_dummy_table
+PREHOOK: Output: default@t_roman
+POSTHOOK: query: insert into t_roman values
+('I', 1, 50),
+('II', 2, 30),
+('III', 3, 30),
+('IV', 4, 60),
+('V', 5, 70),
+('VI', 6, 80)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: _dummy_database@_dummy_table
+POSTHOOK: Output: default@t_roman
+POSTHOOK: Lineage: t_roman.x SCRIPT []
+POSTHOOK: Lineage: t_roman.y SCRIPT []
+POSTHOOK: Lineage: t_roman.z SCRIPT []
+PREHOOK: query: select x1.`z`, x1.`x`, x1.`y`,
+       x2.`z`, x2.`x`, x2.`y`
+from t_letters x1 full outer join t_roman x2 on (x1.`x` > 3) and (x2.`x` < 4) and (x1.`x` = x2.`x`)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@t_letters
+PREHOOK: Input: default@t_roman
+#### A masked pattern was here ####
+POSTHOOK: query: select x1.`z`, x1.`x`, x1.`y`,
+       x2.`z`, x2.`x`, x2.`y`
+from t_letters x1 full outer join t_roman x2 on (x1.`x` > 3) and (x2.`x` < 4) and (x1.`x` = x2.`x`)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@t_letters
+POSTHOOK: Input: default@t_roman
+#### A masked pattern was here ####
+one         	1	50	NULL	NULL	NULL
+NULL	NULL	NULL	I           	1	50
+two         	2	30	NULL	NULL	NULL
+NULL	NULL	NULL	II          	2	30
+three       	3	30	NULL	NULL	NULL
+NULL	NULL	NULL	III         	3	30
+four        	4	60	NULL	NULL	NULL
+NULL	NULL	NULL	IV          	4	60
+five        	5	70	NULL	NULL	NULL
+NULL	NULL	NULL	V           	5	70
+six         	6	80	NULL	NULL	NULL
+NULL	NULL	NULL	VI          	6	80
+PREHOOK: query: select x1.`z`, x1.`x`, x1.`y`,
+       x2.`z`, x2.`x`, x2.`y`
+from t_letters x1 full outer join t_roman x2 on (x1.`x` > 2) and (x2.`x` < 4) and (x1.`x` = x2.`x`)
+PREHOOK: type: QUERY
+PREHOOK: Input: default@t_letters
+PREHOOK: Input: default@t_roman
+#### A masked pattern was here ####
+POSTHOOK: query: select x1.`z`, x1.`x`, x1.`y`,
+       x2.`z`, x2.`x`, x2.`y`
+from t_letters x1 full outer join t_roman x2 on (x1.`x` > 2) and (x2.`x` < 4) and (x1.`x` = x2.`x`)
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@t_letters
+POSTHOOK: Input: default@t_roman
+#### A masked pattern was here ####
+one         	1	50	NULL	NULL	NULL
+NULL	NULL	NULL	I           	1	50
+two         	2	30	NULL	NULL	NULL
+NULL	NULL	NULL	II          	2	30
+three       	3	30	III         	3	30
+four        	4	60	NULL	NULL	NULL
+NULL	NULL	NULL	IV          	4	60
+five        	5	70	NULL	NULL	NULL
+NULL	NULL	NULL	V           	5	70
+six         	6	80	NULL	NULL	NULL
+NULL	NULL	NULL	VI          	6	80