PIG-5201: Null handling on FLATTEN (knoguchi)


git-svn-id: https://svn.apache.org/repos/asf/pig/trunk@1817591 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/CHANGES.txt b/CHANGES.txt
index fd01d2d..e3d869a 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -60,6 +60,8 @@
  
 BUG FIXES
 
+PIG-5201: Null handling on FLATTEN (knoguchi)
+
 PIG-5315: pig.script is not set for scripts run via PigServer (satishsaley via rohini)
 
 PIG-5310: MergeJoin throwing NullPointer Exception (satishsaley via rohini)
diff --git a/src/docs/src/documentation/content/xdocs/basic.xml b/src/docs/src/documentation/content/xdocs/basic.xml
index 9892ff5..9f14164 100644
--- a/src/docs/src/documentation/content/xdocs/basic.xml
+++ b/src/docs/src/documentation/content/xdocs/basic.xml
@@ -1225,6 +1225,20 @@
 (joe,18,2.5,joe,18,2.5)
 </source>
    </section>
+   <section id="nulls_flatten">
+   <title>Nulls and FLATTEN Operator</title>
+   <p>The FLATTEN operator handles null value differently based on its schema.</p>
+   <p>For null tuples, FLATTEN(null) produces multiples nulls based on the number of elements in the schema for that field.
+   If tuple has no schema, FLATTEN(null) simply returns a single null. </p>
+   <p>For null bags, we would have liked to discard the row just like we do with flatten of an empty bag.
+   However, it was too late by the time we noticed this inconsistency.
+   In order to preserve the backward compatibility, FLATTEN(null) for bag produces multiples nulls
+   based on the number of elements defined for the schema of this bag.
+   If no schema, a single null is returned. </p>
+   <p>For bags containing some null tuples, it follows the same rule as flatten of null tuples described above. </p>
+   <p>For null maps, FLATTEN(null) produces 2 nulls to represent the key and the value.</p>
+   <p>For null with other types, FLATTEN(null) simply returns a single null.</p>
+   </section>
    
    </section>
   
@@ -5453,8 +5467,11 @@
       we will see (a,k1,1), (a,k2,2) and (a,k3,3) as the result.
    </p>
 
+   <p>For other types, flatten becomes a no-op and simply returns the passed value. </p>
+
    <p>Also note that the flatten of empty bag will result in that row being discarded; no output is generated. 
    (See also <a href="perf.html#nulls">Drop Nulls Before a Join</a>.) </p>
+   <p>As for flatten with null values, see <a href="#nulls_flatten">Nulls and FLATTEN operator</a>.</p>
    
    <source>
 grunt> cat empty.bag
diff --git a/src/org/apache/pig/backend/hadoop/executionengine/physicalLayer/relationalOperators/POForEach.java b/src/org/apache/pig/backend/hadoop/executionengine/physicalLayer/relationalOperators/POForEach.java
index aba5131..e9fa5a6 100644
--- a/src/org/apache/pig/backend/hadoop/executionengine/physicalLayer/relationalOperators/POForEach.java
+++ b/src/org/apache/pig/backend/hadoop/executionengine/physicalLayer/relationalOperators/POForEach.java
@@ -74,6 +74,8 @@
     // so we can also save on the Boolean.booleanValue() calls
     protected boolean[] isToBeFlattenedArray;
 
+    private int[] flattenNumFields = null;
+
     protected int noItems;
 
     //Since the plan has a generate, this needs to be maintained
@@ -446,6 +448,8 @@
                 } else if (inputData.result instanceof Map && isToBeFlattenedArray[i]) {
                     its[i] = ((Map)bags[i]).entrySet().iterator();
                 } else {
+                    // This includes FLATTEN(null) for bag and map
+                    // in addition to non-null values from other data types
                     its[i] = null;
                 }
             }
@@ -490,7 +494,6 @@
                 if(getReporter()!=null) {
                     getReporter().progress();
                 }
-                //createTuple(data);
                 res.result = createTuple(data);
                 res.returnStatus = POStatus.STATUS_OK;
                 return res;
@@ -538,17 +541,23 @@
         for(int i = 0; i < data.length; ++i) {
             Object in = data[i];
 
-            if(isToBeFlattenedArray[i] && in instanceof Tuple) {
+            if(!isToBeFlattenedArray[i]) {
+                if (knownSize) {
+                    out.set(idx++, in);
+                } else {
+                    out.append(in);
+                }
+            } else if(in instanceof Tuple) {
                 Tuple t = (Tuple)in;
                 int size = t.size();
                 for(int j = 0; j < size; ++j) {
                     if (knownSize) {
                         out.set(idx++, t.get(j));
                     } else {
-                    out.append(t.get(j));
+                        out.append(t.get(j));
+                    }
                 }
-                }
-            } else if (isToBeFlattenedArray[i] && in instanceof Map.Entry) {
+            } else if (in instanceof Map.Entry) {
                 Map.Entry entry = (Map.Entry)in;
                 if (knownSize) {
                     out.set(idx++, entry.getKey());
@@ -557,14 +566,25 @@
                     out.append(entry.getKey());
                     out.append(entry.getValue());
                 }
+            } else if (in == null &&
+                       flattenNumFields != null && flattenNumFields[i] != 0 ) {
+                // Handling of FLATTEN(null) here.
+                // Expanding to multiple nulls depending on the schema
+                for( int j = 0; j < flattenNumFields[i]; j++ ) {
+                    if (knownSize) {
+                        out.set(idx++, null);
+                    } else {
+                        out.append(null);
+                    }
+                }
             } else {
                 if (knownSize) {
                     out.set(idx++, in);
-            } else {
-                out.append(in);
+                } else {
+                    out.append(in);
+                }
             }
         }
-        }
         if (inpTuple != null) {
             return illustratorMarkup(inpTuple, out, 0);
         } else {
@@ -706,6 +726,7 @@
         clone.addOriginalLocation(alias, getOriginalLocations());
         clone.endOfAllInputProcessing = endOfAllInputProcessing;
         clone.mapSideOnly = mapSideOnly;
+        clone.flattenNumFields = flattenNumFields;
         return clone;
     }
 
@@ -714,6 +735,10 @@
         return processingPlan;
     }
 
+    public void setFlattenNumFields (int [] flattenNumFields) {
+        this.flattenNumFields = flattenNumFields;
+    }
+
     protected void setUpFlattens(List<Boolean> isToBeFlattened) {
         if(isToBeFlattened == null) {
             isToBeFlattenedArray = null;
diff --git a/src/org/apache/pig/impl/util/TupleFormat.java b/src/org/apache/pig/impl/util/TupleFormat.java
index ad76b52..1a00663 100644
--- a/src/org/apache/pig/impl/util/TupleFormat.java
+++ b/src/org/apache/pig/impl/util/TupleFormat.java
@@ -47,32 +47,34 @@
     public static String format(Tuple tuple) {
         StringBuilder sb = new StringBuilder();
         sb.append('(');
-        for (int i = 0; i < tuple.size(); ++i) {
-            try {
-                Object d = tuple.get(i);
-                if (d != null) {
-                    if (d instanceof Map) {
-                        sb.append(DataType.mapToString((Map<String, Object>) d));
-                    } else if (d instanceof Tuple) {
-                        Tuple t = (Tuple) d;
-                        sb.append(TupleFormat.format(t));
-                    } else if (d instanceof DataBag){
-                        DataBag bag=(DataBag)d;
-                        sb.append(BagFormat.format(bag));
+        if( tuple != null ) {
+            for (int i = 0; i < tuple.size(); ++i) {
+                try {
+                    Object d = tuple.get(i);
+                    if (d != null) {
+                        if (d instanceof Map) {
+                            sb.append(DataType.mapToString((Map<String, Object>) d));
+                        } else if (d instanceof Tuple) {
+                            Tuple t = (Tuple) d;
+                            sb.append(TupleFormat.format(t));
+                        } else if (d instanceof DataBag){
+                            DataBag bag=(DataBag)d;
+                            sb.append(BagFormat.format(bag));
+                        }
+                        else {
+                            sb.append(d.toString());
+                        }
+                    } else {
+                        sb.append("");
                     }
-                    else {
-                        sb.append(d.toString());
-                    }
-                } else {
-                    sb.append("");
+                    if (i != tuple.size() - 1)
+                        sb.append(",");
+                } catch (ExecException e) {
+                    e.printStackTrace();
+                    mLog.warn("Exception when format tuple", e);
                 }
-                if (i != tuple.size() - 1)
-                    sb.append(",");
-            } catch (ExecException e) {
-                e.printStackTrace();
-                mLog.warn("Exception when format tuple", e);
-            }
 
+            }
         }
         sb.append(')');
         return sb.toString();
diff --git a/src/org/apache/pig/newplan/logical/relational/LOGenerate.java b/src/org/apache/pig/newplan/logical/relational/LOGenerate.java
index 2609c2d..13f5b38 100644
--- a/src/org/apache/pig/newplan/logical/relational/LOGenerate.java
+++ b/src/org/apache/pig/newplan/logical/relational/LOGenerate.java
@@ -33,6 +33,7 @@
 public class LOGenerate extends LogicalRelationalOperator {
      private List<LogicalExpressionPlan> outputPlans;
      private boolean[] flattenFlags;
+     private int[] flattenNumFields;
      // mUserDefinedSchema is the original input from the user, we don't suppose
      // to store uid in mUserDefinedSchema
      private List<LogicalSchema> mUserDefinedSchema = null;
@@ -74,7 +75,9 @@
         outputPlanSchemas = new ArrayList<LogicalSchema>();
         expSchemas = new ArrayList<LogicalSchema>();
         
+        flattenNumFields = new int[outputPlans.size()];
         for(int i=0; i<outputPlans.size(); i++) {
+            flattenNumFields[i] = 0;
             LogicalExpression exp = (LogicalExpression)outputPlans.get(i).getSources().get(0);
             
             LogicalSchema mUserDefinedSchemaCopy = null;
@@ -111,8 +114,10 @@
                             if (fieldSchema.type == DataType.BAG) {
                                 // if it is bag, get the schema of tuples
                                 if (fieldSchema.schema!=null) {
-                                    if (fieldSchema.schema.getField(0).schema!=null)
+                                    if (fieldSchema.schema.getField(0).schema!=null) {
                                         innerFieldSchemas = fieldSchema.schema.getField(0).schema.getFields();
+                                        flattenNumFields[i] = innerFieldSchemas.size();
+                                    }
                                     for (LogicalSchema.LogicalFieldSchema fs : innerFieldSchemas) {
                                         fs.alias = fs.alias == null ? null : fieldSchema.alias + "::" + fs.alias;
                                     }
@@ -120,6 +125,7 @@
                             } else if (fieldSchema.type == DataType.MAP) {
                                 //should only contain 1 schemafield for Map's value
                                 innerFieldSchemas = fieldSchema.schema.getFields();
+                                flattenNumFields[i] = 2;  // used for FLATTEN(null-map)
                                 LogicalSchema.LogicalFieldSchema fsForValue = innerFieldSchemas.get(0);
                                 fsForValue.alias = fieldSchema.alias + "::value";
 
@@ -129,6 +135,7 @@
                                 expSchema.addField(fsForKey);
                             } else { // DataType.TUPLE
                                 innerFieldSchemas = fieldSchema.schema.getFields();
+                                flattenNumFields[i] = innerFieldSchemas.size();
                                 for (LogicalSchema.LogicalFieldSchema fs : innerFieldSchemas) {
                                     fs.alias = fs.alias == null ? null : fieldSchema.alias + "::" + fs.alias;
                                 }
@@ -213,6 +220,10 @@
     public boolean[] getFlattenFlags() {
         return flattenFlags;
     }
+
+    public int [] getFlattenNumFields() {
+        return flattenNumFields;
+    }
     
     public void setFlattenFlags(boolean[] flatten) {
         flattenFlags = flatten;
diff --git a/src/org/apache/pig/newplan/logical/relational/LogToPhyTranslationVisitor.java b/src/org/apache/pig/newplan/logical/relational/LogToPhyTranslationVisitor.java
index 7faa1fd..7526d7d 100644
--- a/src/org/apache/pig/newplan/logical/relational/LogToPhyTranslationVisitor.java
+++ b/src/org/apache/pig/newplan/logical/relational/LogToPhyTranslationVisitor.java
@@ -877,6 +877,7 @@
         }
         POForEach poFE = new POForEach(new OperatorKey(scope, nodeGen
                 .getNextNodeId(scope)), foreach.getRequestedParallelism(), innerPlans, flattenList, schema);
+        poFE.setFlattenNumFields(gen.getFlattenNumFields());
         poFE.addOriginalLocation(foreach.getAlias(), foreach.getLocation());
         poFE.setResultType(DataType.BAG);
         logToPhyMap.put(foreach, poFE);
diff --git a/test/org/apache/pig/test/TestFlatten.java b/test/org/apache/pig/test/TestFlatten.java
index f315b84..c253afc 100644
--- a/test/org/apache/pig/test/TestFlatten.java
+++ b/test/org/apache/pig/test/TestFlatten.java
@@ -97,4 +97,270 @@
                 "('a', 'b', '1', '2')", "('a', 'b', '3', '4')", "('c', 'd', '1', '2')", "('c', 'd', '3', '4')" });
         Util.checkQueryOutputsAfterSort(actualResults.iterator(), expectedResults);
     }
+
+    @Test
+    public void testFlattenOnNullBag() throws Exception {
+        Storage.Data data = Storage.resetData(pig);
+        data.set("input",
+            Storage.tuple(
+                Storage.bag(
+                    Storage.tuple("a","b"),
+                    Storage.tuple("c","d")),
+                Storage.bag(
+                    Storage.tuple("1","2"),
+                    Storage.tuple("3","4"))
+            ),
+            Storage.tuple(
+                null,
+                Storage.bag(
+                    Storage.tuple("11","12"),
+                    Storage.tuple("13","14"))
+            ),
+            Storage.tuple(
+                Storage.bag(
+                    Storage.tuple("k","l"),
+                    Storage.tuple("m","n")),
+                null
+            ),
+            Storage.tuple(
+                Storage.bag(
+                    null,
+                    Storage.tuple("e","f")),
+                Storage.bag(
+                    Storage.tuple("5","6"),
+                    Storage.tuple("7","8"))
+            ),
+            Storage.tuple(
+                Storage.bag(
+                    Storage.tuple("g","h"),
+                    Storage.tuple("i","j")),
+                Storage.bag(
+                    Storage.tuple("9","10"),
+                    null
+                    )
+            )
+        );
+
+        pig.setBatchOn();
+        pig.registerQuery("A = load 'input' using mock.Storage() as (bag1:bag {(a1_1:int, a1_2:chararray)}, bag2:bag{(a2_1:chararray, a2_2:chararray)});");
+        pig.registerQuery("B = foreach A GENERATE FLATTEN(bag1), FLATTEN(bag2);");
+        pig.registerQuery("store B into 'output' using mock.Storage();");
+        List<ExecJob> execJobs = pig.executeBatch();
+        for( ExecJob execJob : execJobs ) {
+          assertTrue(execJob.getStatus() == ExecJob.JOB_STATUS.COMPLETED );
+        }
+        List<Tuple> actualResults = data.get("output");
+        List<Tuple> expectedResults = Util.getTuplesFromConstantTupleStrings(
+                new String[] {
+                "('a', 'b', '1', '2')", "('a', 'b', '3', '4')", "('c', 'd', '1', '2')", "('c', 'd', '3', '4')",
+
+                //flatten(null-bag) on schema {(a1_1:int, a1_2:chararray)} expands to (null, null)
+                "(null, null, '11', '12')", "(null, null, '13', '14')",
+                "('k', 'l', null, null)", "('m', 'n', null, null)",
+
+                //flatten(null-tuple-from-bag) on schema {(a1_1:int, a1_2:chararray)} also expands to (null, null)
+                "(null, null, '5', '6')", "(null, null, '7', '8')", "('e', 'f', '5', '6')", "('e', 'f', '7', '8')",
+                "('g', 'h', '9', '10')", "('g', 'h', null, null)", "('i', 'j', '9', '10')", "('i', 'j', null, null)" });
+
+        Util.checkQueryOutputs(actualResults.iterator(), expectedResults);
+    }
+
+    @Test
+    public void testFlattenOnNullMap() throws Exception {
+        Storage.Data data = Storage.resetData(pig);
+        data.set("input",
+            Storage.tuple(
+                Storage.map("a","b",
+                            "c","d"),
+                Storage.map("1","2",
+                            "3","4")
+            )
+            ,
+            Storage.tuple(
+                null,
+                Storage.map("11","12",
+                            "13","14")
+            ),
+            Storage.tuple(
+                Storage.map("k","l",
+                            "m","n"),
+                null
+            )
+        );
+        pig.setBatchOn();
+        pig.registerQuery("A = load 'input' using mock.Storage() as (map1:map [chararray], map2:map [chararray]);");
+        pig.registerQuery("B = foreach A GENERATE FLATTEN(map1), FLATTEN(map2);");
+        pig.registerQuery("store B into 'output' using mock.Storage();");
+        List<ExecJob> execJobs = pig.executeBatch();
+        for( ExecJob execJob : execJobs ) {
+          assertTrue(execJob.getStatus() == ExecJob.JOB_STATUS.COMPLETED );
+        }
+        List<Tuple> actualResults = data.get("output");
+        List<Tuple> expectedResults = Util.getTuplesFromConstantTupleStrings(
+                new String[] {
+                "('a', 'b', '1', '2')", "('a', 'b', '3', '4')", "('c', 'd', '1', '2')", "('c', 'd', '3', '4')",
+                // flatten(null-map) should expand to (null, null)
+                "(null, null, '11', '12')", "(null, null, '13', '14')", "('k', 'l', null, null)", "('m', 'n', null, null)"
+                });
+        Util.checkQueryOutputsAfterSort(actualResults.iterator(), expectedResults);
+    }
+
+    @Test
+    public void testFlattenOnNullTuple() throws Exception {
+        Storage.Data data = Storage.resetData(pig);
+        data.set("input",
+            Storage.tuple(
+                Storage.tuple("a","b"),
+                Storage.tuple("1","2")
+            ),
+            Storage.tuple(
+                null,
+                Storage.tuple("3","4")
+            ),
+            Storage.tuple(
+                Storage.tuple("c","d"),
+                null
+            ),
+            Storage.tuple(
+                Storage.tuple("e", null),
+                Storage.tuple(null,"5")
+            )
+        );
+        pig.setBatchOn();
+        pig.registerQuery("A = load 'input' using mock.Storage() as (tuple1:tuple (a1:chararray, a2:chararray), tuple2:tuple (a3:chararray, a4:chararray));");
+        pig.registerQuery("B = foreach A GENERATE FLATTEN(tuple1), FLATTEN(tuple2);");
+        pig.registerQuery("store B into 'output' using mock.Storage();");
+        List<ExecJob> execJobs = pig.executeBatch();
+        for( ExecJob execJob : execJobs ) {
+          assertTrue(execJob.getStatus() == ExecJob.JOB_STATUS.COMPLETED );
+        }
+        List<Tuple> actualResults = data.get("output");
+        List<Tuple> expectedResults = Util.getTuplesFromConstantTupleStrings(
+                new String[] {
+                "('a', 'b', '1', '2')", "(null, null, '3', '4')", "('c', 'd', null, null)", "('e', null, null, '5')" });
+
+        Util.checkQueryOutputs(actualResults.iterator(), expectedResults);
+    }
+
+    @Test
+    public void testFlattenOnNullWithNoSchema() throws Exception {
+        Storage.Data data = Storage.resetData(pig);
+        data.set("input",
+            Storage.tuple(
+                null,
+                Storage.bag(
+                    Storage.tuple("1","2"),
+                    Storage.tuple("3","4"))
+            ),
+
+            Storage.tuple(
+                Storage.bag(
+                    null,
+                    Storage.tuple("e","f")),
+                Storage.bag(
+                    Storage.tuple("5","6"),
+                    Storage.tuple("7","8"))
+            ),
+
+            Storage.tuple(
+                null,
+                Storage.map("9","10")
+            ),
+
+            Storage.tuple(
+                Storage.tuple("g","h"),
+                null
+            ),
+
+            Storage.tuple(
+                Storage.tuple("13", null),
+                Storage.tuple(null,"16")
+            )
+        );
+        pig.setBatchOn();
+        pig.registerQuery("A = load 'input' using mock.Storage() as (a1, a2);");
+        pig.registerQuery("B = foreach A GENERATE FLATTEN(a1), FLATTEN(a2);");
+        pig.registerQuery("store B into 'output' using mock.Storage();");
+        List<ExecJob> execJobs = pig.executeBatch();
+        for( ExecJob execJob : execJobs ) {
+          assertTrue(execJob.getStatus() == ExecJob.JOB_STATUS.COMPLETED );
+        }
+        List<Tuple> actualResults = data.get("output");
+        List<Tuple> expectedResults = Util.getTuplesFromConstantTupleStrings(
+                new String[] {
+                "(null, '1', '2')", "(null, '3', '4')",  //since no schema, flatten(null) ==> one null
+                "(null, '5', '6')", "(null, '7', '8')", "('e', 'f', '5', '6')", "('e', 'f', '7', '8')",
+                "(null, '9', '10')",
+                "('g', 'h', null)",
+                "('13', null, null, '16')"});
+
+        Util.checkQueryOutputs(actualResults.iterator(), expectedResults);
+    }
+
+    @Test
+    public void testFlattenOnNullBagWithColumnPrune() throws Exception {
+        Storage.Data data = Storage.resetData(pig);
+        data.set("input",
+            Storage.tuple(
+                1,
+                Storage.bag(
+                    Storage.tuple("a","b"),
+                    Storage.tuple("c","d")),
+                Storage.bag(
+                    Storage.tuple("1","2"),
+                    Storage.tuple("3","4"))
+            ),
+            Storage.tuple(
+                2,
+                null,
+                Storage.bag(
+                    Storage.tuple("11","12"),
+                    Storage.tuple("13","14"))
+            ),
+            Storage.tuple(
+                3,
+                Storage.bag(
+                    Storage.tuple("k","l"),
+                    Storage.tuple("m","n")),
+                null
+            ),
+            Storage.tuple(
+                4,
+                Storage.bag(
+                    null,
+                    Storage.tuple("e","f")),
+                Storage.bag(
+                    Storage.tuple("5","6"),
+                    Storage.tuple("7","8"))
+            ),
+            Storage.tuple(
+                5,
+                Storage.bag(
+                    Storage.tuple("g","h"),
+                    Storage.tuple("i","j")),
+                Storage.bag(
+                    Storage.tuple("9","10"),
+                    null
+                    )
+            )
+        );
+        pig.setBatchOn();
+        pig.registerQuery("A = load 'input' using mock.Storage() as (a0:int, bag1:bag {(a1_1:int, a1_2:chararray)}, bag2:bag{(a2_1:chararray, a2_2:chararray)});");
+        pig.registerQuery("B = foreach A GENERATE FLATTEN(bag1), FLATTEN(bag2);");
+        pig.registerQuery("store B into 'output' using mock.Storage();");
+        List<ExecJob> execJobs = pig.executeBatch();
+        for( ExecJob execJob : execJobs ) {
+          assertTrue(execJob.getStatus() == ExecJob.JOB_STATUS.COMPLETED );
+        }
+        List<Tuple> actualResults = data.get("output");
+        List<Tuple> expectedResults = Util.getTuplesFromConstantTupleStrings(
+                new String[] {
+                "('a', 'b', '1', '2')", "('a', 'b', '3', '4')", "('c', 'd', '1', '2')", "('c', 'd', '3', '4')",
+                "(null, null, '11', '12')", "(null, null, '13', '14')",
+                "('k', 'l', null, null)", "('m', 'n', null, null)",
+                "(null, null, '5', '6')", "(null, null, '7', '8')", "('e', 'f', '5', '6')", "('e', 'f', '7', '8')",
+                "('g', 'h', '9', '10')", "('g', 'h', null, null)", "('i', 'j', '9', '10')", "('i', 'j', null, null)" });
+
+        Util.checkQueryOutputs(actualResults.iterator(), expectedResults);
+    }
 }
diff --git a/test/org/apache/pig/test/TestLineageFindRelVisitor.java b/test/org/apache/pig/test/TestLineageFindRelVisitor.java
index cd54065..8e893f5 100644
--- a/test/org/apache/pig/test/TestLineageFindRelVisitor.java
+++ b/test/org/apache/pig/test/TestLineageFindRelVisitor.java
@@ -181,7 +181,7 @@
         pig.executeBatch();
 
         List<Tuple> actualResults = data.get("output");
-        List<Tuple> expectedResults = Util.getTuplesFromConstantTupleStrings(
+        List<Tuple> expectedResults = Util.getTuplesFromConstantTupleStringAsByteArray(
                 new String[] {"('aaa', 'bbb')"});
         Util.checkQueryOutputs(actualResults.iterator(), expectedResults);
     }
diff --git a/test/org/apache/pig/test/TestProjectRange.java b/test/org/apache/pig/test/TestProjectRange.java
index 660c411..515d5fa 100644
--- a/test/org/apache/pig/test/TestProjectRange.java
+++ b/test/org/apache/pig/test/TestProjectRange.java
@@ -554,8 +554,8 @@
         List<Tuple> expectedRes =
             Util.getTuplesFromConstantTupleStrings(
                     new String[] {
-                            "(10,20,30,40,50)",
-                            "(11,21,31,41,51)",
+                            "(10,20L,30,40,50)",
+                            "(11,21L,31,41,51)",
                     });
         Util.checkQueryOutputs(it, expectedRes);
     }
@@ -799,8 +799,8 @@
         List<Tuple> expectedRes =
             Util.getTuplesFromConstantTupleStrings(
                     new String[] {
-                            "(10,20,30,40,50)",
-                            "(11,21,31,41,51)",
+                            "(10,20L,30,40,50)",
+                            "(11,21L,31,41,51)",
                     });
         Util.checkQueryOutputs(it, expectedRes);
     }
@@ -828,10 +828,10 @@
         Iterator<Tuple> it = pigServer.openIterator("o");
 
         List<Tuple> expectedRes =
-            Util.getTuplesFromConstantTupleStrings(
+            Util.getTuplesFromConstantTupleStringAsByteArray(
                     new String[] {
-                            "(11,21,31,41,51)",
-                            "(10,20,30,40,50)",
+                            "('11','21','31','41','51')",
+                            "('10','20','30','40','50')",
                     });
         Util.checkQueryOutputs(it, expectedRes);
     }
@@ -858,10 +858,10 @@
         Iterator<Tuple> it = pigServer.openIterator("o");
 
         List<Tuple> expectedRes =
-            Util.getTuplesFromConstantTupleStrings(
+            Util.getTuplesFromConstantTupleStringAsByteArray(
                     new String[] {
-                            "(11,21,31,41,51)",
-                            "(10,20,30,40,50)",
+                            "('11','21','31','41','51')",
+                            "('10','20','30','40','50')",
                     });
         Util.checkQueryOutputs(it, expectedRes);
     }
diff --git a/test/org/apache/pig/test/TestTuple.java b/test/org/apache/pig/test/TestTuple.java
index 9dc32b4..680bdbf 100644
--- a/test/org/apache/pig/test/TestTuple.java
+++ b/test/org/apache/pig/test/TestTuple.java
@@ -70,6 +70,9 @@
             assertEquals(
                     "(12,[pig#scalability],,12,1.2,(innerTuple),{(innerTuple)})",
                     TupleFormat.format(tuple));
+
+            //check if TupleFormat can handle null tuple
+            assertEquals("()", TupleFormat.format(null));
         } catch (ExecException e) {
             e.printStackTrace();
             fail();
diff --git a/test/org/apache/pig/test/Util.java b/test/org/apache/pig/test/Util.java
index 8d4282d..d1c711b 100644
--- a/test/org/apache/pig/test/Util.java
+++ b/test/org/apache/pig/test/Util.java
@@ -535,16 +535,10 @@
      * @param actualResults Result of the executed Pig query
      * @param expectedResults Expected results List to validate against
      */
-     static public void checkQueryOutputs(Iterator<Tuple> actualResults,
+      static public void checkQueryOutputs(Iterator<Tuple> actualResults,
                                      List<Tuple> expectedResults) {
-         int count = 0;
-         for (Tuple expected : expectedResults) {
-             Tuple actual = actualResults.next();
-             count++;
-             Assert.assertEquals(expected.toString(), actual.toString());
-         }
-         Assert.assertEquals(expectedResults.size(), count);
-     }
+          checkQueryOutputs(actualResults, expectedResults.iterator(), null );
+      }
 
      /**
       * Helper function to check if the result of a Pig Query is in line with
@@ -560,7 +554,15 @@
               Tuple expected = expectedResults.next();
               Assert.assertTrue("Actual result has less records than expected results", actualResults.hasNext());
               Tuple actual = actualResults.next();
-              Assert.assertEquals(expected.toString(), actual.toString());
+
+              // If this tuple contains any bags, bags will be sorted before comparisons
+              if( !expected.equals(actual) ) {
+                  // Using string comparisons since error message is more readable
+                  // (only showing the part which differs)
+                  Assert.assertEquals(expected.toString(), actual.toString());
+                  // if above goes through, simply failing with object comparisons
+                  Assert.assertEquals(expected, actual);
+              }
               count++;
           }
           Assert.assertFalse("Actual result has more records than expected results", actualResults.hasNext());
@@ -613,9 +615,7 @@
          Collections.sort(actualResList);
          Collections.sort(expectedResList);
 
-         Assert.assertEquals("Comparing actual and expected results. ",
-                 expectedResList, actualResList);
-
+         checkQueryOutputs(actualResList.iterator(), expectedResList);
     }
 
     /**
diff --git a/test/org/apache/pig/test/data/GoldenFiles/tez/TEZC-MergeCogroup-1.gld b/test/org/apache/pig/test/data/GoldenFiles/tez/TEZC-MergeCogroup-1.gld
index 15d9716..9018a24 100644
--- a/test/org/apache/pig/test/data/GoldenFiles/tez/TEZC-MergeCogroup-1.gld
+++ b/test/org/apache/pig/test/data/GoldenFiles/tez/TEZC-MergeCogroup-1.gld
@@ -14,7 +14,7 @@
 |   |
 |   Project[tuple][*] - scope-33
 |
-|---a: Load(file:///tmp/input1:org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.MergeJoinIndexer('org.apache.pig.test.TestMapSideCogroup$DummyCollectableLoader','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','a_1-0','scope','false')) - scope-31
+|---a: Load(file:///tmp/input1:org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.MergeJoinIndexer('org.apache.pig.test.TestMapSideCogroup$DummyCollectableLoader','eNqtVb9v00AUfk2aNoRSWqAsVQfEr81ekTpAC60IuE1Eu5CJV/vqGM6+6/lcHAakLjCwwsCAxMDYfwIxMMPIhNiZGeHdOWncFIRE8WD53rt7P7573+f971BLFZx9iLvoZDrizpJS2POiVOd7nxdef8Q3VRhrwngaPWG5BICxx+PmTYfWhQodlOh3mSOj0NlC/xFLAqeLgRDSYTnzKaJIWBJGCW3p9tLIR+5hjylHckxSp923tWkFxTNWgUoHTlGg1vYS581EZtqDmpAxSg0XPUrqFkldSupGseSuKdxdy7iO1lAu5gouj5RmdtmUTksyhVqowxnrHjTiVSXilSBk6Q48hSrljO+yXqrhtGfQ6Seh+B5Mxh7DXUa+mZLPgEbO8bglbYiaBxPxPSG0XU14MB1viG09mmbKWjdF2VaPy+tcEtoXfteSvbFB4/12KhUYM1WQxVZhT88OL/g2pl3y1Sa/vP9w/sGnKlRWocEFBqvoEzBNOKG7iqVdwYNcXr9RBH1cp9eM+cptTY2+Y+rAYSbi0l9hJ0RL93wHKlFAQKe+kEzDmQJM2h+6G1pFSbiYD7qa1f1tlOb+cQaPppi6S8k9qInGsNVW4iHz9bC2iQ5MR2nfTJeRBB1oiF2mDFKMFnNSCd8ESsJlDFvbm5nkLO3AOYpOF7JBds6skdxNqKcalb4pOE2PL3gWJzQ9c6XpOeCdmd+t/93hyhHbsFWghN5xEg5YfDT0VAdq6PtZTIyODJOXtDY5gqbBaScjCrGgjQo5ZzxK42VoFPBt9iSjwUAeoZ23aVrYABrmRyUgQI2uRZrYN2F3DRh3ilO1GLJNhT5TGq6OnpUsGZC3tJHizAoVUavUovDRdD4IOSkyXcrQkKhYoo2caGiPhu/D6BYwuiMwuodgdK0kumVJpDqqysjMrWMFvmchNXN14a8EHd6dFRHiq4YrvxVdc8wt8Zq4ajA5DfCTnoakx4JU6Me41Q5ptGj5OLNW9FLSkGWYUkxnKtnQqLOUJqCYoMNy0toyPKYSKwNBgYPihn+0QiXNAaeZaBYydebb23c/9p5fq5ifYG0XecYIxpnhvvUs3mLq2f6rhZMvv74wZLIJ8nw0vFnO/1E8rdfClx8BzRrqh04e0eN/doPMfwFKyneZ','eNq9fWtsHFeWXvEhWm9LsmVZkiVRFi1LMqu6my9R1mptiiItOnwtyfHMSJlwi13V7DLr5apqsinHizgGZhcYbAZBsoCzkwDjRbLAAvNjMfmzSBBggw2Q/MgCmwADBEEQLBbJnwDJnwTI5oXNOefeW3Wr6laTtI31jOnu6lv3ec53nvfen/1X7VgcactBtG2Yodls20bobBtbZnPH9i2jbVpBEBp21252EifwbX/b8aFIez92mqa7aO7bkRG6ph8bq/zZKnzT2D99/Vr/M+0MVLTSmnHdBT/sJIvasSD0zDDRbi1CozXWaA0arTle6NagGbe21HETZ8kMH3Yj7a1C17AUNWmshHZkJkGUb/H4onbSm48Cb87atuNPtF/T+qBN76/Y+3Givbz4sblr8kag/kXtJW/RNndt+O2c9NuiEyfw46C3ElIVA4vakLcWBAl9G1zUznrrQSspNnOanm4E8rPjnvy9G8Js31QNCds1xMD5cPr7sYZBD55QL+jt89hNVvypGbfht2Mv/ft//kev/eq/GdD657WTbmBa82YTJmZBO5G0IztuB67VDd97n+o8vXcc/p7Dj13q0/HSD33QysiB0w4zKq3zh1q/Y8FEx80gtBPtAptMKL9dW08ix99+2BWjup7wYtDM978J4UW2a+KPpiv6BGS4Mh9Ec1Bf1rczz7TzTjxnRu7+hh15jm8mtvVMO7HjB3v+uvPCfqadAopcdyx7xXf3F7SX/GAhsb14UbuUo93VKGjacQyDSbRXpAE+DgLXNv2Hz7VzLehRYvvLHW/esV0LyKr/+QJQpEPvI6MQAT3XXnXijeCxPc/K29ZMFJn7WPoZkFEQ0o9rdmwnvPwpnHsg1RZQZKKtPC8yD5+4Gpu4WmHiarmJqwleFdMGPT8FdALEt7Ef2tTpx0DxMVTumYlWV3KqG2xnNbKitXX6D3DOyaQTuvaSuWNHiTZcfN8yE7O2kZZANl/8JoRQHE+29qefacfMZrPjAQ7RGswkCbZhLWivRvYnHRisba2akem6tuvE3mPtZDYRQM6m65i0ZKfhC1WQaFerhwMjH6JSAifOuNBbc9veiMwmTsXbxXdD2xeQIxWEes4HkQNDhSEGTaJyUeVLQSeRWjgZmpHtE20l2uo3IgsC8poM5NCPgQgJ4sk3qniNphSX+eaBsJKtHUEfoEyi3VYSIL5Wk9AIEAbn5Iym/QX80020PhPx8pUML4nJENu7n//ba3/vX5r/YEDrW9AGY8AAQqe+vUEOfx99+7i0CLicDW4IAAggwAvx8YfaMdfxnASeAcd/J3wCFQO9ufOOC1h6Uzl6J6jhz+uh3YRV6g+bCj6jgqvO9mzgJ3YXJdqJ2NkG/OsA7SNRd/HvJSKlU7xvl/HLWT6H+PlGGDIhOJyboR98mww7slIg9pm/9cfL5//d//uyXxuABUImWtCGglYLpifHlWzZ4N9B6mo3xBV//E26xmhVkmyPtdORDTPmrycwcSAUhhhC5IXcytbHdhNIPOwPaerwHw36ckNF8E5giLXLJH0/6AoteLpsejZHnOOtjt/EUol2ubi28/wnaBJ6gi++W6vVEi+sEQA1oO1LhbbFK1mboNecaLpmHKeNPteOo+owE20D17/yvCzGF7WXGZBCCQb3+N5F7MWjQnsJIIexAX+WmHSdDbajoBOOPOl43v5sAJDbTMwt10YWsCNauuuq6cooOFuWcwvay5bdMmEhBHw/0047PtQdsm4hg/lzXUAJxyf0X3DdTpwQvS1qF4iGbGu9GTlhgqshFD1R7WKwvWjv2kALr8tzD2Jv4uMa/fKQFQYasmYDzzN9S9Rxjj/GGU+xG54fR9pD0aJY0Dn+E0pPWJJkU5Y9L1OzoIAAwyQOIvJrkrqaPX/IBILppSMCETFETzKBkZbGJ9OL2qk4PwlQ6Fy844QhTE/bCVfNpM2ed0Mi6z4k7EsZrILo2rEtroxO/OHyXz3n/uH/AfwGvQpkL2hMKxGsb1dWNjVJC8XaXpPWnYZq0AzX45du3Oj/F1MDUCzcA1RaRhAa0gYXludX8uqrVqXX5n44Mjgk9gsg4ReIS65YoYwKNRBpj75Whaq6gIUGGvo4dPLVbHKztX1w4U9ehFO//CVJxuOcStkadnNiDleCGOuVf/ryWzc//E9/cCjD4DjNE4mBroD8J+y3/vfwt/6/gH9HEu3svhn5Rst0XL0FdArafMt0AZi1a6BFR7bVadrGx8GW0dmCfpvxjmH72BmsbyHRavQ2NB50oiawqQ9KT2R4ZldvBsDsNuhjuhmGrsO1Hqi+UYd/Eu0iwObWPoCKARNiwHQ3d+KOB3M22RhLtBllvRaI4n3bwv/a21ShngSwPFDQC3ZNV3cAVyL84GFL46ylX6K6EsezUfLoMZRwYFAukqS1pWc/wFzaUJVp6U1cfx01iUQ70ahPTE/en8KqLrdiIx43jWbg+zZhAdUboCJ5bJI1dyebt6brgDJnxJ0tUAcMRHWoPp0MUMwbUH6Sk1YMlBU5yb6x48XiTdtvRvshTKKxY+8b1CsgwdCJQI06PjE+VmdNGlmTcbvTakE7WQ/1HdsOdYCfXVu1dn5gpfMLLyWAr3akiydIWDgfQceHIfaP5ccHdNF2cNqgb2gzwQu5FTg+PTXBuzhKjQEpSH01vaxFxAmD1CZjZwuUPXjlVql/oWd7OpGKzkZiJdpgEnVgle6pF7kNMO7CeORx4PA/KtK3GIcFrK1bDij3jZFP1X2OExN4fxtLfVbj79XwPRhlVhB5BcQToEdktG3TTdrUcWmKgGSm2OS8leuKeIu3Y0RBkBjUpeGRTzmxgGZgUPvszRovC1UpGSeym8GuDcPj08YpYCTfXQNkCSdSesYEDTVbUZCV+CzRbgBjzGyhPG6S5FnfB1PMYySPUj/R3pSAlQ8C3nERiQ3C43lo6Sw8sjrSDA1Ncfq5rm6gbUa8/ivK+p+aEdZb5kkOT8jBIeguWYuDk0UuzlE5vaygppsVaAlQyB5DL/oaiaZn5QocC7SNTTAeAExs2shyg3VjbBJmT4BE7CIUEFTFgNpN3i1Q+hJtujwFKajgizhvj1FNAvNqnWpgAgTA5FKJ16AVkDqJdq5mJ83aTrQ1mT66xytvJ0lomJ2kDT3lmAZlIhh6EKeFr4x82omRBwLP/owbmOmPFzmeeugpA2ICrATMxSldAwYFCRHbnxANxUGUcDqOLJqiRHuJJAnhn5r5+WqBvh/t50XDYIPeu+mEzYwgCDBZ6ZQCsStfJNrpeNzYAlrdYSLh+NT9Rn0awC2HIrTe2GfoK18aThz10uxaTryjM1jQi7hAPRxqjLGxMflsWp4Df5tAoH33AJuOJNJCUPmARcvggbXURGEV4Aoc4cSpe7Bmg9ONB2NMfsPYodeW3ZU4dqAxNp1oV2HC2MTqe0B/th4ipiVcpB6bmpwcn0q0t5VghTQBxpnoPdKv9lZF52OCgVrkUdlEu1tYDiQe0DCgCeieTWoOCA34JeYQqJJLnCKQj/O0A4Mfo0W50TaNF0GAkhWBGt2IqIswVcBgyjnCGcxCTuD3jYO8L82y2emKJYyzbmymopxx99tl7mZljXVW8CmTdYn2zmFkLSq2HaYXbubgTq1IZHrOUGOaUeYFCZPycuVKHgwJJ+0Ix9YlAoGX31BTMAMGrOavJ9opjg4M4G8rAR5/Xx+fyUQCcLWCjJXi714RJMmgjQ2flMtdm6mB+DM6Ucfr1W+wgns07S0EqpQE7ikgBqaBCAusACPTILGNCYD6WnHymB4NbfhN25V0X4N0X2rIBOYtq6Ygc2C4TtwWTfA+3a/mcy534KEuHCl6M+zoHHIHGrjw99T0BbLY0ncc1xWMoLNZWATxpWR0DmqWBT/ExOPKYu0gTnwTpMe70/VxYKDzMFLQA2BYMkoDEd8CruSY6gW+A4jA7IqUf/myfEEMTAv5sZ3AKgI/wOQRQjBHgpjUqV4qMq5gMzY6fmRvg34Aj8g+yUb9rlobxM8MT1N7ifXWQZsyGxFMiX4YSRvCi02QnsAjrz7d2FitbT5dWd94f3FldmYRPyXaWJ6kyhwOlheF/jrQAYE3tSq8ScGVf+bwA4AQj/vEOJmsxHH8MNE+OJK8ArKNEnqoF6wxPrEMPGIgONviPEov8p5/UO45ewFXOJLfEwvAXl/wl2hZ1meX1pk4eadMUbFL5lSL1tuJU54WlFWhi+AK6oUVTMh1NBQ7xOHa7dKouATl/U4Z5XTdoP8BPyBg3FdyjUS0MY4hSrZsM5HVIN7hmRKNAzvo5vZ2JHAmAgVZz2g0qwNgMPApLKaDantHJtYmUGass6gHMJUb7NkW/0oN/wiokhouNWYjf+l5xhUt4Zv/KtFeK6mNYSfaFnbtA6U1JWnxRLx+xwP2AUNmGyc1BiFNCIzOh9ezClDDAfwzdpuoLmMDuyDBVewUARBgHx0WK9ChhO2FCfNZoMAA9BxH9HyZoWfTzVvjV/jsMTCBXkZeQVyVdHqYSjB+PcRrPnWfdBy0CwhY+Vu6YnkB1YGZQNMC1b5dsPH7UKkttoSEC4v3gtrhFV/gi8BeF8J9bBL0uimlmMTJDNGgdS0TfzMjaBwUNJSXVCDRXrkTkOd9Fhn5ET28W6krJAlTlU9M1SemuSVQz5aGBdZIA2QfW0HkmczywyWHDxauyr0yWoBqm5Z6wjxzs6zwzbKnBaV5JnSFQjWpZEqmrgrRoYcdEs/wQ36lXyu3EoJRgc6z8ckpoNCrKtbR8/RU0ujIw8J84ORxhYkta3Bo2idBM3DRgbaxuL4LjH0edRhaOVk8tUAlleR/GOrk5yJVmLN/6Jo062V3g8SYBSoGOq9UdD8MtjbYW0tsBhd89Fg+PjzkMqw1TD/w972gEwto4vL+weEJ10wSTrYGKicAHU3o+3AlBuZX+GYrzszTOHB3bfJhgpoX73swih2hgUxX2ic6qFy4MOhs5dqknhkh9P5PmLKEXLoFZER2J9gHF8vGFBTJqQlFfSVmcg8r37JbiIXONqp6XE+5mkl+dOnqoEbqwqWLRZYFyZZwCL1oUMH1cpd8T09LwOsJ+QFgNJyv+YCYQTk0NjXWmJjIuVckEoPuxACq+CimsB/AL/aWz3GF86ptwXNme1xWO5egADBBkWYisMMCD4CfqJD7ydACP12DZ7UO+x2AR+liSm0VppNAM2QAG5WuP+GBFC9ySzjvwCJBxmeuyWJ1qB0zfaleyXBLZrgBqz8C/12hlx/TrAvLPU+WAqoQZ2IbXYOJmGFdTVnM+weDMUBexdABm1Q/DqG1SpuUyS3mqcnbGqtASsX16DiWIVtyx4BShDNf+A/RIYP8yQryXquDG5gcY3XcTG1HB6LTpDBes7fmWYqTCCsFX8GuYngIgJ40iFn+cJUpEvBsFdvZB/EgwXZmWrbQ3xCDucaedD23ZEvGIcyJyxiVeTaYHiueo2umwfyfI2pM3bO3cNFTVfQ2t9nK4JsZbY3p6UrPeJkCBKoAAbyjZGboOCg5FvKyWFZuGXwhul29ZJzi1462TtL7YqXE6qyLn3JDlK0skC9E1aklb0G5mDy79UnhrKnW+gsRmMl6EeRAsli6HyROSwg5xhiYigZ0IxSSVwrqWpNQor8xmVNqct59xIws2LyTaJfyijH3WJNTsFEfmyi538SSAX8GrS0Tw6jCEOFycJh65UuafCfEyGZckJeXQCXjEsZ1tgxz13RcoeyYxamvhv02LKvQ4t9XkspeEO3o3F+Itk4Gx2yh8dme6Ui+jTG108JEpTkAhdNp6uh2xFrkQeVRkTOtMEckZHELruh7CnphoTfRBZ2ZqJ5Y+bdKOEopH0KCpqGGASDIRLuVX+NUZshKM1b8HzNvGPn3mSqE8+w0U4UJBx05FkLjcQsmtx08egigkW8CkxNw5E3mKKR5c/xmxGfputpJnAWsz3MMSh99BpqtkiBS2DpGuANahbwCHfThZIikVEq4zOWv389eZ1OKbEOfuK0B2j0wMqM9MDh5GFJQIAMrkDygHjTRCrAiNH1BRfeTWHK4jnPjZqRaP0O3FJrpiEPV+jO3ZVCkz0ov1A4bPk671DeZU/6LtgpP4WkGIUtL6XsgllHW/2x/V99rOwmmakKdyx/OfDSz+XRlaW706cyTlZXVzdmVpaWV5dyjp0/m1wtlluc3nyysie/fn1ljb+TASKKBFIFAt0PAR5sd1+P3gWgKEIkjp4HjuAErp+rFSsnohdlE0utEPJeBt8QVcEWMCTEaXnQsl2rmOHKtvAplz/r1opfgxY6kB4m5vlnqpEEODiLu1Er9SDhSmG6/ARWsZ24W+PUOg5pM34E+e0DFaDOxenTmF0HvOFilV0pumTQvJdFOgoJ+f2J6fGrifmU0twVGE1O4rysVbvx9PgkxoivrQFxSSjoQf0I6EIuV8RWQ6E/PRfyKjrFF4VFXySZybxqSf/NyLh7Ecnj1F9gYDJwHPfU2gNlEiQv2HLAG9mI9i86k/vbC2l+W4qGu+WIfgJijMkfK2yWO9OxoG7EJJHW2FlyQ6AeBFyMZ1Mv4QDezaU/pj7Rs4XOghDjm1TyxMfdsk1zQwvubM/0cv9PNhqyztCrUhHlAJUbzPtFTkdaJzdS/pysFgvAly6FDNLvwpd8SIdgeTlJBDsKW5jxwV/neix1dSTVf5HJxJNSR8RrYaMuFjwh79NYvwCRHLkwAdjydiWUeKR2cqD+YEpJCJfSB3pzA0nGVUAsDy6YUfvt410Phk0Y9QfJcrohae1scCm9UKTV5ktRL/WIsQkHRkvqK6PQ6aKLQGhGxZMLjT0BeM0fMhYJhQSehMleANsgmRKJyjBVdojqInER7c2lmEShzc2Ztbnlmc2nme49Gik+KvirBC+SbbmHgu8szAXgOAvp1JaBH5YczZbVHCB030DdctmmsoIwNVoAEo+IT/KAzv9PLtU4c1bYcv8aKVzFI2W7N+QvfKIOH2ZVtiF8IR1spjOfpkccS8dALTJEwWCI9IuU1Hy5A3YuSwoSHtJxdlXYzldRGmctuVcrBpu1gqzwgAwLhsg84bnfRrk7dfWSeIsPcG472Eu0cE4Oyj+xVlY9M4VzI+xexyT8SJkE5PgUUyG0mFt7IMe/AfYyLX43QpcdDi590TKjaLeTtvVmJMHFmjPZ0ov5Kx+7YqAVK1uuEejmQ+AkiEK1sv8zR2u8BeqksX4E1wwVtH3EmDpFl5SSn6UPbtQV76ELJz0VaULtoFAr/Gky2I3T9ltNFjzdSBp/bg/xaIkORi8PLhbFl/hXO/VdSt2XO5hIS9X+VwNpsuvquY+/puLRa3zCYvlyrQssm7/V8iWem5jwlhU4zMcWCUKgHpmzROGCyRZJCfsLjHPnlchwR31IQ7kc5dAb1tWIo+I6Cc8vptKyffWdFUpLMSyxtoEiGQGmgaBnC1NYziwhBmXmjDWAuKUsHsGisrsj2Y4kVTI+nqEfJHfH4aNEdycQLg8BNQ9kf5QJWPZycZQC8LEmb/Kg4aRaWiVnZzBEloTryyb1DOk8YLtayMvgxXgB5qIj4kawOmLuAed0wLgn/NhNUu0IwxSlfdbOMU/zVlRDkSezO2PFsEs3SMwrCjVa+8WHTLpVWZbuUVW6e3qbSum8UsK3j+yRegN2pOJ/uGyUyLbpKs6j9fXSIviItIPo8keE4TUxWe22lz3rTDEHqJkAVhP3Mo9hQDfhAddsTXLSQ84lIsCkyNt+mdFCxzDX2uPZxm+XPZClcifbw6N1oO3aEwbV9jJVwqwlrUSbec2sUifhq0VeshjOZ7h/kvDcHTTNfdTHRA3UD5vkcDZBwL+Se+ROYf7O5srz4/SLhpOKHKX2ckf9Dzo0iJxOU0gc4nV1R2HjcC4vDul4VtQCLJW8ZkYnK4lLHs/zJ8QM1FxCfiYNROZbr5KS+hBuyosvD+rwwJhvESp2ECqNHd50ch98BIvquvTVPbwufUWVsASQg56lEu6YumnLf2wcHKhr1MZQF07K/QNq7wgMrugiQk3M2n1Y8MMaTQyuTttA45kriHeU6qTPM0Wx6AwGDW1VMGQP9EPS4VJn42zmaE9IEYR+IjnEYJ6JLLKe6ZG9yK2zscFEjP8gCR1wq3VbPcUX+5SWVEh8EoBCeqIlnoD+qZa2c8LV0tHBO2p3M9bS2hARo87QvntvMjFQ3CLzURv2x8AiocwIzRGMde9y7Y3IlaZ4Jr2uOV1VSMstm2RkExz2nlXDn2bQ6U5ZKxDyKso7flumznDt776Dcqcz1Bdw33piYvI/p3rd6pXLlc7fGqu2MZuBhlimF2TDXVZfSVkFjfRnVSSmdWjhY1W5eYj7B/WeE7J2s1ymPV4nNxMuebTmIk9lGoF8+8kagTbkm4YGUF7uQ+c92bEqhbNTtxeauN5R9LQ+tUa+PVe4lohgB24+JfjKh+t1S5f4V1o227JGD4lp1YjVN1JvqJH3d99IwmsrLwbI8WO9QPFLOPqWQQBWUqLCPS/3jSpBXJk+Bie24lkH7KIMQjf3j+ve8LswqkPloUV2lYsyXKfI3THc7gN/aUPz4+tOZxura8gcC4aoNxHxa/dnU4uWAMFxmTdrk+Ssdp7mzTjleF+XnbUxz5nmiXieC/xdXOFUsYH6LdsJPc/EKWSJUh9vuljQA38u8ekWr67kIYPfwr+OaSiHTnwot45AhU2/Ltqw0Zmr0ysjmfq38Vp9x4qIHlb3kyVTxvt8UwyMjDbvNcG5gEmuYOtQmHvQyskf7mB7MPK7dnBdEWjRJeUSO/MegVOYiCbTh58JeELnWu6a/D9DybrTXtMzKnLdtdNHA9Ml6S071lPbi8jBHeUZZ/JgpeCzbS+fpXgbTcjAJ4Xxu/w8SlcjCr9I/MQAqOddBXXjLtwH1ApiAYHufuoBSCs1eEUBmAu1OmWvwTbbbn3a0LbHyqSsPxrqWNQUysl7hG/DtPZ0lgynM6FbR2ZaafyKlUrIAb6Y5cFUbn7Dg30m0J4c3jHxYJgIloG2LN6djuF2EfN4oqlAfm2ZMLGF3MXQ8S11ReXfLvqqrst7KAvkU2cc/UBWL34NSXspayDJtSWsfmp9ZWJx7UiVlgXrtmE6fkNJ3MIWPyztJh3X4blTTMoGnLJZcCLJxovFgYrw+URkRByUBMTeVkacaY/dJSjbezTdAnhEcn8K397a6bqR5lhEpGaAgSsd7aP0HZJ2+U4zEIUvn0wh8G9YLPofc1SWSDtFbHKPbP8lvBjX4gQJQeQXvJCDlzMhap5fTfaBXJCNDndh8vcIfp9ydcL/SzCnIBgKWoQecBDC1PBUFMKAgFjQ6dpgN1nl1Ct8MRBJ5eQvSUTYfjYlqOOGngCLB2qawwKtEqKTB5neJvqUwh/jWQqOES5OH2TpZFaO8fwT5C8C9BQjLXQUXmUbn2jgU3XYZbahC/7Qjw2BR276OUBN6KMGFbsKSzVeRDofJQ4aceAfuKgJc0Q5mehVTofCFO0eaYibCyRwG4xWRbHSYlIaHh0goT7VckVouEe5iKekuzeLHn/8zqLuYpVyZdf1mj90fKe3f5LSfWxyJ7tGXP1zeCVVypk+w1NGrynnL7ex8rUUipsL/kG7vAQAiB6eRxq6/UJyXcUCOvocaJIol8eFaz8MMEm0BHXR+4jpb77bxt0fNsPMoNhHC41GYg/BRDII9HgVwbtqP/FGmND7aHwV22QKogkdY36O3oK73Dq00tiIbaAozYLnpA8U8RZyJDGWEeAYn3Ojh3OUZmK4EwiJOV4kdF6KXuetNaZcLbdkgV/3WCyccQ49cZKI8OMNjGkyzASbq5duiqAm04ViwLHj+yhTRw3D19p0srmkWDAk6QobO9tPlnWzofetmSFuv3Mmaplg7PgppYxfDGYhUg8sry3OlsBvm+vOsITxYdOTTVipC59c/631IS2EaGCLIcalXU82w7L3QFfYkUWWv3dpGD66ucCA+EA75Sjgtk46CZizKmTdatt9EZovBOhV5MxJqraZ70I9CkOdz1gDT/N9Say/LdoKJuhu8cJXTu4DVBQNkU5lzR6CTpWlu5nZjyXhRjsaXwqFK/9NU3kkjv1TaClW5B9fA6L1qL9TM4Y0LMVuxzk/JEU6KhcN7LclJwV2Xi7Nza6LK9CyCW0oboBgby5xYD6YxOHaB2kNdNAqbolt6Rbew2FP6/n34uoru+bXV2USbqDD5tvFQzlbH1ZGKVWZfLI6FyAUNWZd77Om6Xn0EDMv4Rya8WmUdg6mPfPp/q/YwACuRAZ+P3T6scI5nRN/rLK6xCqW3+p3P0ly0XlmhTG79uCp7jk8lskh8NA38QV3UWXlih7QdrhwJp3Xh5h7zcrItAXi0FZiTc1/bMsdKUUUGTAO2vffXnm8aM/ozU39R1x/84Ln+vvz10/ro2OTkZ+89H/nBeyNleMmbLWobmmS/YgsMUpi0e7kFCo2NQElbFPF3mL/XpcAzpSBnObqDEySwSTurVCnfVotzieb0w+GIqCLzIi+yHM4N/oMcknmzIsGgkFCTOomrqAgn4Z/lUmUF8AMI+zHWld9Z2Bhv1O+PsQzNyjl5p0coGSx9wvhsmgcaRimTvGL7H5/JD3udxbA7ZrRj4ymrYJ3mNgvpZHO4zhZKde6bpD1QE4kJthvzWdGRP8dwd09dfUAQblpFiNAx+kNhgBN0bimeqZFl1ikSpku27iedIMITAM9Sd3DB3h1rTDdyFhDOLkU9efw3dXOUUInpfSVUwgj5Rcl5gtFcYcSezWtyiTb79T11FNPgnjM/2Aqs/VyuT/WK8zxmkbvcpwkXStXxVlt2nOh2C6wRkcFxs4pDJd58eEjeLLEkcePoUXYlc0336dc9A4T5UUuHgBx83ARQSDvAANaZD+Y2RldX1jdGn87NPMGNHvhKby/tadkCSNhhvnQmr/a6IrmYy7DrPS3petVmMXl/YlX4v6Ay8tR+sWGMn4wmfPrXyKA9YIRXSw6R0kkXI2Xz1abDiIpxoF+IyFj10I7maqsX5XYW+Mx5G+XwJx4OZPSmMtXugN9kO3/YkUIE7GHg+EnxdKF6TwcvP4cb5VNks70UtGm7dPadnh5LoKdv6ewteR99pXNEpIMKRVByQ6MTcerABB6YApdZZLn0YzyXFZNw3++lshUPXmXj4Mk++c2No4dKbEyP8RxRcE4xbeQz1V7GLNHVtGTd6afp/qUeuxOUTusp4TZTnKBG50LrLJ58AuPJKBk9oXTkXL50GYGeuup+kssyZbsMGYPmHfdMsL1TafjRWZksrJN67TE7DsMD7PCN2Oh4JnqPaPvRQH1srGibFHiJLA88ked2dWS5yPA/yXLwcVbIf+S3nO1OxDgi9bcM1Y2x8cLGUtnmtfyYcRpMA9J4/49yGxIPPMWFB8fX5mZX1p4I/q8KN+Qd4kZ6ZsD8IaLKGDJvxTrwJRAdGnTkF7f0KC5mB98+jIcydsW2rsp4F+ek87TvK6I8OmG5/Vx5aI0oBf3/LjSMfVqXXxw96C1zNwqMGfiDB8tj8uTXfH3NbmFoIPd21R6sgw3rez3PIiiYkYc6kQDtSDprtlU80qb6fFb1punBunEfKls6nJ8XlCJ6jm4TPi2Ztzc7ew+qfcCyGqUtfynF5zLqP0+0XzripilQjvQ9ExOUzGiHRjDeOow61aagD0zxO9/T18RtK/p3naQ9Sgf6g6qBZ6CPzjSbdpiMsksgAHp6n4Aozs/tebIiD+NofyIOOM6dCs0u8mFHD/JgIhb+UmWw7JaOkOZcdq2cYVzYfmsK1U+G+eIxBUz1JZczXiQDioe/zdSMH4q+K10XZX15tMIN5Jodn7YSKJTExoFnuUkef51B56BPR1dPHvnMLmbd3L1zO3doFz69eyeeWQIywJ7hXRSPPq1/dvduZe6XZHnStsZOqHA9Xy3tPGV7hkF6AUmOxGbsvovVvz86TJ/ZDItv6N9/H7BWOT/sCKLXOXCgb4hy17ijKFadUtEMwnwu5MnJ8anp+/UHdLjpeV6+ZPbeqtom4YS4onHHwXzB8zNz67XZjbXacrAq9kmc4tufEcW4D+NazxUDTa7HcdAf+g7lzXzHd7ofEKfxDBpk53ngeAw4qH1tppcdF4pblXMGwy1leByDNvv4d9exkGbeqzA++XuzXJOwrbWleV7HKlaxmtZwq+ch9Lmw0jXFaRN0KndqMOXPGspUjSwfNc0FFHoNH+6dg70Ouek5V7wDgD9vVGktkkYlpk9Y8I2KSWQKovxqNm16xenwfJd16ZyMQ5lqjewc75CdWC+ZJHFVHL3yoJU84l6Qd78x9b3naXIRO0JK2A6Fk37JF2oCvfsWemxEoMdsYeZcEu51HFH72XwmK8ADebW4DcftOpqCnI/2IHWV136rKv5j2V2eCLvFBeNI9WG9GfclWt906QCijHxjO+mEKbb6tp3lU15LT2QX57bjng1h6YBZSN8P8kEVpNfvVV3goTLDcWpMdtRIYafw4DhdunG95y0FtB1HHxObGipdtMOFDUKYSZcOB0V1z921aYRMOvJf7cthWMfiAZGzC33atosGQuNQOfD0SWeb1bhf53JJ/8D9EszteromPU+0G7loKk+JYoeeAgdsx3yj/9Xqs5+wyMDZdIct2xmZnm2CoYT3DjhovKCqUFqt2D8k7YG81csuOBIWYezwhvoyDaYt0EzdqL5Gg2+DGD+iSi38M38O/Fq5M718CrV8/qYYBkoYsLwQrV96Mjc/853FDZFCUdJj6T4UwnjMysU9aZcr3Y9cabii0MYzr0nflz3PjJPFG1oEaVoOLOLV0p4ZO4owysyOlQNzBk87U/shpBOsX/m4HfMDrNfmZhaXjI3FJ8pwDc6Z4hQJdGyqD4GkvANbUHCcM/wC9Tls4kqbih1v18unR6E2WmD2t0uJHd4WXVSndt3eO0SMRY9hzE4XEJLpp9OHi3RLpo0E1rsCyZSutyp0Rmw4rTwgWz5HZV9x9HqtVwYlnmDK8llzB5mChvaqfPpNdkbXlTIvO4E4n+t2j8tWyHsuWfFTUyJwUq3uspPu6OoKtfbBj4Mibxw85luezgqmyG2Ef4UdDYBZWO2OvyNvMTMO2oXlRp1y4PfAI26KyVDobVsQW5cVuQ6HTxAcK25TonMMvMByWvs6m4i+38y5utTpDPeq8rnTR8W06ytlHsQaGXFcqwR6apVOFSR7QOgKDLPiMudKcw8fcftlYf6/rKQeaZdYQYtkN5iIm5tGekcHc0eAnJOsQX40dP9Yo+qehRc75RsZjB43MlTccrTLji1WnNuFB1akZ+WqL3riRT6C/+DxXQ8OZ4hUh8OOdqkb5hrmXQp4gt1ItUcaKZvFCLhLWr7Ho8XtYz0JdJbaz+IgUlb/QsnuLBykKAyBstQRpIg2J5/SyapgrfTeLH9v/enM2OTUAr33dlX4zrK3OttcoGV7y98sp/aDzBHOS252zhz5coU1kl8zYTjLapJO0QEZzg+tT3USm4exu9k1tRpdU8svgqQrI+nBEIAxnnuEG9j5EUiAtfSR8J89OFaL6b8n6Af2+WWpED4BSXrM3Gzo9W75blz8fkfcAZteS4sf7vXzO9D703vc8WpVg18g/sfD0d/4xd//3/+Nrs48BoTXwWuJOxHeIb70T3719u5/+fk/onsisQZ+caSWNt9PzffTd/Z0qMf97t/o4nXoFvcIyhccr0YBOvVydxyfdWL+eCOY861n2knEJpaM9Ey7GKY3qj82t1dadId2/Ayv5sYbdtfhuWvTQ/h5QTtOhvps4C5qLzUDt+NhXOOidA9qer8zXjW99W2PcK70TL68s3yT8hXpJuWxUL5FWZBnkSyk1cwuWpboZAEACfjjwp/99B/+z89/fbofb6/mdBJp57Jyy2S0/fBnv3Xt1N/90x8JkpHY4Vu66FpNB7NmLBHB4DPtTBOeLAfJMrkRFrVTYKy41jq/XX68eBGuSAllBUbE1/nspYfS1cg4JAO+A9677Gbdc9KlxY/BuH+IazOQ5NbmqrQ2J8v3W+MLnYNYO9H6uvISwmw2CrN58FCkiXqsDSZ06/wpy2bWN3f3nV7UBv3sVuihmM/cjd4z97AbngR5gTt0aJMnmFXWcCsKvOFVZ3uY+jCc3uA88EPaKDYedrsVqNGPpf4m/vkc/+yyOVLN3Oc9q/g8radD9XTVqD3U+3bfI/0sQR/1QL3cXS08FHhi6ShHTW98G5yO1b7AT13lT7+Wa/HawfT724eg3/0c/eJbv3ES//4I//zuoSjid/DPV/jnJ6xVVV++6lnFV2k9v031/OVTxFfqCQSK6JL4ffbdHw8/ePUPfvBnkvgtdRJKrjxf/CZ4usq/CTR9+Dujr239j+1//fO02ZSBvqJ+Pf7Zf7/050PHN/40LXASqKFi/tRj167jnzN/qXOuwcT+fzW1+yM=','a_1-0','scope','false')) - scope-31
 Tez vertex scope-32
 # Plan on vertex
 POValueOutputTez - scope-38	->	 [scope-22]
@@ -40,4 +40,4 @@
         |   |
         |   |---Project[bytearray][1] - scope-4
         |
-        |---a: Load(file:///tmp/input1:org.apache.pig.test.TestMapSideCogroup$DummyCollectableLoader) - scope-0
\ No newline at end of file
+        |---a: Load(file:///tmp/input1:org.apache.pig.test.TestMapSideCogroup$DummyCollectableLoader) - scope-0
diff --git a/test/org/apache/pig/test/data/GoldenFiles/tez/TEZC-MergeJoin-1.gld b/test/org/apache/pig/test/data/GoldenFiles/tez/TEZC-MergeJoin-1.gld
index 5111019..9977eb4 100644
--- a/test/org/apache/pig/test/data/GoldenFiles/tez/TEZC-MergeJoin-1.gld
+++ b/test/org/apache/pig/test/data/GoldenFiles/tez/TEZC-MergeJoin-1.gld
@@ -14,7 +14,7 @@
 |   |
 |   Project[tuple][*] - scope-38
 |
-|---b: Load(file:///tmp/input2:org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.MergeJoinIndexer('org.apache.pig.builtin.PigStorage','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','b_1-1','scope','true')) - scope-8
+|---b: Load(file:///tmp/input2:org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.MergeJoinIndexer('org.apache.pig.builtin.PigStorage','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','b_1-1','scope','true')) - scope-8
 Tez vertex scope-37
 # Plan on vertex
 POValueOutputTez - scope-43	->	 [scope-29]
@@ -48,4 +48,4 @@
             |   |
             |   |---Project[bytearray][1] - scope-4
             |
-            |---a: Load(file:///tmp/input1:org.apache.pig.builtin.PigStorage) - scope-0
\ No newline at end of file
+            |---a: Load(file:///tmp/input1:org.apache.pig.builtin.PigStorage) - scope-0