Merge branch 'gerrit/trinity' into 'gerrit/ionic'

Ext-ref: MB-64874
Change-Id: I1065bc955c2d554cd8a405b944535409de867174
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestHelper.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestHelper.java
index 8d7f188..6688ad8 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestHelper.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestHelper.java
@@ -67,6 +67,8 @@
     private static final String[] TEST_DIRS = new String[] { "txnLogDir", "IODevice", "spill_area", "config" };
     private static final String PATTERN_VAR_ID_PREFIX = "\\$\\$";
     private static final Pattern PATTERN_VAR_ID = Pattern.compile(PATTERN_VAR_ID_PREFIX + "(\\d+)");
+    private static final Map<Integer, Integer> EXPECTED = new HashMap<>();
+    private static final Map<Integer, Integer> ACTUAL = new HashMap<>();
     private static final ObjectMapper SORTED_MAPPER = new ObjectMapper();
     private static final ObjectWriter PRETTY_SORTED_WRITER;
 
@@ -314,10 +316,20 @@
         return objectMapper;
     }
 
+    public static void comparePlansWithoutCost(List<String> linesExpected, List<String> linesActual, File queryFile)
+            throws Exception {
+        comparePlans(linesExpected, linesActual, queryFile, TestHelper::planLineEqualsWithoutCosts);
+    }
+
     public static void comparePlans(List<String> linesExpected, List<String> linesActual, File queryFile)
             throws Exception {
-        int varBaseExpected = findBaseVarId(linesExpected);
-        int varBaseActual = findBaseVarId(linesActual);
+        comparePlans(linesExpected, linesActual, queryFile, TestHelper::planLineEquals);
+    }
+
+    public static void comparePlans(List<String> linesExpected, List<String> linesActual, File queryFile,
+            LineComparator lineComparator) throws Exception {
+        int varBaseExpected = findBaseVarId(linesExpected, EXPECTED);
+        int varBaseActual = findBaseVarId(linesActual, ACTUAL);
 
         Iterator<String> readerExpected = linesExpected.iterator();
         Iterator<String> readerActual = linesActual.iterator();
@@ -330,7 +342,7 @@
             }
             lineActual = readerActual.next();
 
-            if (!planLineEquals(lineExpected, varBaseExpected, lineActual, varBaseActual)) {
+            if (!lineComparator.equalLines(lineExpected, varBaseExpected, lineActual, varBaseActual)) {
                 throw TestExecutor.createLineChangedException(queryFile, lineExpected, lineActual, num);
             }
             ++num;
@@ -343,13 +355,20 @@
 
     private static boolean planLineEquals(String lineExpected, int varIdBaseExpected, String lineActual,
             int varIdBaseActual) {
-        String lineExpectedNorm = normalizePlanLine(lineExpected, varIdBaseExpected);
-        String lineActualNorm = normalizePlanLine(lineActual, varIdBaseActual);
+        String lineExpectedNorm = normalizePlanLine(lineExpected, varIdBaseExpected, EXPECTED);
+        String lineActualNorm = normalizePlanLine(lineActual, varIdBaseActual, ACTUAL);
+        return lineExpectedNorm.equals(lineActualNorm);
+    }
+
+    private static boolean planLineEqualsWithoutCosts(String lineExpected, int varIdBaseExpected, String lineActual,
+            int varIdBaseActual) {
+        String lineExpectedNorm = normalizePlanLine(removeCost(lineExpected), varIdBaseExpected, EXPECTED);
+        String lineActualNorm = normalizePlanLine(removeCost(lineActual), varIdBaseActual, ACTUAL);
         return lineExpectedNorm.equals(lineActualNorm);
     }
 
     // rewrite variable ids in given plan line: $$varId -> $$(varId-varIdBase)
-    private static String normalizePlanLine(String line, int varIdBase) {
+    private static String normalizePlanLine(String line, int varIdBase, Map<Integer, Integer> varMap) {
         if (varIdBase == Integer.MAX_VALUE) {
             // plan did not contain any variables -> no rewriting necessary
             return line;
@@ -358,23 +377,43 @@
         StringBuilder sb = new StringBuilder(line.length());
         while (m.find()) {
             int varId = Integer.parseInt(m.group(1));
-            int newVarId = varId - varIdBase;
+            Integer newVarId = varMap.get(varId);
+            if (newVarId == null) {
+                throw new IllegalStateException("no new var id mapped for " + varId);
+            }
             m.appendReplacement(sb, PATTERN_VAR_ID_PREFIX + newVarId);
         }
         m.appendTail(sb);
         return sb.toString();
     }
 
-    private static int findBaseVarId(Collection<String> plan) {
+    private static int findBaseVarId(Collection<String> plan, Map<Integer, Integer> map) {
         int varIdBase = Integer.MAX_VALUE;
+        map.clear();
+        int counter = 1;
         Matcher m = PATTERN_VAR_ID.matcher("");
         for (String line : plan) {
             m.reset(line);
             while (m.find()) {
                 int varId = Integer.parseInt(m.group(1));
+                Integer previouslyMapped = map.putIfAbsent(varId, counter);
+                if (previouslyMapped == null) {
+                    counter++;
+                }
                 varIdBase = Math.min(varIdBase, varId);
             }
         }
         return varIdBase;
     }
+
+    private static String removeCost(String originalStr) {
+        int i = originalStr.indexOf(" [cardinality: ");
+        return i >= 0 ? originalStr.substring(0, i) : originalStr;
+    }
+
+    @FunctionalInterface
+    private interface LineComparator {
+        boolean equalLines(String lineExpected, int varIdBaseExpected, String lineActual, int varIdBaseActual);
+
+    }
 }
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/optimizer/OptimizerTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/optimizer/OptimizerTest.java
index 6a85e0c..922a4c9 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/optimizer/OptimizerTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/optimizer/OptimizerTest.java
@@ -34,6 +34,8 @@
 import org.apache.asterix.compiler.provider.ILangCompilationProvider;
 import org.apache.asterix.om.base.IAObject;
 import org.apache.asterix.test.common.TestHelper;
+import org.apache.asterix.translator.ExecutionPlans;
+import org.apache.asterix.translator.SessionConfig;
 import org.apache.commons.io.FileUtils;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.api.client.IHyracksClientConnection;
@@ -83,14 +85,17 @@
                     (ICcApplicationContext) integrationUtil.cc.getApplicationContext(), hcc, new StringReader(query),
                     plan, provider, statementExecutorFactory, storageComponentProvider);
             asterix.setStatementParameters(queryParams);
-            asterix.compile(true, false, false, true, true, false, false);
+            asterix.compile(true, false, true, true, false, false, false, SessionConfig.PlanFormat.STRING);
+            ExecutionPlans executionPlans = asterix.getExecutionPlans();
+            String planStr = executionPlans.getOptimizedLogicalPlan();
+            plan.write(planStr);
         } catch (AlgebricksException e) {
             throw new Exception("Compile ERROR for " + queryFile + ": " + e.getMessage(), e);
         }
 
         List<String> linesActual = Files.readAllLines(actualFile.toPath(), StandardCharsets.UTF_8);
         List<String> linesExpected = getExpectedLines();
-        TestHelper.comparePlans(linesExpected, linesActual, queryFile);
+        TestHelper.comparePlansWithoutCost(linesExpected, linesActual, queryFile);
     }
 
     protected List<String> getExpectedLines() throws IOException {
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ASTERIXDB-2402.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ASTERIXDB-2402.plan
index ad746cf..1dff738 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ASTERIXDB-2402.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ASTERIXDB-2402.plan
@@ -1,173 +1,328 @@
+distribute result [$$227]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$227])
     -- STREAM_PROJECT  |PARTITIONED|
-      -- SUBPLAN  |PARTITIONED|
-              {
+      subplan {
+                aggregate [$$227] <- [listify($$226)]
                 -- AGGREGATE  |LOCAL|
+                  assign [$$226] <- [{"channelExecutionTime": $$257, "result": $$258, "BrokerEndpoint": $$BrokerEndpoint}]
                   -- ASSIGN  |LOCAL|
-                    -- MICRO_PRE_CLUSTERED_GROUP_BY[$$230]  |LOCAL|
-                            {
+                    group by ([$$BrokerEndpoint := $$230]) decor ([$$257 := $$259; $$258 := $$260]) {
+                              aggregate [] <- []
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- MICRO_PRE_CLUSTERED_GROUP_BY[$$230]  |LOCAL|
+                      order (ASC, $$230)
                       -- MICRO_STABLE_SORT [$$230(ASC)]  |LOCAL|
+                        assign [$$230] <- [$$sub.getField("BrokerEndpoint")]
                         -- ASSIGN  |LOCAL|
+                          unnest $$sub <- scan-collection($$219)
                           -- UNNEST  |LOCAL|
-                            -- SUBPLAN  |LOCAL|
-                                    {
+                            subplan {
+                                      aggregate [$$219] <- [listify($$218)]
                                       -- AGGREGATE  |LOCAL|
+                                        assign [$$218] <- [{"sub": $$sub}]
                                         -- ASSIGN  |LOCAL|
+                                          unnest $$sub <- scan-collection($$256)
                                           -- UNNEST  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- SUBPLAN  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-              }
+             }
+      -- SUBPLAN  |PARTITIONED|
+        project ([$$260, $$259, $$256])
         -- STREAM_PROJECT  |PARTITIONED|
+          commit
           -- COMMIT  |PARTITIONED|
+            project ([$$260, $$259, $$256, $$214])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                insert into channels.EmergenciesNearMeChannelResults from record: $$231 partitioned by [$$214]
                 -- INSERT_DELETE  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$214]  |PARTITIONED|
+                    assign [$$260, $$259, $$256, $$214] <- [$$231.getField("result"), $$231.getField("channelExecutionTime"), $$231.getField("brokerSubIds"), $$231.getField(0)]
                     -- ASSIGN  |PARTITIONED|
+                      assign [$$231] <- [cast(check-unknown(put-autogenerated-key($$212, "resultId")))] project: [$$231]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$212] <- [{"result": $$result, "channelExecutionTime": current-datetime(), "channelSubId": $$266, "deliveryTime": current-datetime(), "brokerSubIds": $$211}] project: [$$212]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$211, $$266, $$result])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$267]  |PARTITIONED|
-                                      {
+                              group by ([$$269 := $$267]) decor ([$$266; $$result]) {
+                                        aggregate [$$211] <- [listify({"BrokerEndPoint": $$253, "brokerSubId": $$238})]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$268)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$267]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$267)
                                   -- STABLE_SORT [$$267(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$267]  |PARTITIONED|
+                                      project ([$$result, $$266, $$253, $$238, $$268, $$267])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          left outer join (eq($$237, $$266))
                                           -- HYBRID_HASH_JOIN [$$266][$$237]  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              running-aggregate [$$267] <- [create-query-uid()]
                                               -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                unnest $$result <- scan-collection($$191) project: [$$result, $$266]
                                                 -- UNNEST  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- PRE_CLUSTERED_GROUP_BY[$$322]  |PARTITIONED|
-                                                            {
+                                                    group by ([$$266 := $$322]) decor ([]) {
+                                                              aggregate [$$191] <- [listify({"report": $$331, "shelters": $$181})]
                                                               -- AGGREGATE  |LOCAL|
-                                                                -- MICRO_PRE_CLUSTERED_GROUP_BY[$$324, $$325]  |LOCAL|
-                                                                        {
+                                                                group by ([$$262 := $$324; $$263 := $$325]) decor ([$$320; $$326; $$327; $$328; $$322; $$329; $$330; $$331]) {
+                                                                          aggregate [$$181] <- [listify({"location": $$232})]
                                                                           -- AGGREGATE  |LOCAL|
+                                                                            select (not(is-missing($$236)))
                                                                             -- STREAM_SELECT  |LOCAL|
+                                                                              nested tuple source
                                                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                        }
+                                                                       }
+                                                                -- MICRO_PRE_CLUSTERED_GROUP_BY[$$324, $$325]  |LOCAL|
+                                                                  select (and(not(is-missing($$321)), not(is-missing($$323))))
                                                                   -- STREAM_SELECT  |LOCAL|
+                                                                    nested tuple source
                                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                            }
+                                                           }
+                                                    -- PRE_CLUSTERED_GROUP_BY[$$322]  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        order (ASC, $$322) (ASC, $$324) (ASC, $$325)
                                                         -- STABLE_SORT [$$322(ASC), $$324(ASC), $$325(ASC)]  |PARTITIONED|
+                                                          exchange
                                                           -- HASH_PARTITION_EXCHANGE [$$322]  |PARTITIONED|
+                                                            union ($$319, $$294, $$232) ($$u, $$u, $$320) ($$264, $$264, $$321) ($$233, $$233, $$322) ($$265, $$265, $$323) ($$234, $$234, $$324) ($$235, $$235, $$325) ($$242, $$242, $$326) ($$243, $$243, $$327) ($$244, $$244, $$328) ($$252, $$252, $$329) ($$sub, $$sub, $$330) ($$r, $$r, $$331) ($$317, $$292, $$236)
                                                             -- UNION_ALL  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                select (spatial-intersect($$319, $$244)) retain-untrue ($$317 <- missing) project: [$$319, $$u, $$264, $$233, $$265, $$234, $$235, $$242, $$243, $$244, $$252, $$sub, $$r, $$317]
                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                  assign [$$319] <- [$$318.getField(1)] project: [$$233, $$sub, $$242, $$234, $$r, $$243, $$252, $$264, $$235, $$u, $$265, $$244, $$292, $$317, $$319]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- BTREE_SEARCH (channels.Shelters.Shelters)  |PARTITIONED|
+                                                                      left-outer-unnest-map [$$317, $$318] <- index-search("Shelters", 0, "Default", "channels", "Shelters", true, false, 1, $$292, 1, $$292, true, true, true)
+                                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          project ([$$233, $$sub, $$242, $$234, $$r, $$243, $$252, $$264, $$235, $$u, $$265, $$244, $$292])
                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              split ($$293)
                                                                               -- SPLIT  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  project ([$$233, $$sub, $$242, $$234, $$r, $$243, $$252, $$264, $$235, $$u, $$265, $$244, $$288, $$289, $$292, $$293])
                                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                      -- RTREE_SEARCH (channels.Shelters.s_location)  |PARTITIONED|
+                                                                                      left-outer-unnest-map [$$288, $$289, $$290, $$291, $$292, $$293] <- index-search("s_location", 1, "Default", "channels", "Shelters", true, true, 4, $$284, $$285, $$286, $$287)
+                                                                                      -- RTREE_SEARCH  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                          assign [$$284, $$285, $$286, $$287] <- [create-mbr($$244, 2, 0), create-mbr($$244, 2, 1), create-mbr($$244, 2, 2), create-mbr($$244, 2, 3)]
                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              left outer join (and(spatial-intersect($$243, $$244), eq($$235, $$242)))
                                                                                               -- NESTED_LOOP  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                  left outer join (true)
                                                                                                   -- NESTED_LOOP  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                      assign [$$242] <- [$$sub.getField("param0")]
                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                          -- DATASOURCE_SCAN (channels.EmergenciesNearMeChannelChannelSubscriptions)  |PARTITIONED|
+                                                                                                          data-scan []<-[$$233, $$sub] <- channels.EmergenciesNearMeChannelChannelSubscriptions
+                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                              empty-tuple-source
                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                      assign [$$264] <- [true]
                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                        select (gt($$252, numeric-subtract(current-datetime(), day_time_duration: {PT10S })))
                                                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                                                          assign [$$243, $$252] <- [$$r.getField(2), $$r.getField(3)]
                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                              -- BTREE_SEARCH (channels.Reports.Reports)  |PARTITIONED|
+                                                                                                              unnest-map [$$234, $$r] <- index-search("Reports", 0, "Default", "channels", "Reports", false, false, 1, $$274, 1, $$274, true, true, true)
+                                                                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                                                                exchange
                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                  order (ASC, $$274)
                                                                                                                   -- STABLE_SORT [$$274(ASC)]  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                      project ([$$274])
                                                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                        exchange
                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                          -- BTREE_SEARCH (channels.Reports.report_time)  |PARTITIONED|
+                                                                                                                          unnest-map [$$273, $$274] <- index-search("report_time", 0, "Default", "channels", "Reports", false, false, 1, $$272, 0, false, true, false)
+                                                                                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                              assign [$$272] <- [numeric-subtract(current-datetime(), day_time_duration: {PT10S })]
                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                empty-tuple-source
                                                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                  assign [$$265, $$244] <- [true, $$u.getField(0)]
                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                      -- DATASOURCE_SCAN (channels.UserLocations)  |PARTITIONED|
+                                                                                                      data-scan []<-[$$235, $$u] <- channels.UserLocations
+                                                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                          empty-tuple-source
                                                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                select (spatial-intersect($$294, $$244)) retain-untrue ($$236 <- missing) project: [$$294, $$u, $$264, $$233, $$265, $$234, $$235, $$242, $$243, $$244, $$252, $$sub, $$r, $$292]
                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                  assign [$$294] <- [create-point($$288, $$289)] project: [$$233, $$sub, $$242, $$234, $$r, $$243, $$252, $$264, $$235, $$u, $$265, $$244, $$292, $$294]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    project ([$$233, $$sub, $$242, $$234, $$r, $$243, $$252, $$264, $$235, $$u, $$265, $$244, $$288, $$289, $$292])
                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        split ($$293)
                                                                         -- SPLIT  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            project ([$$233, $$sub, $$242, $$234, $$r, $$243, $$252, $$264, $$235, $$u, $$265, $$244, $$288, $$289, $$292, $$293])
                                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                -- RTREE_SEARCH (channels.Shelters.s_location)  |PARTITIONED|
+                                                                                left-outer-unnest-map [$$288, $$289, $$290, $$291, $$292, $$293] <- index-search("s_location", 1, "Default", "channels", "Shelters", true, true, 4, $$284, $$285, $$286, $$287)
+                                                                                -- RTREE_SEARCH  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                    assign [$$284, $$285, $$286, $$287] <- [create-mbr($$244, 2, 0), create-mbr($$244, 2, 1), create-mbr($$244, 2, 2), create-mbr($$244, 2, 3)]
                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        left outer join (and(spatial-intersect($$243, $$244), eq($$235, $$242)))
                                                                                         -- NESTED_LOOP  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            left outer join (true)
                                                                                             -- NESTED_LOOP  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                assign [$$242] <- [$$sub.getField("param0")]
                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                    -- DATASOURCE_SCAN (channels.EmergenciesNearMeChannelChannelSubscriptions)  |PARTITIONED|
+                                                                                                    data-scan []<-[$$233, $$sub] <- channels.EmergenciesNearMeChannelChannelSubscriptions
+                                                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                        empty-tuple-source
                                                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                assign [$$264] <- [true]
                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                  select (gt($$252, numeric-subtract(current-datetime(), day_time_duration: {PT10S })))
                                                                                                   -- STREAM_SELECT  |PARTITIONED|
+                                                                                                    assign [$$243, $$252] <- [$$r.getField(2), $$r.getField(3)]
                                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                        -- BTREE_SEARCH (channels.Reports.Reports)  |PARTITIONED|
+                                                                                                        unnest-map [$$234, $$r] <- index-search("Reports", 0, "Default", "channels", "Reports", false, false, 1, $$274, 1, $$274, true, true, true)
+                                                                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                                                                          exchange
                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                            order (ASC, $$274)
                                                                                                             -- STABLE_SORT [$$274(ASC)]  |PARTITIONED|
+                                                                                                              exchange
                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                project ([$$274])
                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                  exchange
                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                    -- BTREE_SEARCH (channels.Reports.report_time)  |PARTITIONED|
+                                                                                                                    unnest-map [$$273, $$274] <- index-search("report_time", 0, "Default", "channels", "Reports", false, false, 1, $$272, 0, false, true, false)
+                                                                                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                                                                                      exchange
                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                        assign [$$272] <- [numeric-subtract(current-datetime(), day_time_duration: {PT10S })]
                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                          empty-tuple-source
                                                                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                            assign [$$265, $$244] <- [true, $$u.getField(0)]
                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                -- DATASOURCE_SCAN (channels.UserLocations)  |PARTITIONED|
+                                                                                                data-scan []<-[$$235, $$u] <- channels.UserLocations
+                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    empty-tuple-source
                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$237]  |PARTITIONED|
+                                              assign [$$268] <- [true]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$238, $$237, $$253])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    join (and(eq($$248, $$239), eq($$250, $$240)))
                                                     -- HYBRID_HASH_JOIN [$$248, $$250][$$239, $$240]  |PARTITIONED|
+                                                      exchange
                                                       -- HASH_PARTITION_EXCHANGE [$$248, $$250]  |PARTITIONED|
+                                                        assign [$$250, $$248] <- [$$bs.getField("BrokerName"), $$bs.getField("DataverseName")] project: [$$238, $$237, $$248, $$250]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (channels.EmergenciesNearMeChannelBrokerSubscriptions)  |PARTITIONED|
+                                                            data-scan []<-[$$237, $$238, $$bs] <- channels.EmergenciesNearMeChannelBrokerSubscriptions
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                      exchange
                                                       -- HASH_PARTITION_EXCHANGE [$$239, $$240]  |PARTITIONED|
+                                                        assign [$$253] <- [$$b.getField("BrokerEndPoint")] project: [$$253, $$239, $$240]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (channels.Broker)  |PARTITIONED|
+                                                            data-scan []<-[$$239, $$240, $$b] <- channels.Broker
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/array_agg/array_agg.1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/array_agg/array_agg.1.plan
index bb0f33b..fbd03b5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/array_agg/array_agg.1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/array_agg/array_agg.1.plan
@@ -1,6 +1,12 @@
+distribute result [$$r]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    order (ASC, $$r)
     -- STABLE_SORT [$$r(ASC)]  |UNPARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+        unnest $$r <- range(1, 2)
         -- UNNEST  |UNPARTITIONED|
+          empty-tuple-source
           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.10.plan
index 665d725..aeb19d0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.10.plan
@@ -1,33 +1,63 @@
+distribute result [$$79]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$79] <- [{"g": $$g, "count_distinct_x": $$82, "sum_distinct_x": $$83}] project: [$$79]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$g(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
-                {
+        group by ([$$g := $$g]) decor ([]) {
+                  aggregate [$$82, $$83] <- [agg-sql-count($$72), agg-sql-sum($$72)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$72])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$72)
                       -- MICRO_STABLE_SORT [$$72(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$g)
             -- STABLE_SORT [$$g(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$g]  |PARTITIONED|
+                join (true)
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true)
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$72] <- [$$x.getField(1)] project: [$$72]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$x])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                              data-scan []<-[$$80, $$x] <- test.d1
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        project ([])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                            data-scan []<-[$$81, $$y] <- test.d2
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    unnest $$g <- range(1, 3)
                     -- UNNEST  |UNPARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.11.plan
index 55a8c3a..548b0cd 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.11.plan
@@ -1,40 +1,75 @@
+distribute result [$$79]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$79] <- [{"g": $$g, "sum_distinct_x": $$82, "sum_distinct_y": $$83}] project: [$$79]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$g(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
-                {
+        group by ([$$g := $$g]) decor ([]) {
+                  aggregate [$$82] <- [agg-sql-sum($$72)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$72])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$72)
                       -- MICRO_STABLE_SORT [$$72(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$83] <- [agg-sql-sum($$77)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$77])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$77)
                       -- MICRO_STABLE_SORT [$$77(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$g)
             -- STABLE_SORT [$$g(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$g]  |PARTITIONED|
+                join (true)
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true)
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$72] <- [$$x.getField(1)] project: [$$72]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$x])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                              data-scan []<-[$$80, $$x] <- test.d1
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        assign [$$77] <- [$$y.getField(1)] project: [$$77]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$y])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                              data-scan []<-[$$81, $$y] <- test.d2
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    unnest $$g <- range(1, 3)
                     -- UNNEST  |UNPARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.12.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.12.plan
index 523e336..78a3a5d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.12.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.12.plan
@@ -1,37 +1,69 @@
+distribute result [$$88]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$88] <- [{"g": $$g, "sum_x": $$91, "sum_distinct_x": $$92, "sum_distinct_y": $$93}] project: [$$88]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$g(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
-                {
+        group by ([$$g := $$g]) decor ([]) {
+                  aggregate [$$91] <- [agg-sql-sum($$76)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$92, $$93] <- [agg-sql-sum($$76), agg-sql-sum($$76)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$76])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$76)
                       -- MICRO_STABLE_SORT [$$76(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$g)
             -- STABLE_SORT [$$g(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$g]  |PARTITIONED|
+                join (true)
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true)
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$76] <- [$$x.getField(1)] project: [$$76]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$x])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                              data-scan []<-[$$89, $$x] <- test.d1
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        project ([])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                            data-scan []<-[$$90, $$y] <- test.d2
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    unnest $$g <- range(1, 3)
                     -- UNNEST  |UNPARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.13.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.13.plan
index aefdb9a..9eb6774 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.13.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.13.plan
@@ -1,53 +1,99 @@
+distribute result [$$100]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$100] <- [{"g": $$g, "sum_distinct_x": $$104, "sum_y": $$105, "sum_distinct_z": $$106}] project: [$$100]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$g(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
-                {
+        group by ([$$g := $$g]) decor ([]) {
+                  aggregate [$$104] <- [agg-sql-sum($$88)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$88])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$88)
                       -- MICRO_STABLE_SORT [$$88(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$105] <- [agg-sql-sum($$93)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$106] <- [agg-sql-sum($$98)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$98])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$98)
                       -- MICRO_STABLE_SORT [$$98(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$g)
             -- STABLE_SORT [$$g(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$g]  |PARTITIONED|
+                join (true)
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true)
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (true)
                         -- NESTED_LOOP  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$88] <- [$$x.getField(1)] project: [$$88]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$x])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                  data-scan []<-[$$101, $$x] <- test.d1
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$93] <- [$$y.getField(1)] project: [$$93]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$y])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                  data-scan []<-[$$102, $$y] <- test.d2
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        assign [$$98] <- [$$z.getField(1)] project: [$$98]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$z])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.d3)  |PARTITIONED|
+                              data-scan []<-[$$103, $$z] <- test.d3
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    unnest $$g <- range(1, 3)
                     -- UNNEST  |UNPARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.14.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.14.plan
index c522bc1..1052301 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.14.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.14.plan
@@ -1,59 +1,109 @@
+distribute result [$$154]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$154] <- [{"g": $$g, "sum_distinct_x": $$158, "sum_y": $$159, "sum_distinct_z": $$160, "avg_distinct_x": $$161, "avg_distinct_y": $$162, "count_x": $$163, "count_distinct_y": $$164, "avg_z": $$165, "count_distinct_z": $$166}] project: [$$154]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$g(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
-                {
+        group by ([$$g := $$g]) decor ([]) {
+                  aggregate [$$158, $$161] <- [agg-sql-sum($$112), agg-sql-avg($$112)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$112])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$112)
                       -- MICRO_STABLE_SORT [$$112(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$159, $$163, $$165] <- [agg-sql-sum($$117), agg-sql-count($$112), agg-sql-avg($$122)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$160, $$166] <- [agg-sql-sum($$122), agg-sql-count($$122)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$122])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$122)
                       -- MICRO_STABLE_SORT [$$122(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$162, $$164] <- [agg-sql-avg($$117), agg-sql-count($$117)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$117])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$117)
                       -- MICRO_STABLE_SORT [$$117(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$g)
             -- STABLE_SORT [$$g(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$g]  |PARTITIONED|
+                join (true)
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true)
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (true)
                         -- NESTED_LOOP  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$112] <- [$$x.getField(1)] project: [$$112]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$x])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                  data-scan []<-[$$155, $$x] <- test.d1
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$117] <- [$$y.getField(1)] project: [$$117]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$y])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                  data-scan []<-[$$156, $$y] <- test.d2
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        assign [$$122] <- [$$z.getField(1)] project: [$$122]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$z])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.d3)  |PARTITIONED|
+                              data-scan []<-[$$157, $$z] <- test.d3
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    unnest $$g <- range(1, 3)
                     -- UNNEST  |UNPARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.15.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.15.plan
index 5485ea5..46d05cb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.15.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.15.plan
@@ -1,162 +1,324 @@
+distribute result [$$122]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$122] <- [{"sum_distinct_x": $$123, "sum_y": $$124, "sum_distinct_z": $$125, "avg_distinct_x": $$126, "avg_distinct_y": $$127, "count_x": $$128, "count_distinct_y": $$129, "avg_z": $$130, "count_distinct_z": $$131}] project: [$$122]
     -- ASSIGN  |LOCAL|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+        join (true)
         -- NESTED_LOOP  |LOCAL|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+            join (true)
             -- NESTED_LOOP  |LOCAL|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                join (true)
                 -- NESTED_LOOP  |LOCAL|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                    aggregate [$$123, $$126] <- [agg-sql-sum($$141), agg-sql-avg($$141)]
                     -- AGGREGATE  |LOCAL|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                        distinct ([$$141])
                         -- PRE_SORTED_DISTINCT_BY  |LOCAL|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                            order (ASC, $$141)
                             -- STABLE_SORT [$$141(ASC)]  |LOCAL|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                join (true)
                                 -- NESTED_LOOP  |UNPARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                    join (true)
                                     -- NESTED_LOOP  |UNPARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        replicate
                                         -- REPLICATE  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            replicate
                                             -- REPLICATE  |UNPARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                unnest $$141 <- range(1, 5)
                                                 -- UNNEST  |UNPARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        replicate
                                         -- REPLICATE  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            project ([])
                                             -- STREAM_PROJECT  |UNPARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |UNPARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                    unnest $$142 <- range(6, 10)
                                                     -- UNNEST  |UNPARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                    replicate
                                     -- REPLICATE  |UNPARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        project ([])
                                         -- STREAM_PROJECT  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            replicate
                                             -- REPLICATE  |UNPARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                unnest $$143 <- range(11, 15)
                                                 -- UNNEST  |UNPARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                    aggregate [$$124, $$128, $$130] <- [agg-global-sql-sum($$168), agg-sql-sum($$169), agg-global-sql-avg($$170)]
                     -- AGGREGATE  |LOCAL|
+                      aggregate [$$168, $$169, $$170] <- [agg-local-sql-sum($$154), agg-sql-count($$153), agg-local-sql-avg($$155)]
                       -- AGGREGATE  |LOCAL|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                          join (true)
                           -- NESTED_LOOP  |UNPARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                              join (true)
                               -- NESTED_LOOP  |UNPARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                  assign [$$153] <- [$$141] project: [$$153]
                                   -- ASSIGN  |UNPARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                      replicate
                                       -- REPLICATE  |UNPARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                          replicate
                                           -- REPLICATE  |UNPARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                              unnest $$141 <- range(1, 5)
                                               -- UNNEST  |UNPARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                  replicate
                                   -- REPLICATE  |UNPARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                      assign [$$154] <- [$$142] project: [$$154]
                                       -- ASSIGN  |UNPARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                          replicate
                                           -- REPLICATE  |UNPARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                              unnest $$142 <- range(6, 10)
                                               -- UNNEST  |UNPARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                              assign [$$155] <- [$$167] project: [$$155]
                               -- ASSIGN  |UNPARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                  replicate
                                   -- REPLICATE  |UNPARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                      assign [$$167] <- [$$143] project: [$$167]
                                       -- ASSIGN  |UNPARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                          replicate
                                           -- REPLICATE  |UNPARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                              unnest $$143 <- range(11, 15)
                                               -- UNNEST  |UNPARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                aggregate [$$125, $$131] <- [agg-sql-sum($$167), agg-sql-count($$167)]
                 -- AGGREGATE  |LOCAL|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                    distinct ([$$167])
                     -- PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                        order (ASC, $$167)
                         -- STABLE_SORT [$$167(ASC)]  |LOCAL|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                            join (true)
                             -- NESTED_LOOP  |UNPARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                join (true)
                                 -- NESTED_LOOP  |UNPARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                    replicate
                                     -- REPLICATE  |UNPARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        assign [$$165] <- [$$141] project: []
                                         -- ASSIGN  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            replicate
                                             -- REPLICATE  |UNPARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                unnest $$141 <- range(1, 5)
                                                 -- UNNEST  |UNPARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                    assign [] <- [] project: []
                                     -- ASSIGN  |UNPARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        replicate
                                         -- REPLICATE  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            project ([])
                                             -- STREAM_PROJECT  |UNPARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |UNPARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                    unnest $$142 <- range(6, 10)
                                                     -- UNNEST  |UNPARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                replicate
                                 -- REPLICATE  |UNPARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                    assign [$$167] <- [$$143] project: [$$167]
                                     -- ASSIGN  |UNPARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        replicate
                                         -- REPLICATE  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            unnest $$143 <- range(11, 15)
                                             -- UNNEST  |UNPARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+            aggregate [$$127, $$129] <- [agg-sql-avg($$y), agg-sql-count($$y)]
             -- AGGREGATE  |LOCAL|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                distinct ([$$y])
                 -- PRE_SORTED_DISTINCT_BY  |LOCAL|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                    order (ASC, $$y)
                     -- STABLE_SORT [$$y(ASC)]  |LOCAL|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                        join (true)
                         -- NESTED_LOOP  |UNPARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                            join (true)
                             -- NESTED_LOOP  |UNPARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                assign [] <- [] project: []
                                 -- ASSIGN  |UNPARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                    replicate
                                     -- REPLICATE  |UNPARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        assign [$$165] <- [$$141] project: []
                                         -- ASSIGN  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            replicate
                                             -- REPLICATE  |UNPARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                unnest $$141 <- range(1, 5)
                                                 -- UNNEST  |UNPARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                assign [$$y] <- [$$154] project: [$$y]
                                 -- ASSIGN  |UNPARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                    replicate
                                     -- REPLICATE  |UNPARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        assign [$$154] <- [$$142] project: [$$154]
                                         -- ASSIGN  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            replicate
                                             -- REPLICATE  |UNPARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                unnest $$142 <- range(6, 10)
                                                 -- UNNEST  |UNPARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                            assign [] <- [] project: []
                             -- ASSIGN  |UNPARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                replicate
                                 -- REPLICATE  |UNPARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                    project ([])
                                     -- STREAM_PROJECT  |UNPARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        replicate
                                         -- REPLICATE  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            unnest $$143 <- range(11, 15)
                                             -- UNNEST  |UNPARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.16.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.16.plan
index 481e9fe..9b628cf 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.16.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.16.plan
@@ -1,48 +1,87 @@
+distribute result [$$145]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$145] <- [{"g": $$g, "sum_distinct_x": $$146, "sum_y": $$147, "sum_distinct_z": $$148, "avg_distinct_x": $$149, "avg_distinct_y": $$150, "count_x": $$151, "count_distinct_y": $$152, "avg_z": $$153, "count_distinct_z": $$154}] project: [$$145]
     -- ASSIGN  |LOCAL|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |LOCAL|
-        -- PRE_CLUSTERED_GROUP_BY[$$g]  |LOCAL|
-                {
+        group by ([$$g := $$g]) decor ([]) {
+                  aggregate [$$146, $$149] <- [agg-sql-sum($$x), agg-sql-avg($$x)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$x])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$x)
                       -- MICRO_STABLE_SORT [$$x(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$147, $$151, $$153] <- [agg-global-sql-sum($$182), agg-sql-sum($$183), agg-global-sql-avg($$184)]
                   -- AGGREGATE  |LOCAL|
+                    aggregate [$$182, $$183, $$184] <- [agg-local-sql-sum($$y), agg-sql-count($$x), agg-local-sql-avg($$z)]
                     -- AGGREGATE  |LOCAL|
+                      nested tuple source
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$148, $$154] <- [agg-sql-sum($$z), agg-sql-count($$z)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$z])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$z)
                       -- MICRO_STABLE_SORT [$$z(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$150, $$152] <- [agg-sql-avg($$y), agg-sql-count($$y)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$y])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$y)
                       -- MICRO_STABLE_SORT [$$y(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$g]  |LOCAL|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+            order (ASC, $$g)
             -- STABLE_SORT [$$g(ASC)]  |LOCAL|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                join (true)
                 -- NESTED_LOOP  |UNPARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                    join (true)
                     -- NESTED_LOOP  |UNPARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                        join (true)
                         -- NESTED_LOOP  |UNPARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                            unnest $$x <- range(1, 5)
                             -- UNNEST  |UNPARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                            unnest $$y <- range(6, 10)
                             -- UNNEST  |UNPARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                        unnest $$z <- range(11, 15)
                         -- UNNEST  |UNPARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                    unnest $$g <- range(1, 3)
                     -- UNNEST  |UNPARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.17.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.17.plan
index cc28b55..b8fa1cf 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.17.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.17.plan
@@ -1,86 +1,162 @@
+distribute result [$$155]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    union ($$224, $$258, $$155)
     -- UNION_ALL  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        assign [$$224] <- [to-object-var-str({"sum_distinct_x": $$292, "sum_distinct_y": $$293})] project: [$$224]
         -- ASSIGN  |PARTITIONED|
+          project ([$$292, $$293])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- PRE_CLUSTERED_GROUP_BY[$$156]  |PARTITIONED|
-                      {
+              group by ([$#1 := $$156]) decor ([]) {
+                        aggregate [$$292] <- [agg-sql-sum($$124)]
                         -- AGGREGATE  |LOCAL|
+                          distinct ([$$124])
                           -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                            order (ASC, $$124)
                             -- MICRO_STABLE_SORT [$$124(ASC)]  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                      }
-                      {
+                     }
+                     {
+                        aggregate [$$293] <- [agg-sql-sum($$129)]
                         -- AGGREGATE  |LOCAL|
+                          distinct ([$$129])
                           -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                            order (ASC, $$129)
                             -- MICRO_STABLE_SORT [$$129(ASC)]  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                      }
+                     }
+              -- PRE_CLUSTERED_GROUP_BY[$$156]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$156)
                   -- STABLE_SORT [$$156(ASC)]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$156]  |PARTITIONED|
+                      join (true)
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$156, $$124] <- [true, $$x.getField(1)] project: [$$156, $$124]
                           -- ASSIGN  |PARTITIONED|
+                            assign [$$x] <- [$$x] project: [$$x]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                replicate
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$x])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                        data-scan []<-[$$160, $$x] <- test.d1
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$129] <- [$$147] project: [$$129]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  assign [$$147] <- [$$y.getField(1)] project: [$$147]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$y])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                        data-scan []<-[$$161, $$y] <- test.d2
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        assign [$$258] <- [to-object-var-str({"sum_distinct_x": $$294, "sum_distinct_y": $$295})] project: [$$258]
         -- ASSIGN  |PARTITIONED|
+          project ([$$294, $$295])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- PRE_CLUSTERED_GROUP_BY[$$157]  |PARTITIONED|
-                      {
+              group by ([$#2 := $$157]) decor ([]) {
+                        aggregate [$$294] <- [agg-sql-sum($$142)]
                         -- AGGREGATE  |LOCAL|
+                          distinct ([$$142])
                           -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                            order (ASC, $$142)
                             -- MICRO_STABLE_SORT [$$142(ASC)]  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                      }
-                      {
+                     }
+                     {
+                        aggregate [$$295] <- [agg-sql-sum($$147)]
                         -- AGGREGATE  |LOCAL|
+                          distinct ([$$147])
                           -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                            order (ASC, $$147)
                             -- MICRO_STABLE_SORT [$$147(ASC)]  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                      }
+                     }
+              -- PRE_CLUSTERED_GROUP_BY[$$157]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$157)
                   -- STABLE_SORT [$$157(ASC)]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$157]  |PARTITIONED|
+                      join (true)
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$157, $$142] <- [false, $$x.getField(1)] project: [$$157, $$142]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$x])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                      data-scan []<-[$$160, $$x] <- test.d1
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                              assign [$$147] <- [$$y.getField(1)] project: [$$147]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$y])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                    data-scan []<-[$$161, $$y] <- test.d2
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.3.plan
index 704690c..2007ceb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.3.plan
@@ -1,23 +1,46 @@
+distribute result [$$47]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$47] <- [{"count_distinct_x": $$50}] project: [$$47]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$50] <- [agg-sql-count(1)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$45(ASC) ]  |PARTITIONED|
+          distinct ([$$45])
           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$45)
               -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$45]  |PARTITIONED|
+                  join (true)
                   -- NESTED_LOOP  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$45] <- [$$x.getField(1)] project: [$$45]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$x])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                            data-scan []<-[$$48, $$x] <- test.d1
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                      project ([])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                          data-scan []<-[$$49, $$y] <- test.d2
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.4.plan
index f48a2c6..3788451 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.4.plan
@@ -1,23 +1,46 @@
+distribute result [$$56]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$56] <- [{"count_distinct_x": $$59, "sum_distinct_x": $$60}] project: [$$56]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$59, $$60] <- [agg-sql-count($$49), agg-sql-sum($$49)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$49(ASC) ]  |PARTITIONED|
+          distinct ([$$49])
           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$49)
               -- STABLE_SORT [$$49(ASC)]  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$49]  |PARTITIONED|
+                  join (true)
                   -- NESTED_LOOP  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$49] <- [$$x.getField(1)] project: [$$49]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$x])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                            data-scan []<-[$$57, $$x] <- test.d1
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                      project ([])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                          data-scan []<-[$$58, $$y] <- test.d2
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.5.plan
index f555a00..2c05ac1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.5.plan
@@ -1,55 +1,110 @@
+distribute result [$$56]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$56] <- [{"sum_distinct_x": $$59, "sum_distinct_y": $$60}] project: [$$56]
     -- ASSIGN  |UNPARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+        join (true)
         -- NESTED_LOOP  |UNPARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+            aggregate [$$59] <- [agg-sql-sum($$65)]
             -- AGGREGATE  |UNPARTITIONED|
+              exchange
               -- SORT_MERGE_EXCHANGE [$$65(ASC) ]  |PARTITIONED|
+                distinct ([$$65])
                 -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$65)
                     -- STABLE_SORT [$$65(ASC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$65]  |PARTITIONED|
+                        join (true)
                         -- NESTED_LOOP  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$65] <- [$$67.getField(1)] project: [$$65]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$67])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  replicate
                                   -- REPLICATE  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                      data-scan []<-[$$68, $$67] <- test.d1
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$70, $$69] <- [$$58, $$y] project: []
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                replicate
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                    data-scan []<-[$$58, $$y] <- test.d2
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+            aggregate [$$60] <- [agg-sql-sum($$54)]
             -- AGGREGATE  |UNPARTITIONED|
+              exchange
               -- SORT_MERGE_EXCHANGE [$$54(ASC) ]  |PARTITIONED|
+                distinct ([$$54])
                 -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$54)
                     -- STABLE_SORT [$$54(ASC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$54]  |PARTITIONED|
+                        join (true)
                         -- NESTED_LOOP  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$57, $$x] <- [$$68, $$67] project: []
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                replicate
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                    data-scan []<-[$$68, $$67] <- test.d1
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$54] <- [$$y.getField(1)] project: [$$54]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$y])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  replicate
                                   -- REPLICATE  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                      data-scan []<-[$$58, $$y] <- test.d2
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.6.plan
index 6fd488e..9e7ed5c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.6.plan
@@ -1,57 +1,114 @@
+distribute result [$$65]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$65] <- [{"sum_x": $$68, "sum_distinct_x": $$69, "sum_distinct_y": $$70}] project: [$$65]
     -- ASSIGN  |UNPARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+        join (true)
         -- NESTED_LOOP  |UNPARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+            aggregate [$$68] <- [agg-global-sql-sum($$80)]
             -- AGGREGATE  |UNPARTITIONED|
+              exchange
               -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                aggregate [$$80] <- [agg-local-sql-sum($$75)]
                 -- AGGREGATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true)
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$75] <- [$$53] project: [$$75]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$53] <- [$$x.getField(1)] project: [$$53]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$x])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                      data-scan []<-[$$66, $$x] <- test.d1
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [] <- [] project: []
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                project ([])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                    data-scan []<-[$$67, $$y] <- test.d2
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+            aggregate [$$69, $$70] <- [agg-sql-sum($$53), agg-sql-sum($$53)]
             -- AGGREGATE  |UNPARTITIONED|
+              exchange
               -- SORT_MERGE_EXCHANGE [$$53(ASC) ]  |PARTITIONED|
+                distinct ([$$53])
                 -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$53)
                     -- STABLE_SORT [$$53(ASC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$53]  |PARTITIONED|
+                        join (true)
                         -- NESTED_LOOP  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$53] <- [$$x.getField(1)] project: [$$53]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$x])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                      data-scan []<-[$$66, $$x] <- test.d1
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                project ([])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                    data-scan []<-[$$67, $$y] <- test.d2
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.7.plan
index fcda7e7..9f486e6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.7.plan
@@ -1,128 +1,256 @@
+distribute result [$$77]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$77] <- [{"sum_distinct_x": $$81, "sum_y": $$82, "sum_distinct_z": $$83}] project: [$$77]
     -- ASSIGN  |UNPARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+        join (true)
         -- NESTED_LOOP  |UNPARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+            join (true)
             -- NESTED_LOOP  |UNPARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                aggregate [$$81] <- [agg-sql-sum($$90)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- SORT_MERGE_EXCHANGE [$$90(ASC) ]  |PARTITIONED|
+                    distinct ([$$90])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$90)
                         -- STABLE_SORT [$$90(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$90]  |PARTITIONED|
+                            join (true)
                             -- NESTED_LOOP  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (true)
                                 -- NESTED_LOOP  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$90] <- [$$93.getField(1)] project: [$$90]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$93])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                              data-scan []<-[$$94, $$93] <- test.d1
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        project ([])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            replicate
                                             -- REPLICATE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                                data-scan []<-[$$96, $$95] <- test.d2
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                replicate
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    project ([])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (test.d3)  |PARTITIONED|
+                                            data-scan []<-[$$98, $$97] <- test.d3
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                aggregate [$$82] <- [agg-global-sql-sum($$111)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$111] <- [agg-local-sql-sum($$103)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (true)
                         -- NESTED_LOOP  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (true)
                             -- NESTED_LOOP  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [] <- [] project: []
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$78, $$x] <- [$$94, $$93] project: []
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            replicate
                                             -- REPLICATE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                                data-scan []<-[$$94, $$93] <- test.d1
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$103] <- [$$107.getField(1)] project: [$$103]
                                 -- ASSIGN  |PARTITIONED|
+                                  assign [$$108, $$107] <- [$$96, $$95] project: [$$107]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      replicate
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                          data-scan []<-[$$96, $$95] <- test.d2
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [] <- [] project: []
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                replicate
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    project ([])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (test.d3)  |PARTITIONED|
+                                            data-scan []<-[$$98, $$97] <- test.d3
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+            aggregate [$$83] <- [agg-sql-sum($$75)]
             -- AGGREGATE  |UNPARTITIONED|
+              exchange
               -- SORT_MERGE_EXCHANGE [$$75(ASC) ]  |PARTITIONED|
+                distinct ([$$75])
                 -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$75)
                     -- STABLE_SORT [$$75(ASC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$75]  |PARTITIONED|
+                        join (true)
                         -- NESTED_LOOP  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (true)
                             -- NESTED_LOOP  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                replicate
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$78, $$x] <- [$$94, $$93] project: []
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                            data-scan []<-[$$94, $$93] <- test.d1
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [] <- [] project: []
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        project ([])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            replicate
                                             -- REPLICATE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                                data-scan []<-[$$96, $$95] <- test.d2
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$75] <- [$$z.getField(1)] project: [$$75]
                             -- ASSIGN  |PARTITIONED|
+                              assign [$$80, $$z] <- [$$98, $$97] project: [$$z]
                               -- ASSIGN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  replicate
                                   -- REPLICATE  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.d3)  |PARTITIONED|
+                                      data-scan []<-[$$98, $$97] <- test.d3
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.8.plan
index 91e3ad3..9c9693d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.8.plan
@@ -1,185 +1,370 @@
+distribute result [$$131]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$131] <- [{"sum_distinct_x": $$135, "sum_y": $$136, "sum_distinct_z": $$137, "avg_distinct_x": $$138, "avg_distinct_y": $$139, "count_x": $$140, "count_distinct_y": $$141, "avg_z": $$142, "count_distinct_z": $$143}] project: [$$131]
     -- ASSIGN  |UNPARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+        join (true)
         -- NESTED_LOOP  |UNPARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+            join (true)
             -- NESTED_LOOP  |UNPARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                join (true)
                 -- NESTED_LOOP  |UNPARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                    aggregate [$$135, $$138] <- [agg-sql-sum($$156), agg-sql-avg($$156)]
                     -- AGGREGATE  |UNPARTITIONED|
+                      exchange
                       -- SORT_MERGE_EXCHANGE [$$156(ASC) ]  |PARTITIONED|
+                        distinct ([$$156])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$156)
                             -- STABLE_SORT [$$156(ASC)]  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$156]  |PARTITIONED|
+                                join (true)
                                 -- NESTED_LOOP  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (true)
                                     -- NESTED_LOOP  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$156] <- [$$159.getField(1)] project: [$$156]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$159])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  replicate
                                                   -- REPLICATE  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                                      data-scan []<-[$$160, $$159] <- test.d1
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            assign [$$162, $$161] <- [$$180, $$179] project: []
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                                    data-scan []<-[$$180, $$179] <- test.d2
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        assign [$$164, $$163] <- [$$200, $$199] project: []
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            replicate
                                             -- REPLICATE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.d3)  |PARTITIONED|
+                                                data-scan []<-[$$200, $$199] <- test.d3
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                    aggregate [$$136, $$140, $$142] <- [agg-global-sql-sum($$201), agg-sql-sum($$202), agg-global-sql-avg($$203)]
                     -- AGGREGATE  |UNPARTITIONED|
+                      exchange
                       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                        aggregate [$$201, $$202, $$203] <- [agg-local-sql-sum($$175), agg-sql-count($$174), agg-local-sql-avg($$176)]
                         -- AGGREGATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (true)
                             -- NESTED_LOOP  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (true)
                                 -- NESTED_LOOP  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$174] <- [$$156] project: [$$174]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$156] <- [$$159.getField(1)] project: [$$156]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$159])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  replicate
                                                   -- REPLICATE  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                                      data-scan []<-[$$160, $$159] <- test.d1
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        assign [$$175] <- [$$179.getField(1)] project: [$$175]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$179])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              replicate
                                               -- REPLICATE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                                  data-scan []<-[$$180, $$179] <- test.d2
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$176] <- [$$194] project: [$$176]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        assign [$$194] <- [$$199.getField(1)] project: [$$194]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$199])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              replicate
                                               -- REPLICATE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.d3)  |PARTITIONED|
+                                                  data-scan []<-[$$200, $$199] <- test.d3
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                aggregate [$$137, $$143] <- [agg-sql-sum($$194), agg-sql-count($$194)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- SORT_MERGE_EXCHANGE [$$194(ASC) ]  |PARTITIONED|
+                    distinct ([$$194])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$194)
                         -- STABLE_SORT [$$194(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$194]  |PARTITIONED|
+                            join (true)
                             -- NESTED_LOOP  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (true)
                                 -- NESTED_LOOP  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$196, $$195] <- [$$160, $$159] project: []
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            replicate
                                             -- REPLICATE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                                data-scan []<-[$$160, $$159] <- test.d1
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [] <- [] project: []
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            assign [$$162, $$161] <- [$$180, $$179] project: []
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                                    data-scan []<-[$$180, $$179] <- test.d2
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                replicate
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$194] <- [$$199.getField(1)] project: [$$194]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$199])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.d3)  |PARTITIONED|
+                                              data-scan []<-[$$200, $$199] <- test.d3
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+            aggregate [$$139, $$141] <- [agg-sql-avg($$94), agg-sql-count($$94)]
             -- AGGREGATE  |UNPARTITIONED|
+              exchange
               -- SORT_MERGE_EXCHANGE [$$94(ASC) ]  |PARTITIONED|
+                distinct ([$$94])
                 -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$94)
                     -- STABLE_SORT [$$94(ASC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$94]  |PARTITIONED|
+                        join (true)
                         -- NESTED_LOOP  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (true)
                             -- NESTED_LOOP  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [] <- [] project: []
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$196, $$195] <- [$$160, $$159] project: []
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            replicate
                                             -- REPLICATE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                                data-scan []<-[$$160, $$159] <- test.d1
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$94] <- [$$175] project: [$$94]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        assign [$$175] <- [$$179.getField(1)] project: [$$175]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$179])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              replicate
                                               -- REPLICATE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                                  data-scan []<-[$$180, $$179] <- test.d2
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [] <- [] project: []
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                replicate
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$164, $$163] <- [$$200, $$199] project: []
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (test.d3)  |PARTITIONED|
+                                            data-scan []<-[$$200, $$199] <- test.d3
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.9.plan
index 979d032..c7ec943 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.9.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-sql-sugar/distinct_mixed/distinct_mixed.9.plan
@@ -1,33 +1,63 @@
+distribute result [$$70]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$70] <- [{"g": $$g, "count_distinct_x": $$73}] project: [$$70]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$g(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
-                {
+        group by ([$$g := $$g]) decor ([]) {
+                  aggregate [$$73] <- [agg-sql-count($$68)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$68])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$68)
                       -- MICRO_STABLE_SORT [$$68(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$g)
             -- STABLE_SORT [$$g(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$g]  |PARTITIONED|
+                join (true)
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true)
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$68] <- [$$x.getField(1)] project: [$$68]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$x])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                              data-scan []<-[$$71, $$x] <- test.d1
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        project ([])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                            data-scan []<-[$$72, $$y] <- test.d2
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    unnest $$g <- range(1, 3)
                     -- UNNEST  |UNPARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.10.plan
index 9887601..0b3845b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.10.plan
@@ -1,25 +1,44 @@
+distribute result [$$84]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$84] <- [{"ten": $$ten, "cnt": $$88, "min2": $$89, "max2": $$90, "sum20": $$91}] project: [$$84]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$ten(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$98]  |PARTITIONED|
-                {
+        group by ([$$ten := $$98]) decor ([]) {
+                  aggregate [$$88, $$89, $$90, $$91] <- [agg-sql-sum($$94), agg-global-sql-min($$95), agg-global-sql-max($$96), agg-global-sql-sum($$97)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$98]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$98]  |PARTITIONED|
-            -- PRE_CLUSTERED_GROUP_BY[$$85]  |PARTITIONED|
-                    {
+            group by ([$$98 := $$85]) decor ([]) {
+                      aggregate [$$94, $$95, $$96, $$97] <- [agg-sql-count(1), agg-local-sql-min($$66), agg-local-sql-max($$66), agg-local-sql-sum($$82)]
                       -- AGGREGATE  |LOCAL|
+                        select (gt($$93, 0))
                         -- STREAM_SELECT  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- PRE_CLUSTERED_GROUP_BY[$$85]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$85)
                 -- STABLE_SORT [$$85(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    assign [$$82, $$66, $$93, $$85] <- [$$tenk.getField(5), $$tenk.getField(2), $$tenk.getField(3), $$tenk.getField(4)] project: [$$66, $$82, $$93, $$85]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$tenk])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                          data-scan []<-[$$87, $$tenk] <- test.tenk
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.3.plan
index 52403ee..5925fff 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.3.plan
@@ -1,14 +1,28 @@
+distribute result [$$48]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$48] <- [{"cnt": $$51, "sm": $$52}] project: [$$48]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$51, $$52] <- [agg-sql-sum($$54), agg-global-sql-sum($$55)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$54, $$55] <- [agg-sql-count($$38), agg-local-sql-sum($$49)]
           -- AGGREGATE  |PARTITIONED|
+            assign [$$38] <- [1]
             -- ASSIGN  |PARTITIONED|
+              select (gt($$49, 0))
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$49] <- [$$tenk.getField(3)] project: [$$49]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                      data-scan []<-[$$50, $$tenk] <- test.tenk
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.4.plan
index a45aec6..548cfe0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.4.plan
@@ -1,25 +1,44 @@
+distribute result [$$60]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$60] <- [{"two": $$two, "cnt": $$64, "sm": $$65}] project: [$$60]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$two(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$70]  |PARTITIONED|
-                {
+        group by ([$$two := $$70]) decor ([]) {
+                  aggregate [$$64, $$65] <- [agg-sql-sum($$68), agg-global-sql-sum($$69)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$70]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$70]  |PARTITIONED|
-            -- PRE_CLUSTERED_GROUP_BY[$$61]  |PARTITIONED|
-                    {
+            group by ([$$70 := $$61]) decor ([]) {
+                      aggregate [$$68, $$69] <- [agg-sql-count(1), agg-local-sql-sum($$62)]
                       -- AGGREGATE  |LOCAL|
+                        select (gt($$62, 0))
                         -- STREAM_SELECT  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- PRE_CLUSTERED_GROUP_BY[$$61]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$61)
                 -- STABLE_SORT [$$61(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    assign [$$62, $$61] <- [$$tenk.getField(3), $$tenk.getField(2)] project: [$$62, $$61]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$tenk])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                          data-scan []<-[$$63, $$tenk] <- test.tenk
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.5.plan
index 28d7ebb..4cfa640 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.5.plan
@@ -1,63 +1,114 @@
+distribute result [$#2]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$#2])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$192(ASC) ]  |PARTITIONED|
+        order (ASC, $$192)
         -- STABLE_SORT [$$192(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            union ($$243, $$244, $#2) ($$two, $$two, $$192)
             -- UNION_ALL  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$243] <- [cast({"two": $$two, "cnt": $$186, "sm": $$187})] project: [$$243, $$two]
                 -- ASSIGN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$239]  |PARTITIONED|
-                            {
+                    group by ([$$two := $$239]) decor ([]) {
+                              aggregate [$$186, $$187] <- [agg-sql-sum($$237), agg-global-sql-sum($$238)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$239]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$239]  |PARTITIONED|
-                        -- PRE_CLUSTERED_GROUP_BY[$$118]  |PARTITIONED|
-                                {
+                        group by ([$$239 := $$118]) decor ([]) {
+                                  aggregate [$$237, $$238] <- [agg-sql-count(1), agg-local-sql-sum($$120)]
                                   -- AGGREGATE  |LOCAL|
+                                    select (gt($$120, 0))
                                     -- STREAM_SELECT  |LOCAL|
+                                      nested tuple source
                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- PRE_CLUSTERED_GROUP_BY[$$118]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$118)
                             -- STABLE_SORT [$$118(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$120, $$118] <- [$$tenk.getField(3), $$tenk.getField(2)] project: [$$120, $$118]
                                 -- ASSIGN  |PARTITIONED|
+                                  assign [$$tenk] <- [$$tenk] project: [$$tenk]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      replicate
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$tenk])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                              data-scan []<-[$$123, $$tenk] <- test.tenk
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$244] <- [cast({"two": $$two, "cnt": $$188, "sm": $$189})] project: [$$244, $$two]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$188, $$189, $$two])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- SORT_GROUP_BY[$$242]  |PARTITIONED|
-                              {
+                      group by ([$$94 := $$242]) decor ([$$two := $$117]) {
+                                aggregate [$$188, $$189] <- [agg-sql-sum($$240), agg-global-sql-sum($$241)]
                                 -- AGGREGATE  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- SORT_GROUP_BY[$$242]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$242]  |PARTITIONED|
-                          -- PRE_CLUSTERED_GROUP_BY[$$119]  |PARTITIONED|
-                                  {
+                          group by ([$$242 := $$119]) decor ([$$117]) {
+                                    aggregate [$$240, $$241] <- [agg-sql-count(1), agg-local-sql-sum($$121)]
                                     -- AGGREGATE  |LOCAL|
+                                      select (gt($$121, 0))
                                       -- STREAM_SELECT  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
+                                 }
+                          -- PRE_CLUSTERED_GROUP_BY[$$119]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$119)
                               -- STABLE_SORT [$$119(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$119, $$117, $$121] <- [true, null, $$tenk.getField(3)] project: [$$119, $$117, $$121]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      replicate
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$tenk])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                              data-scan []<-[$$123, $$tenk] <- test.tenk
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.6.plan
index 5692b93..f0a897c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.6.plan
@@ -1,24 +1,42 @@
+distribute result [$$123]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$123] <- [{"twothous": $$125, "fivethous": $$135, "tenthous": $$tenk.tenthous, "cnt": $$127, "sm": $$128, "cnt_filter": $$129, "sm_filter": $$130}] project: [$$123]
     -- ASSIGN  |UNPARTITIONED|
-      -- WINDOW  |UNPARTITIONED|
-              {
+      window-aggregate [] <- [] order (ASC, $$tenk.tenthous) frame on (ASC, $$tenk.tenthous) start unbounded end [$$tenk.tenthous] {
+                aggregate [$$130, $$129] <- [agg-sql-sum($$tenk.tenthous), agg-sql-count(1)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  select (eq($$125, 0))
                   -- STREAM_SELECT  |UNPARTITIONED|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |UNPARTITIONED|
-              }
-        -- WINDOW  |UNPARTITIONED|
-                {
+             }
+      -- WINDOW  |UNPARTITIONED|
+        window-aggregate [] <- [] order (ASC, $$tenk.tenthous) frame on (ASC, $$tenk.tenthous) start unbounded end [$$tenk.tenthous] {
+                  aggregate [$$128, $$127] <- [agg-sql-sum($$tenk.tenthous), agg-sql-count(1)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- WINDOW  |UNPARTITIONED|
+          exchange
           -- SORT_MERGE_EXCHANGE [$$tenk.tenthous(ASC) ]  |PARTITIONED|
+            order (ASC, $$tenk.tenthous)
             -- STABLE_SORT [$$tenk.tenthous(ASC)]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (eq($$tenk.getField(7), 0)) project: [$$125, $$135, $$tenk.tenthous]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$135, $$tenk.tenthous, $$125] <- [$$tenk.getField(9), $$tenk.getField(10), $$tenk.getField(8)]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$tenk])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                        data-scan []<-[$$126, $$tenk] <- test.tenk
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.7.plan
index 1b586cb..20cd7fa 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.7.plan
@@ -1,42 +1,69 @@
+distribute result [$$182]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$182] <- [{"twenty": $$twenty, "sm": $$189, "sm_sm": $$193, "sm_sm_where_twenty_lt_10": $$194, "sm_sm_where_sm_lt_3k": $$195}] project: [$$182]
     -- ASSIGN  |UNPARTITIONED|
+      project ([$$twenty, $$189, $$193, $$194, $$195])
       -- STREAM_PROJECT  |UNPARTITIONED|
-        -- WINDOW  |UNPARTITIONED|
-                {
+        window-aggregate [] <- [] order (ASC, $$twenty) frame on (ASC, $$twenty) start unbounded end [$$twenty] {
+                  aggregate [$$195] <- [agg-sql-sum($$188)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    select (lt($$187, 3000))
                     -- STREAM_SELECT  |UNPARTITIONED|
+                      nested tuple source
                       -- NESTED_TUPLE_SOURCE  |UNPARTITIONED|
-                }
+               }
+        -- WINDOW  |UNPARTITIONED|
+          project ([$$twenty, $$189, $$193, $$194, $$188, $$187])
           -- STREAM_PROJECT  |UNPARTITIONED|
-            -- WINDOW  |UNPARTITIONED|
-                    {
+            window-aggregate [] <- [] order (ASC, $$twenty) frame on (ASC, $$twenty) start unbounded end [$$twenty] {
+                      aggregate [$$194] <- [agg-sql-sum($$186)]
                       -- AGGREGATE  |UNPARTITIONED|
+                        select (lt($$twenty, 10))
                         -- STREAM_SELECT  |UNPARTITIONED|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |UNPARTITIONED|
-                    }
+                   }
+            -- WINDOW  |UNPARTITIONED|
+              project ([$$twenty, $$189, $$193, $$188, $$187, $$186])
               -- STREAM_PROJECT  |UNPARTITIONED|
-                -- WINDOW  |UNPARTITIONED|
-                        {
+                window-aggregate [] <- [] order (ASC, $$twenty) frame on (ASC, $$twenty) start unbounded end [$$twenty] {
+                          aggregate [$$193] <- [agg-sql-sum($$185)]
                           -- AGGREGATE  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- WINDOW  |UNPARTITIONED|
+                  exchange
                   -- SORT_MERGE_EXCHANGE [$$twenty(ASC) ]  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$201]  |PARTITIONED|
-                            {
+                    group by ([$$twenty := $$201]) decor ([]) {
+                              aggregate [$$185, $$186, $$187, $$188, $$189] <- [agg-global-sql-sum($$196), agg-global-sql-sum($$197), agg-global-sql-sum($$198), agg-global-sql-sum($$199), agg-global-sql-sum($$200)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$201]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$201]  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$183]  |PARTITIONED|
-                                {
+                        group by ([$$201 := $$183]) decor ([]) {
+                                  aggregate [$$196, $$197, $$198, $$199, $$200] <- [agg-local-sql-sum($$125), agg-local-sql-sum($$125), agg-local-sql-sum($$125), agg-local-sql-sum($$125), agg-local-sql-sum($$125)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$183]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$125, $$183] <- [$$tenk.getField(4), $$tenk.getField(5)] project: [$$125, $$183]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$tenk])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                  data-scan []<-[$$184, $$tenk] <- test.tenk
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.8.plan
index fd9f30c..d7aca6d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.8.plan
@@ -1,26 +1,46 @@
+distribute result [$$69]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$69] <- [{"two": $$two, "sm": $$72}] project: [$$69]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$two(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$70]  |PARTITIONED|
-                {
+        group by ([$$two := $$70]) decor ([]) {
+                  aggregate [$$72] <- [agg-sql-sum($$74)]
                   -- AGGREGATE  |LOCAL|
+                    select ($$64)
                     -- STREAM_SELECT  |LOCAL|
-                      -- SUBPLAN  |LOCAL|
-                              {
+                      subplan {
+                                aggregate [$$64] <- [empty-stream()]
                                 -- AGGREGATE  |LOCAL|
+                                  select (not(if-missing-or-null(gt($$x, 0), false)))
                                   -- STREAM_SELECT  |LOCAL|
+                                    unnest $$x <- scan-collection(ordered-list-constructor($$74, numeric-add($$74, $$74)))
                                     -- UNNEST  |LOCAL|
+                                      nested tuple source
                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- SUBPLAN  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$70]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$70)
             -- STABLE_SORT [$$70(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$70]  |PARTITIONED|
+                assign [$$74, $$70] <- [$$tenk.getField(3), $$tenk.getField(2)] project: [$$74, $$70]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                      data-scan []<-[$$71, $$tenk] <- test.tenk
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.9.plan
index 52403ee..1ee0304 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.9.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate-subclause/agg_filter_01/agg_filter_01.9.plan
@@ -1,14 +1,28 @@
+distribute result [$$72]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$72] <- [{"cnt": $$75, "min2": $$76, "max2": $$77, "sum20": $$78}] project: [$$72]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$75, $$76, $$77, $$78] <- [agg-sql-sum($$80), agg-global-sql-min($$81), agg-global-sql-max($$82), agg-global-sql-sum($$83)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$80, $$81, $$82, $$83] <- [agg-sql-count($$46), agg-local-sql-min($$54), agg-local-sql-max($$54), agg-local-sql-sum($$70)]
           -- AGGREGATE  |PARTITIONED|
+            assign [$$46] <- [1]
             -- ASSIGN  |PARTITIONED|
+              select (gt($$tenk.getField(3), 0)) project: [$$70, $$54]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$70, $$54] <- [$$tenk.getField(5), $$tenk.getField(2)]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                      data-scan []<-[$$74, $$tenk] <- test.tenk
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/constant-agg.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/constant-agg.plan
index 33300f5..d88cf12 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/constant-agg.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/constant-agg.plan
@@ -1,10 +1,20 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$33] <- [{"count": $$35}] project: [$$33]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$35] <- [agg-sql-sum($$36)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$36] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+              data-scan []<-[$$34, $$u] <- TinySocial.FacebookUsers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/constant-gby-agg.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/constant-gby-agg.plan
index fd2f29d..2af4bc2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/constant-gby-agg.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/constant-gby-agg.plan
@@ -1,22 +1,38 @@
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"alias": $$alias, "count": $$48}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- SORT_GROUP_BY[$$50]  |PARTITIONED|
-                {
+        group by ([$$alias := $$50]) decor ([]) {
+                  aggregate [$$48] <- [agg-sql-sum($$49)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$50]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$50]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$46]  |PARTITIONED|
-                    {
+            group by ([$$50 := $$46]) decor ([]) {
+                      aggregate [$$49] <- [agg-sql-count(1)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$46]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$46] <- [$$u.getField("alias")] project: [$$46]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$u])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+                      data-scan []<-[$$47, $$u] <- TinySocial.FacebookUsers
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/count-dataset.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/count-dataset.plan
index 6318801..9bc4be3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/count-dataset.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/count-dataset.plan
@@ -1,9 +1,18 @@
+distribute result [$$7]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    aggregate [$$7] <- [agg-sum($$8)]
     -- AGGREGATE  |UNPARTITIONED|
+      exchange
       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+        aggregate [$$8] <- [agg-count(1)]
         -- AGGREGATE  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+            data-scan []<-[$$6, $$4] <- TinySocial.FacebookUsers
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/list-dataset.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/list-dataset.plan
index 1b428e7..cb245b9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/list-dataset.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/list-dataset.plan
@@ -1,9 +1,18 @@
+distribute result [$$4]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    aggregate [$$4] <- [listify($$3)]
     -- AGGREGATE  |UNPARTITIONED|
+      exchange
       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+        project ([$$3])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+            data-scan []<-[$$5, $$3] <- TinySocial.FacebookUsers
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/query-ASTERIXDB-1626-2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/query-ASTERIXDB-1626-2.plan
index 46a1291..bc7a301 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/query-ASTERIXDB-1626-2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/query-ASTERIXDB-1626-2.plan
@@ -1,13 +1,26 @@
+distribute result [$$46]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$46] <- [{"total": numeric-multiply($$48, $$49)}] project: [$$46]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$48, $$49] <- [agg-sql-sum($$51), agg-global-sql-avg($$52)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$51, $$52] <- [agg-sql-count($$37), agg-local-sql-avg($$43)]
           -- AGGREGATE  |PARTITIONED|
+            assign [$$43] <- [count($$37)]
             -- ASSIGN  |PARTITIONED|
+              assign [$$37] <- [$$FacebookUsers.getField("friend-ids")] project: [$$37]
               -- ASSIGN  |PARTITIONED|
+                project ([$$FacebookUsers])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+                    data-scan []<-[$$47, $$FacebookUsers] <- TinySocial.FacebookUsers
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/query-ASTERIXDB-1626-3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/query-ASTERIXDB-1626-3.plan
index 46a1291..a327c96 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/query-ASTERIXDB-1626-3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/query-ASTERIXDB-1626-3.plan
@@ -1,13 +1,26 @@
+distribute result [$$60]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$60] <- [{"total": numeric-multiply($$62, $$63), "t": 1}] project: [$$60]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$62, $$63] <- [agg-sql-sum($$65), agg-global-sql-avg($$66)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$65, $$66] <- [agg-sql-count($$51), agg-local-sql-avg($$57)]
           -- AGGREGATE  |PARTITIONED|
+            assign [$$57] <- [count($$51)]
             -- ASSIGN  |PARTITIONED|
+              assign [$$51] <- [$$FacebookUsers.getField("friend-ids")] project: [$$51]
               -- ASSIGN  |PARTITIONED|
+                project ([$$FacebookUsers])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+                    data-scan []<-[$$61, $$FacebookUsers] <- TinySocial.FacebookUsers
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/query-ASTERIXDB-1626.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/query-ASTERIXDB-1626.plan
index 46a1291..d568c99 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/query-ASTERIXDB-1626.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/query-ASTERIXDB-1626.plan
@@ -1,13 +1,26 @@
+distribute result [$$47]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$47] <- [{"$1": $$49, "$2": $$50}] project: [$$47]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$49, $$50] <- [agg-sql-sum($$52), agg-global-sql-avg($$53)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$52, $$53] <- [agg-sql-count($$39), agg-local-sql-avg($$45)]
           -- AGGREGATE  |PARTITIONED|
+            assign [$$45] <- [count($$39)]
             -- ASSIGN  |PARTITIONED|
+              assign [$$39] <- [$$FacebookUsers.getField("friend-ids")] project: [$$39]
               -- ASSIGN  |PARTITIONED|
+                project ([$$FacebookUsers])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+                    data-scan []<-[$$48, $$FacebookUsers] <- TinySocial.FacebookUsers
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/serial-agg.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/serial-agg.plan
index 9de2dc1..7481ff2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/serial-agg.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/aggregate/serial-agg.plan
@@ -1,22 +1,38 @@
+distribute result [$$47]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$47] <- [{"gid": $$gid, "stddev": $$50}] project: [$$47]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- EXTERNAL_GROUP_BY[$$53]  |PARTITIONED|
-                {
+        group by ([$$gid := $$53]) decor ([]) {
+                  aggregate [$$50] <- [global-sql-stddev-serial_samp($$52)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- EXTERNAL_GROUP_BY[$$53]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$53]  |PARTITIONED|
-            -- EXTERNAL_GROUP_BY[$$48]  |PARTITIONED|
-                    {
+            group by ([$$53 := $$48]) decor ([]) {
+                      aggregate [$$52] <- [local-sql-stddev-serial_samp($$45)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- EXTERNAL_GROUP_BY[$$48]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$45, $$48] <- [$$t.getField(2), $$t.getField(1)] project: [$$45, $$48]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.Test)  |PARTITIONED|
+                      data-scan []<-[$$49, $$t] <- test.Test
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/any-and-every-1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/any-and-every-1.plan
index 6efb86d..6ab4db5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/any-and-every-1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/any-and-every-1.plan
@@ -1,17 +1,31 @@
+distribute result [$$30]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$30] <- [{"D": $$D}] project: [$$30]
     -- ASSIGN  |PARTITIONED|
+      select (and($$26, eq($$27, 0))) project: [$$D]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D, $$26, $$27])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$26, $$27] <- [non-empty-stream(), agg-sql-count(switch-case(eq($$I, 1), true, null, true))]
                     -- AGGREGATE  |LOCAL|
+                      unnest $$I <- scan-collection($$32)
                       -- UNNEST  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$32] <- [$$D.getField("items")]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TestDataverse.Dataset1)  |PARTITIONED|
+                  data-scan []<-[$$31, $$D] <- TestDataverse.Dataset1
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/any-and-every-2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/any-and-every-2.plan
index e85b511..981d916 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/any-and-every-2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/any-and-every-2.plan
@@ -1,24 +1,42 @@
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"D": $$D}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      select (and($$41, eq($$42, 0))) project: [$$D]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D, $$41, $$42])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$41, $$42] <- [non-empty-stream(), agg-sql-count(switch-case(and($$38, eq($$39, 0)), true, null, true))]
                     -- AGGREGATE  |LOCAL|
-                      -- SUBPLAN  |LOCAL|
-                              {
+                      subplan {
+                                aggregate [$$38, $$39] <- [non-empty-stream(), agg-sql-count(switch-case(eq($$J, 1), true, null, true))]
                                 -- AGGREGATE  |LOCAL|
+                                  unnest $$J <- scan-collection($$48)
                                   -- UNNEST  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- SUBPLAN  |LOCAL|
+                        assign [$$48] <- [$$I.getField("items")]
                         -- ASSIGN  |LOCAL|
+                          unnest $$I <- scan-collection($$47)
                           -- UNNEST  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$47] <- [$$D.getField("items")]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TestDataverse.Dataset1)  |PARTITIONED|
+                  data-scan []<-[$$46, $$D] <- TestDataverse.Dataset1
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/any-and-every-3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/any-and-every-3.plan
index aaac121..3c577a8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/any-and-every-3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/any-and-every-3.plan
@@ -1,18 +1,33 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"D": $$D}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      select (and($$40, eq($$41, 0))) project: [$$D]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D, $$40, $$41])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$40, $$41] <- [non-empty-stream(), agg-sql-count(switch-case(and(eq($$I, 1), eq($$J, 2)), true, null, true))]
                     -- AGGREGATE  |LOCAL|
+                      unnest $$J <- scan-collection($$47)
                       -- UNNEST  |LOCAL|
+                        unnest $$I <- scan-collection($$46)
                         -- UNNEST  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$47, $$46] <- [$$D.getField("other_items"), $$D.getField("items")]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TestDataverse.Dataset1)  |PARTITIONED|
+                  data-scan []<-[$$45, $$D] <- TestDataverse.Dataset1
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query1.plan
index ed2e3eb..181b717 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query1.plan
@@ -1,21 +1,42 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"D": $$D, "DI": $$DI}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq($$DI.getField("field2"), 2), eq($$DI.getField("field3"), 3)))
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$DI <- scan-collection($$39) project: [$$D, $$DI]
         -- UNNEST  |PARTITIONED|
+          select (and(eq($$D.getField("field1"), 1), eq($$D.getField("field4"), 4)))
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$39] <- [$$D.getField("items")]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$36, $$D] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$54, 1, $$54, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$54])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$54)
                           -- STABLE_SORT [$$54(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$54])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                  unnest-map [$$50, $$51, $$52, $$53, $$54] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", false, false, 4, $$42, $$43, $$44, $$45, 4, $$46, $$47, $$48, $$49, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$42, $$43, $$44, $$45, $$46, $$47, $$48, $$49] <- [1, 2, 3, 4, 1, 2, 3, 4]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query2.plan
index 4e34538..f0a8a6c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query2.plan
@@ -1,21 +1,42 @@
+distribute result [$$39]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$39] <- [{"D": $$D, "DI": $$DI}] project: [$$39]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq($$DI.getField("field2"), 2), eq($$DI.getField("field3"), 3), eq($$DI.getField("field3_notindexed"), 3)))
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$DI <- scan-collection($$44) project: [$$D, $$DI]
         -- UNNEST  |PARTITIONED|
+          select (and(eq($$D.getField("field4"), 4), eq($$D.getField("field1"), 1), eq($$D.getField("field4_notindexed"), 4)))
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$44] <- [$$D.getField("items")]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$40, $$D] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$60, 1, $$60, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$60])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$60)
                           -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$60])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                  unnest-map [$$56, $$57, $$58, $$59, $$60] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", false, false, 4, $$48, $$49, $$50, $$51, 4, $$52, $$53, $$54, $$55, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$48, $$49, $$50, $$51, $$52, $$53, $$54, $$55] <- [1, 2, 3, 4, 1, 2, 3, 4]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query3.plan
index c4fc356..f86f3cf 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query3.plan
@@ -1,24 +1,48 @@
+distribute result [$$51]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$51] <- [{"D": $$D, "DOI": $$DOI, "DII": $$DII}] project: [$$51]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq($$DII.getField("field2"), 2), eq($$DII.getField("field3"), 3), eq($$DII.getField("field3_notindexed"), 3)))
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$DII <- scan-collection($$57) project: [$$D, $$DOI, $$DII]
         -- UNNEST  |PARTITIONED|
+          select (eq($$DOI.getField("field2_notindexed"), 2))
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$57] <- [$$DOI.getField("inner_items")]
             -- ASSIGN  |PARTITIONED|
+              unnest $$DOI <- scan-collection($$55) project: [$$D, $$DOI]
               -- UNNEST  |PARTITIONED|
+                select (and(eq($$D.getField("field1"), 1), eq($$D.getField("field4"), 4)))
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$55] <- [$$D.getField("outer_items")]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$D])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                        unnest-map [$$52, $$D] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$73, 1, $$73, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            distinct ([$$73])
                             -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$73)
                                 -- STABLE_SORT [$$73(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$73])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                        unnest-map [$$69, $$70, $$71, $$72, $$73] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", false, false, 4, $$61, $$62, $$63, $$64, 4, $$65, $$66, $$67, $$68, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$61, $$62, $$63, $$64, $$65, $$66, $$67, $$68] <- [1, 2, 3, 4, 1, 2, 3, 4]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query4.plan
index ed5677d..e794791 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query4.plan
@@ -1,29 +1,55 @@
+distribute result [$$37]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$37] <- [{"D": $$D}] project: [$$37]
     -- ASSIGN  |PARTITIONED|
+      select ($$32) project: [$$D]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D, $$32])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$32] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (and(eq($$43, 2), eq($$42, 3)))
                       -- STREAM_SELECT  |LOCAL|
+                        assign [$$43, $$42] <- [$$DI.getField("field2"), $$DI.getField("field3")]
                         -- ASSIGN  |LOCAL|
+                          unnest $$DI <- scan-collection($$41)
                           -- UNNEST  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            select (and(eq($$D.getField("field1"), 1), eq($$D.getField("field4"), 4)))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$41] <- [$$D.getField("items")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$D])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                    unnest-map [$$38, $$D] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$56, 1, $$56, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$56])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$56)
                             -- STABLE_SORT [$$56(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$56])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                    unnest-map [$$52, $$53, $$54, $$55, $$56] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", false, false, 4, $$44, $$45, $$46, $$47, 4, $$48, $$49, $$50, $$51, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$44, $$45, $$46, $$47, $$48, $$49, $$50, $$51] <- [1, 2, 3, 4, 1, 2, 3, 4]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query5.plan
index 21e5109..310f454 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query5.plan
@@ -1,38 +1,70 @@
+distribute result [$$55]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$55] <- [{"D": $$D}] project: [$$55]
     -- ASSIGN  |PARTITIONED|
+      select ($$50) project: [$$D]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D, $$50])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$50] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select ($$48)
                       -- STREAM_SELECT  |LOCAL|
-                        -- SUBPLAN  |LOCAL|
-                                {
+                        subplan {
+                                  aggregate [$$48] <- [non-empty-stream()]
                                   -- AGGREGATE  |LOCAL|
+                                    select (and(eq($$64, 2), eq($$63, 3), eq($$62, 3)))
                                     -- STREAM_SELECT  |LOCAL|
+                                      assign [$$64, $$63, $$62] <- [$$DII.getField("field2"), $$DII.getField("field3"), $$DII.getField("field3_notindexed")]
                                       -- ASSIGN  |LOCAL|
+                                        unnest $$DII <- scan-collection($$61)
                                         -- UNNEST  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SUBPLAN  |LOCAL|
+                          select (eq($$60, 2))
                           -- STREAM_SELECT  |LOCAL|
+                            assign [$$61, $$60] <- [$$DOI.getField("inner_items"), $$DOI.getField("field2_notindexed")]
                             -- ASSIGN  |LOCAL|
+                              unnest $$DOI <- scan-collection($$59)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            select (and(eq($$D.getField("field1"), 1), eq($$D.getField("field4"), 4)))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$59] <- [$$D.getField("outer_items")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$D])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                    unnest-map [$$56, $$D] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$79, 1, $$79, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$79])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$79)
                             -- STABLE_SORT [$$79(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$79])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                    unnest-map [$$75, $$76, $$77, $$78, $$79] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", false, false, 4, $$67, $$68, $$69, $$70, 4, $$71, $$72, $$73, $$74, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$67, $$68, $$69, $$70, $$71, $$72, $$73, $$74] <- [1, 2, 3, 4, 1, 2, 3, 4]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query6.plan
index 57502ba..95d34b0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query6.plan
@@ -1,28 +1,56 @@
+distribute result [$$73]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$73] <- [{"D2": $$D2, "D1IV": {"field1": $$89, "field2": $$90, "field3": $$91, "field4": $$92}}] project: [$$73]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq($$90, $$77), eq($$91, $$79), eq($$92, $$81), eq($$89, $$83))) project: [$$D2, $$92, $$89, $$91, $$90]
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$91, $$90] <- [$$D1I.getField("field3"), $$D1I.getField("field2")] project: [$$D2, $$83, $$81, $$79, $$77, $$92, $$89, $$91, $$90]
         -- ASSIGN  |PARTITIONED|
+          unnest $$D1I <- scan-collection($$88) project: [$$D2, $$83, $$81, $$79, $$77, $$92, $$89, $$D1I]
           -- UNNEST  |PARTITIONED|
+            assign [$$92, $$89, $$88] <- [$$D1.getField("field4"), $$D1.getField("field1"), $$D1.getField("items")] project: [$$D2, $$83, $$81, $$79, $$77, $$92, $$89, $$88]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D2, $$83, $$81, $$79, $$77, $$D1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$75, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", true, false, 1, $$97, 1, $$97, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$97, $$D2, $$83, $$81, $$79, $$77])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$97, $$98])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$97) (ASC, $$98)
                               -- STABLE_SORT [$$97(ASC), $$98(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$D2, $$83, $$81, $$79, $$77, $$98, $$97])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                      unnest-map [$$93, $$94, $$95, $$96, $$97] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", true, true, 4, $$83, $$77, $$79, $$81, 4, $$83, $$77, $$79, $$81, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          running-aggregate [$$98] <- [create-query-uid()]
                                           -- RUNNING_AGGREGATE  |PARTITIONED|
+                                            assign [$$83, $$81, $$79, $$77] <- [to-bigint($$D2.getField("field1")), to-bigint($$D2.getField("field4")), to-bigint($$D2.getField("field3")), to-bigint($$D2.getField("field2"))]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$D2])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (TestDataverse.Dataset2)  |PARTITIONED|
+                                                  data-scan []<-[$$74, $$D2] <- TestDataverse.Dataset2
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query7.plan
index 65775fc..f3fce2e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query7.plan
@@ -1,28 +1,56 @@
+distribute result [$$83]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$83] <- [{"D2": $$D2, "D1IV": {"field1_notindexed": $$105, "field1": $$106, "field2": $$107, "field3": $$108, "field3_notindexed": $$109, "field4": $$110}}] project: [$$83]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq($$105, $$87), eq($$107, $$89), eq($$108, $$91), eq($$109, $$93), eq($$110, $$95), eq($$106, $$97))) project: [$$D2, $$110, $$106, $$105, $$109, $$108, $$107]
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$109, $$108, $$107] <- [$$D1I.getField("field3_notindexed"), $$D1I.getField("field3"), $$D1I.getField("field2")] project: [$$D2, $$97, $$95, $$93, $$91, $$89, $$87, $$110, $$106, $$105, $$109, $$108, $$107]
         -- ASSIGN  |PARTITIONED|
+          unnest $$D1I <- scan-collection($$104) project: [$$D2, $$97, $$95, $$93, $$91, $$89, $$87, $$110, $$106, $$105, $$D1I]
           -- UNNEST  |PARTITIONED|
+            assign [$$110, $$106, $$105, $$104] <- [$$D1.getField("field4"), $$D1.getField("field1"), $$D1.getField("field1_notindexed"), $$D1.getField("items")] project: [$$D2, $$97, $$95, $$93, $$91, $$89, $$87, $$110, $$106, $$105, $$104]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D2, $$97, $$95, $$93, $$91, $$89, $$87, $$D1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$85, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", true, false, 1, $$115, 1, $$115, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$115, $$D2, $$97, $$95, $$93, $$91, $$89, $$87])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$115, $$116])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$115) (ASC, $$116)
                               -- STABLE_SORT [$$115(ASC), $$116(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$D2, $$97, $$95, $$93, $$91, $$89, $$87, $$116, $$115])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                      unnest-map [$$111, $$112, $$113, $$114, $$115] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", true, true, 4, $$97, $$89, $$91, $$95, 4, $$97, $$89, $$91, $$95, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          running-aggregate [$$116] <- [create-query-uid()]
                                           -- RUNNING_AGGREGATE  |PARTITIONED|
+                                            assign [$$97, $$95, $$93, $$91, $$89, $$87] <- [to-bigint($$D2.getField("field1")), to-bigint($$D2.getField("field4")), to-bigint($$D2.getField("field3_notindexed")), to-bigint($$D2.getField("field3")), to-bigint($$D2.getField("field2")), to-bigint($$D2.getField("field1_notindexed"))]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$D2])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (TestDataverse.Dataset2)  |PARTITIONED|
+                                                  data-scan []<-[$$84, $$D2] <- TestDataverse.Dataset2
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query8.plan
index 9bf272a..4b4bbc4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query8.plan
@@ -1,36 +1,69 @@
+distribute result [$$57]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$57] <- [{"D2": $$D2, "D1": $$D1}] project: [$$57]
     -- ASSIGN  |PARTITIONED|
+      select ($$50) project: [$$D2, $$D1]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D2, $$D1, $$50])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$50] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (and(eq($$69, to-bigint($$70)), eq($$67, to-bigint($$68))))
                       -- STREAM_SELECT  |LOCAL|
+                        assign [$$69, $$67] <- [$$D1I.getField("field2"), $$D1I.getField("field3")]
                         -- ASSIGN  |LOCAL|
+                          unnest $$D1I <- scan-collection($$66)
                           -- UNNEST  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$66] <- [$$D1.getField("items")]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D2, $$70, $$68, $$D1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$59, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", true, false, 1, $$77, 1, $$77, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$77, $$D2, $$70, $$68])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$77, $$78])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$77) (ASC, $$78)
                               -- STABLE_SORT [$$77(ASC), $$78(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$D2, $$70, $$68, $$77, $$78])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                      unnest-map [$$73, $$74, $$75, $$76, $$77] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", true, true, 4, $$61, $$71, $$72, $$63, 4, $$61, $$71, $$72, $$63, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          running-aggregate [$$78] <- [create-query-uid()]
                                           -- RUNNING_AGGREGATE  |PARTITIONED|
+                                            assign [$$72, $$71] <- [to-bigint($$68), to-bigint($$70)]
                                             -- ASSIGN  |PARTITIONED|
+                                              assign [$$63, $$61, $$70, $$68] <- [to-bigint($$D2.getField("field4")), to-bigint($$D2.getField("field1")), $$D2.getField("field2"), $$D2.getField("field3")]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$D2])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (TestDataverse.Dataset2)  |PARTITIONED|
+                                                    data-scan []<-[$$58, $$D2] <- TestDataverse.Dataset2
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query9.plan
index ab7ffda..a95a723 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query9.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/atomic-and-array-queries/query9.plan
@@ -1,45 +1,84 @@
+distribute result [$$79]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$79] <- [{"D2": $$D2, "D1": $$D1}] project: [$$79]
     -- ASSIGN  |PARTITIONED|
+      select ($$72) project: [$$D2, $$D1]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D2, $$D1, $$72])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$72] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select ($$70)
                       -- STREAM_SELECT  |LOCAL|
-                        -- SUBPLAN  |LOCAL|
-                                {
+                        subplan {
+                                  aggregate [$$70] <- [non-empty-stream()]
                                   -- AGGREGATE  |LOCAL|
+                                    select (and(eq($$96, to-bigint($$97)), eq($$94, to-bigint($$95)), eq($$92, to-bigint($$93))))
                                     -- STREAM_SELECT  |LOCAL|
+                                      assign [$$96, $$94, $$92] <- [$$DII.getField("field2"), $$DII.getField("field3"), $$DII.getField("field3_notindexed")]
                                       -- ASSIGN  |LOCAL|
+                                        unnest $$DII <- scan-collection($$91)
                                         -- UNNEST  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SUBPLAN  |LOCAL|
+                          select (eq($$89, to-bigint($$90)))
                           -- STREAM_SELECT  |LOCAL|
+                            assign [$$91, $$89] <- [$$DOI.getField("inner_items"), $$DOI.getField("field2_notindexed")]
                             -- ASSIGN  |LOCAL|
+                              unnest $$DOI <- scan-collection($$88)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$88] <- [$$D1.getField("outer_items")]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D2, $$97, $$95, $$93, $$90, $$D1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$81, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", true, false, 1, $$108, 1, $$108, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$108, $$D2, $$97, $$95, $$93, $$90])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$108, $$109])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$108) (ASC, $$109)
                               -- STABLE_SORT [$$108(ASC), $$109(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$D2, $$97, $$95, $$93, $$90, $$108, $$109])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                      unnest-map [$$104, $$105, $$106, $$107, $$108] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", true, true, 4, $$83, $$100, $$101, $$85, 4, $$83, $$100, $$101, $$85, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          running-aggregate [$$109] <- [create-query-uid()]
                                           -- RUNNING_AGGREGATE  |PARTITIONED|
+                                            assign [$$101, $$100] <- [to-bigint($$95), to-bigint($$97)]
                                             -- ASSIGN  |PARTITIONED|
+                                              assign [$$85, $$83, $$97, $$95, $$93, $$90] <- [to-bigint($$D2.getField("field4")), to-bigint($$D2.getField("field1")), $$D2.getField("field2"), $$D2.getField("field3"), $$D2.getField("field3_notindexed"), $$D2.getField("field2_notindexed")]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$D2])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (TestDataverse.Dataset2)  |PARTITIONED|
+                                                    data-scan []<-[$$80, $$D2] <- TestDataverse.Dataset2
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query1.plan
index 9526cce..5e1aacb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query1.plan
@@ -1,36 +1,69 @@
+distribute result [$$55]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$55] <- [{"$1": $$58}] project: [$$55]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$58] <- [agg-sql-sum($$62)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$62] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$45)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$45])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$45] <- [non-empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select (eq($$61, $#4))
                             -- STREAM_SELECT  |LOCAL|
+                              unnest $#4 <- scan-collection($$60)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  select (eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg")) project: [$$61, $$60]
                   -- STREAM_SELECT  |PARTITIONED|
+                    assign [$$60] <- [$$C.getField(2)]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$61, $$C])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                          unnest-map [$$57, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$64, 1, $$64, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$64, $$61])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  distinct ([$$64, $$56])
                                   -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$64) (ASC, $$56)
                                       -- STABLE_SORT [$$64(ASC), $$56(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$56, $$61, $$64])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                              unnest-map [$$63, $$64] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$61, 1, $$61, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                  assign [$$61] <- [$$M.getField(2)] project: [$$56, $$61]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                      data-scan []<-[$$56, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query2.plan
index 90476c2..bb28529 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query2.plan
@@ -1,36 +1,69 @@
+distribute result [$$64]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$64] <- [{"$1": $$67}] project: [$$64]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$67] <- [agg-sql-sum($$71)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$71] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$56)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$56])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$56] <- [non-empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select (eq($$70, $$D))
                             -- STREAM_SELECT  |LOCAL|
+                              unnest $$D <- scan-collection($$69)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  select (eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg")) project: [$$70, $$69]
                   -- STREAM_SELECT  |PARTITIONED|
+                    assign [$$69] <- [$$C.getField(2)]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$70, $$C])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                          unnest-map [$$66, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$73, 1, $$73, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$73, $$70])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  distinct ([$$73, $$65])
                                   -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$73) (ASC, $$65)
                                       -- STABLE_SORT [$$73(ASC), $$65(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$65, $$70, $$73])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                              unnest-map [$$72, $$73] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$70, 1, $$70, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                  assign [$$70] <- [$$M.getField(2)] project: [$$65, $$70]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                      data-scan []<-[$$65, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query3.plan
index e2e4669..bcd2bd8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query3.plan
@@ -1,36 +1,69 @@
+distribute result [$$67]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$67] <- [{"$1": $$70}] project: [$$67]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$70] <- [agg-sql-sum($$75)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$75] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$59)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$59])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$59] <- [empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select (not(if-missing-or-null(eq($$74, $$D), false)))
                             -- STREAM_SELECT  |LOCAL|
+                              unnest $$D <- scan-collection($$72)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  select (and(gt(len($$72), 0), eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg"))) project: [$$74, $$72]
                   -- STREAM_SELECT  |PARTITIONED|
+                    assign [$$72] <- [$$C.getField(2)]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$74, $$C])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                          unnest-map [$$69, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$77, 1, $$77, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$77, $$74])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  distinct ([$$77, $$68])
                                   -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$77) (ASC, $$68)
                                       -- STABLE_SORT [$$77(ASC), $$68(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$68, $$74, $$77])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                              unnest-map [$$76, $$77] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$74, 1, $$74, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                  assign [$$74] <- [$$M.getField(2)] project: [$$68, $$74]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                      data-scan []<-[$$68, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query4.plan
index b8e4112..9a50d42 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query4.plan
@@ -1,60 +1,114 @@
+distribute result [$$71]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$71] <- [{"$1": $$75}] project: [$$71]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$75] <- [agg-sql-sum($$80)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$80] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$63)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$63])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$63] <- [non-empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select (eq($$77, $#5))
                             -- STREAM_SELECT  |LOCAL|
+                              unnest $#5 <- scan-collection($$78)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  assign [$$78] <- [$$B.getField(2)] project: [$$77, $$78]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$77, $$B])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (TestYelp.YelpCheckinB.YelpCheckinB)  |PARTITIONED|
+                        unnest-map [$$74, $$B] <- index-search("YelpCheckinB", 0, "Default", "TestYelp", "YelpCheckinB", true, false, 1, $$84, 1, $$84, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$84, $$77])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                distinct ([$$84, $$85])
                                 -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$84) (ASC, $$85)
                                     -- STABLE_SORT [$$84(ASC), $$85(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        project ([$$77, $$85, $$84])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- BTREE_SEARCH (TestYelp.YelpCheckinB.IdxYelpCheckinBDates)  |PARTITIONED|
+                                            unnest-map [$$83, $$84] <- index-search("IdxYelpCheckinBDates", 0, "Default", "TestYelp", "YelpCheckinB", true, true, 1, $$77, 1, $$77, true, true, true)
+                                            -- BTREE_SEARCH  |PARTITIONED|
+                                              exchange
                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                running-aggregate [$$85] <- [create-query-uid()]
                                                 -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                  select ($$59) project: [$$77]
                                                   -- STREAM_SELECT  |PARTITIONED|
+                                                    project ([$$77, $$59])
                                                     -- STREAM_PROJECT  |PARTITIONED|
-                                                      -- SUBPLAN  |PARTITIONED|
-                                                              {
+                                                      subplan {
+                                                                aggregate [$$59] <- [non-empty-stream()]
                                                                 -- AGGREGATE  |LOCAL|
+                                                                  select (eq($$77, $#4))
                                                                   -- STREAM_SELECT  |LOCAL|
+                                                                    unnest $#4 <- scan-collection($$76)
                                                                     -- UNNEST  |LOCAL|
+                                                                      nested tuple source
                                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                              }
+                                                             }
+                                                      -- SUBPLAN  |PARTITIONED|
+                                                        assign [$$76] <- [$$A.getField(2)] project: [$$77, $$76]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          project ([$$77, $$A])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (TestYelp.YelpCheckinA.YelpCheckinA)  |PARTITIONED|
+                                                              unnest-map [$$73, $$A] <- index-search("YelpCheckinA", 0, "Default", "TestYelp", "YelpCheckinA", true, false, 1, $$82, 1, $$82, true, true, true)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  project ([$$82, $$77])
                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      distinct ([$$82, $$72])
                                                                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          order (ASC, $$82) (ASC, $$72)
                                                                           -- STABLE_SORT [$$82(ASC), $$72(ASC)]  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              project ([$$72, $$77, $$82])
                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- BTREE_SEARCH (TestYelp.YelpCheckinA.IdxYelpCheckinADates)  |PARTITIONED|
+                                                                                  unnest-map [$$81, $$82] <- index-search("IdxYelpCheckinADates", 0, "Default", "TestYelp", "YelpCheckinA", true, true, 1, $$77, 1, $$77, true, true, true)
+                                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                      assign [$$77] <- [$$M.getField(2)] project: [$$72, $$77]
                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                          -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                                                          data-scan []<-[$$72, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              empty-tuple-source
                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query5.plan
index d6a912e..af39183 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-1/query5.plan
@@ -1,35 +1,67 @@
+distribute result [$$66]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$66] <- [{"$1": $$69}] project: [$$66]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$69] <- [agg-sql-sum($$73)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$73] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and($$56, eq($$57, 0)))
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$56, $$57])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$56, $$57] <- [non-empty-stream(), agg-sql-count(switch-case(eq($$72, $$D), true, null, true))]
                           -- AGGREGATE  |LOCAL|
+                            unnest $$D <- scan-collection($$71)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  select (eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg")) project: [$$72, $$71]
                   -- STREAM_SELECT  |PARTITIONED|
+                    assign [$$71] <- [$$C.getField(2)]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$72, $$C])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                          unnest-map [$$68, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$75, 1, $$75, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$75, $$72])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  distinct ([$$75, $$67])
                                   -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$75) (ASC, $$67)
                                       -- STABLE_SORT [$$75(ASC), $$67(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$67, $$72, $$75])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                              unnest-map [$$74, $$75] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$72, 1, $$72, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                  assign [$$72] <- [$$M.getField(2)] project: [$$67, $$72]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                      data-scan []<-[$$67, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-2/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-2/query1.plan
index 5832cff..bcdf9fd 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-2/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-2/query1.plan
@@ -1,36 +1,69 @@
+distribute result [$$56]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$56] <- [{"$1": $$59}] project: [$$56]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$59] <- [agg-sql-sum($$64)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$64] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$46)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$46])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$46] <- [non-empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select (eq($$62, $#4))
                             -- STREAM_SELECT  |LOCAL|
+                              unnest $#4 <- scan-collection($$61)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  assign [$$61] <- [$$C.getField(2).getField(0)] project: [$$62, $$61]
                   -- ASSIGN  |PARTITIONED|
+                    select (eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      project ([$$62, $$C])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                          unnest-map [$$58, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$66, 1, $$66, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$66, $$62])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  distinct ([$$66, $$57])
                                   -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$66) (ASC, $$57)
                                       -- STABLE_SORT [$$66(ASC), $$57(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$57, $$62, $$66])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                              unnest-map [$$65, $$66] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$62, 1, $$62, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                  assign [$$62] <- [$$M.getField(2)] project: [$$57, $$62]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                      data-scan []<-[$$57, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-2/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-2/query2.plan
index d276431..9878797 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-2/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-2/query2.plan
@@ -1,35 +1,67 @@
+distribute result [$$67]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$67] <- [{"$1": $$70}] project: [$$67]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$70] <- [agg-sql-sum($$75)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$75] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and($$57, eq($$58, 0)))
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$57, $$58])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$57, $$58] <- [non-empty-stream(), agg-sql-count(switch-case(eq($$73, $$D), true, null, true))]
                           -- AGGREGATE  |LOCAL|
+                            unnest $$D <- scan-collection($$72)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  assign [$$72] <- [$$C.getField(2).getField(0)] project: [$$73, $$72]
                   -- ASSIGN  |PARTITIONED|
+                    select (eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      project ([$$73, $$C])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                          unnest-map [$$69, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$77, 1, $$77, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$77, $$73])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  distinct ([$$77, $$68])
                                   -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$77) (ASC, $$68)
                                       -- STABLE_SORT [$$77(ASC), $$68(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$68, $$73, $$77])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                              unnest-map [$$76, $$77] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$73, 1, $$73, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                  assign [$$73] <- [$$M.getField(2)] project: [$$68, $$73]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                      data-scan []<-[$$68, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-2/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-2/query3.plan
index ba0454c..0734e88 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-2/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-2/query3.plan
@@ -1,32 +1,61 @@
+distribute result [$$65]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$65] <- [{"$1": $$68}] project: [$$65]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$68] <- [agg-sql-sum($$73)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$73] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$57)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$57])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$57] <- [empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select (not(if-missing-or-null(eq($$71, $$D), false)))
                             -- STREAM_SELECT  |LOCAL|
+                              unnest $$D <- scan-collection($$70)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true)
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$71] <- [$$M.getField(2)] project: [$$71]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$M])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                              data-scan []<-[$$66, $$M] <- TestYelp.YelpCheckinDateMarkers
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        assign [$$70] <- [$$C.getField(2).getField(0)] project: [$$70]
                         -- ASSIGN  |PARTITIONED|
+                          select (eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg"))
                           -- STREAM_SELECT  |PARTITIONED|
+                            project ([$$C])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                                data-scan []<-[$$67, $$C] <- TestYelp.YelpCheckin
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-3/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-3/query1.plan
index f12c1c5..cff7aa5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-3/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-3/query1.plan
@@ -1,37 +1,71 @@
+distribute result [$$65]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$65] <- [{"$1": $$68}] project: [$$65]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$68] <- [agg-sql-sum($$73)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$73] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$55)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$55])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$55] <- [non-empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select (eq($$71, $$72))
                             -- STREAM_SELECT  |LOCAL|
+                              assign [$$71] <- [$$D.getField(0)]
                               -- ASSIGN  |LOCAL|
+                                unnest $$D <- scan-collection($$70)
                                 -- UNNEST  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  select (eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg")) project: [$$72, $$70]
                   -- STREAM_SELECT  |PARTITIONED|
+                    assign [$$70] <- [$$C.getField(2)]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$72, $$C])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                          unnest-map [$$67, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$75, 1, $$75, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$75, $$72])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  distinct ([$$75, $$66])
                                   -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$75) (ASC, $$66)
                                       -- STABLE_SORT [$$75(ASC), $$66(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$66, $$72, $$75])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                              unnest-map [$$74, $$75] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$72, 1, $$72, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                  assign [$$72] <- [$$M.getField(2)] project: [$$66, $$72]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                      data-scan []<-[$$66, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-3/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-3/query2.plan
index 19dc505..7a8a0ad 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-3/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-3/query2.plan
@@ -1,36 +1,69 @@
+distribute result [$$67]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$67] <- [{"$1": $$70}] project: [$$67]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$70] <- [agg-sql-sum($$75)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$75] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and($$55, eq($$56, 0)))
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$55, $$56])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$55, $$56] <- [non-empty-stream(), agg-sql-count(switch-case(eq($$73, $$74), true, null, true))]
                           -- AGGREGATE  |LOCAL|
+                            assign [$$73] <- [$$D.getField(0)]
                             -- ASSIGN  |LOCAL|
+                              unnest $$D <- scan-collection($$72)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  select (eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg")) project: [$$74, $$72]
                   -- STREAM_SELECT  |PARTITIONED|
+                    assign [$$72] <- [$$C.getField(2)]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$74, $$C])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                          unnest-map [$$69, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$77, 1, $$77, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$77, $$74])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  distinct ([$$77, $$68])
                                   -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$77) (ASC, $$68)
                                       -- STABLE_SORT [$$77(ASC), $$68(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$68, $$74, $$77])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                              unnest-map [$$76, $$77] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$74, 1, $$74, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                  assign [$$74] <- [$$M.getField(2)] project: [$$68, $$74]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                      data-scan []<-[$$68, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-4/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-4/query1.plan
index 36c2e82..b9e7921 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-4/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-4/query1.plan
@@ -1,44 +1,82 @@
+distribute result [$$77]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$77] <- [{"$1": $$80}] project: [$$77]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$80] <- [agg-sql-sum($$87)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$87] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$67)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$67])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$67] <- [non-empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select ($$66)
                             -- STREAM_SELECT  |LOCAL|
-                              -- SUBPLAN  |LOCAL|
-                                      {
+                              subplan {
+                                        aggregate [$$66] <- [non-empty-stream()]
                                         -- AGGREGATE  |LOCAL|
+                                          select (eq($$D, $$84))
                                           -- STREAM_SELECT  |LOCAL|
+                                            unnest $$D <- scan-collection($$83)
                                             -- UNNEST  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- SUBPLAN  |LOCAL|
+                                assign [$$83] <- [$$CT.getField(1)]
                                 -- ASSIGN  |LOCAL|
+                                  unnest $$CT <- scan-collection($$82)
                                   -- UNNEST  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  select (eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg")) project: [$$84, $$82]
                   -- STREAM_SELECT  |PARTITIONED|
+                    assign [$$82] <- [$$C.getField(2)]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$84, $$C])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                          unnest-map [$$79, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$89, 1, $$89, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$89, $$84])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  distinct ([$$89, $$78])
                                   -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$89) (ASC, $$78)
                                       -- STABLE_SORT [$$89(ASC), $$78(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$78, $$84, $$89])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                              unnest-map [$$88, $$89] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$84, 1, $$84, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                  assign [$$84] <- [$$M.getField(2)] project: [$$78, $$84]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                      data-scan []<-[$$78, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-4/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-4/query2.plan
index 453abb1..8328a4a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-4/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-4/query2.plan
@@ -1,44 +1,82 @@
+distribute result [$$80]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$80] <- [{"$1": $$83}] project: [$$80]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$83] <- [agg-sql-sum($$91)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$91] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$67)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$67])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$67] <- [empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select (not(if-missing-or-null($$66, false)))
                             -- STREAM_SELECT  |LOCAL|
-                              -- SUBPLAN  |LOCAL|
-                                      {
+                              subplan {
+                                        aggregate [$$66] <- [non-empty-stream()]
                                         -- AGGREGATE  |LOCAL|
+                                          select (eq($$D, $$88))
                                           -- STREAM_SELECT  |LOCAL|
+                                            unnest $$D <- scan-collection($$87)
                                             -- UNNEST  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- SUBPLAN  |LOCAL|
+                                assign [$$87] <- [$$CT.getField(1)]
                                 -- ASSIGN  |LOCAL|
+                                  unnest $$CT <- scan-collection($$84)
                                   -- UNNEST  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  select (and(eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg"), gt(len($$84), 0))) project: [$$88, $$84]
                   -- STREAM_SELECT  |PARTITIONED|
+                    assign [$$84] <- [$$C.getField(2)]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$88, $$C])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                          unnest-map [$$82, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$93, 1, $$93, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$93, $$88])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  distinct ([$$93, $$81])
                                   -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$93) (ASC, $$81)
                                       -- STABLE_SORT [$$93(ASC), $$81(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$81, $$88, $$93])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                              unnest-map [$$92, $$93] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$88, 1, $$88, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                  assign [$$88] <- [$$M.getField(2)] project: [$$81, $$88]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                      data-scan []<-[$$81, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-4/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-4/query3.plan
index aa9e6b0..da4ecf8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-4/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-4/query3.plan
@@ -1,42 +1,78 @@
+distribute result [$$81]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$81] <- [{"$1": $$84}] project: [$$81]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$84] <- [agg-sql-sum($$91)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$91] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and($$69, eq($$70, 0)))
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$69, $$70])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$69, $$70] <- [non-empty-stream(), agg-sql-count(switch-case(and($$66, eq($$67, 0)), true, null, true))]
                           -- AGGREGATE  |LOCAL|
-                            -- SUBPLAN  |LOCAL|
-                                    {
+                            subplan {
+                                      aggregate [$$66, $$67] <- [non-empty-stream(), agg-sql-count(switch-case(eq($$D, $$88), true, null, true))]
                                       -- AGGREGATE  |LOCAL|
+                                        unnest $$D <- scan-collection($$87)
                                         -- UNNEST  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- SUBPLAN  |LOCAL|
+                              assign [$$87] <- [$$CT.getField(1)]
                               -- ASSIGN  |LOCAL|
+                                unnest $$CT <- scan-collection($$86)
                                 -- UNNEST  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  select (eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg")) project: [$$88, $$86]
                   -- STREAM_SELECT  |PARTITIONED|
+                    assign [$$86] <- [$$C.getField(2)]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$88, $$C])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                          unnest-map [$$83, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$93, 1, $$93, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$93, $$88])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  distinct ([$$93, $$82])
                                   -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$93) (ASC, $$82)
                                       -- STABLE_SORT [$$93(ASC), $$82(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$82, $$88, $$93])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                              unnest-map [$$92, $$93] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$88, 1, $$88, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                  assign [$$88] <- [$$M.getField(2)] project: [$$82, $$88]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                      data-scan []<-[$$82, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-4/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-4/query4.plan
index 696a0f0..10e665d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-4/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-quantified-queries/use-case-4/query4.plan
@@ -1,72 +1,132 @@
+distribute result [$$123]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$123] <- [{"$1": $$127}] project: [$$123]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$127] <- [agg-sql-sum($$138)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$138] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and($$113, eq($$114, 0)))
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$113, $$114])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$113, $$114] <- [non-empty-stream(), agg-sql-count(switch-case(and($$110, eq($$111, 0)), true, null, true))]
                           -- AGGREGATE  |LOCAL|
-                            -- SUBPLAN  |LOCAL|
-                                    {
+                            subplan {
+                                      aggregate [$$110, $$111] <- [non-empty-stream(), agg-sql-count(switch-case(eq($$D, $$130), true, null, true))]
                                       -- AGGREGATE  |LOCAL|
+                                        unnest $$D <- scan-collection($$132)
                                         -- UNNEST  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- SUBPLAN  |LOCAL|
+                              assign [$$132] <- [$$CT.getField(1)]
                               -- ASSIGN  |LOCAL|
+                                unnest $$CT <- scan-collection($$131)
                                 -- UNNEST  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  assign [$$131] <- [$$B.getField(2)] project: [$$130, $$131]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$130, $$B])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (TestYelp.YelpCheckinB.YelpCheckinB)  |PARTITIONED|
+                        unnest-map [$$126, $$B] <- index-search("YelpCheckinB", 0, "Default", "TestYelp", "YelpCheckinB", true, false, 1, $$142, 1, $$142, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$142, $$130])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                distinct ([$$142, $$143])
                                 -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$142) (ASC, $$143)
                                     -- STABLE_SORT [$$142(ASC), $$143(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        project ([$$130, $$143, $$142])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- BTREE_SEARCH (TestYelp.YelpCheckinB.IdxYelpCheckinDatesB)  |PARTITIONED|
+                                            unnest-map [$$141, $$142] <- index-search("IdxYelpCheckinDatesB", 0, "Default", "TestYelp", "YelpCheckinB", true, true, 1, $$130, 1, $$130, true, true, true)
+                                            -- BTREE_SEARCH  |PARTITIONED|
+                                              exchange
                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                running-aggregate [$$143] <- [create-query-uid()]
                                                 -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                  select (and($$103, eq($$104, 0))) project: [$$130]
                                                   -- STREAM_SELECT  |PARTITIONED|
+                                                    project ([$$130, $$103, $$104])
                                                     -- STREAM_PROJECT  |PARTITIONED|
-                                                      -- SUBPLAN  |PARTITIONED|
-                                                              {
+                                                      subplan {
+                                                                aggregate [$$103, $$104] <- [non-empty-stream(), agg-sql-count(switch-case(and($$100, eq($$101, 0)), true, null, true))]
                                                                 -- AGGREGATE  |LOCAL|
-                                                                  -- SUBPLAN  |LOCAL|
-                                                                          {
+                                                                  subplan {
+                                                                            aggregate [$$100, $$101] <- [non-empty-stream(), agg-sql-count(switch-case(eq($$D, $$130), true, null, true))]
                                                                             -- AGGREGATE  |LOCAL|
+                                                                              unnest $$D <- scan-collection($$129)
                                                                               -- UNNEST  |LOCAL|
+                                                                                nested tuple source
                                                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                          }
+                                                                         }
+                                                                  -- SUBPLAN  |LOCAL|
+                                                                    assign [$$129] <- [$$CT.getField(1)]
                                                                     -- ASSIGN  |LOCAL|
+                                                                      unnest $$CT <- scan-collection($$128)
                                                                       -- UNNEST  |LOCAL|
+                                                                        nested tuple source
                                                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                              }
+                                                             }
+                                                      -- SUBPLAN  |PARTITIONED|
+                                                        assign [$$128] <- [$$A.getField(2)] project: [$$130, $$128]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          project ([$$130, $$A])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (TestYelp.YelpCheckinA.YelpCheckinA)  |PARTITIONED|
+                                                              unnest-map [$$125, $$A] <- index-search("YelpCheckinA", 0, "Default", "TestYelp", "YelpCheckinA", true, false, 1, $$140, 1, $$140, true, true, true)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  project ([$$140, $$130])
                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      distinct ([$$140, $$124])
                                                                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          order (ASC, $$140) (ASC, $$124)
                                                                           -- STABLE_SORT [$$140(ASC), $$124(ASC)]  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              project ([$$124, $$130, $$140])
                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- BTREE_SEARCH (TestYelp.YelpCheckinA.IdxYelpCheckinDatesA)  |PARTITIONED|
+                                                                                  unnest-map [$$139, $$140] <- index-search("IdxYelpCheckinDatesA", 0, "Default", "TestYelp", "YelpCheckinA", true, true, 1, $$130, 1, $$130, true, true, true)
+                                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                      assign [$$130] <- [$$M.getField(2)] project: [$$124, $$130]
                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                          -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                                                          data-scan []<-[$$124, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              empty-tuple-source
                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-1/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-1/query1.plan
index 1f0fd3d..d2bce8a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-1/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-1/query1.plan
@@ -1,27 +1,54 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"marker": $$45}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$D, $$47)) project: [$$45]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$49) project: [$$45, $$47, $$D]
         -- UNNEST  |PARTITIONED|
+          select (eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg")) project: [$$45, $$47, $$49]
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$49] <- [$$C.getField(2)]
             -- ASSIGN  |PARTITIONED|
+              project ([$$45, $$47, $$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$46, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$52, 1, $$52, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$52, $$45, $$47])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$52, $$53])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$52) (ASC, $$53)
                               -- STABLE_SORT [$$52(ASC), $$53(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$45, $$47, $$53, $$52])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                      unnest-map [$$51, $$52] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$47, 1, $$47, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          running-aggregate [$$53] <- [create-query-uid()]
                                           -- RUNNING_AGGREGATE  |PARTITIONED|
+                                            assign [$$47] <- [$$M.getField(1)] project: [$$45, $$47]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                data-scan []<-[$$45, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-1/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-1/query2.plan
index 2a54768..c9f949d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-1/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-1/query2.plan
@@ -1,27 +1,54 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"marker": $$45}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$D, $$47)) project: [$$45]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$49) project: [$$45, $$47, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$49] <- [$$C.getField(2)] project: [$$45, $$47, $$49]
           -- ASSIGN  |PARTITIONED|
+            project ([$$45, $$47, $$C])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                unnest-map [$$46, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$52, 1, $$52, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$52, $$45, $$47])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$52, $$53])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$52) (ASC, $$53)
                             -- STABLE_SORT [$$52(ASC), $$53(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$45, $$47, $$53, $$52])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                    unnest-map [$$51, $$52] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$47, 1, $$47, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        running-aggregate [$$53] <- [create-query-uid()]
                                         -- RUNNING_AGGREGATE  |PARTITIONED|
+                                          select (eq($$M.getField(3), "19:49:16")) project: [$$45, $$47]
                                           -- STREAM_SELECT  |PARTITIONED|
+                                            assign [$$47] <- [$$M.getField(1)]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                data-scan []<-[$$45, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-1/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-1/query3.plan
index 15fb51a..87d953d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-1/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-1/query3.plan
@@ -1,30 +1,60 @@
+distribute result [$$72]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$72] <- [{"$1": $$76}] project: [$$72]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$76] <- [agg-sql-sum($$78)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$78] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (eq($$D, $$75))
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$77) project: [$$75, $$D]
               -- UNNEST  |PARTITIONED|
+                assign [$$77] <- [$$C.getField(2)] project: [$$75, $$77]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$75, $$C])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                      unnest-map [$$74, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$80, 1, $$80, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$80, $$75])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              distinct ([$$80, $$81])
                               -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$80) (ASC, $$81)
                                   -- STABLE_SORT [$$80(ASC), $$81(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$75, $$81, $$80])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                          unnest-map [$$79, $$80] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$75, 1, $$75, true, true, true)
+                                          -- BTREE_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              running-aggregate [$$81] <- [create-query-uid()]
                                               -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                assign [$$75] <- [$$M.getField(1)] project: [$$75]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  project ([$$M])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                      data-scan []<-[$$73, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-1/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-1/query4.plan
index 91ae9ed..16e068a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-1/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-1/query4.plan
@@ -1,32 +1,64 @@
+distribute result [$$74]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$74] <- [{"$1": $$77}] project: [$$74]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$77] <- [agg-sql-sum($$82)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$82] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$85)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$85])
               -- STREAM_PROJECT  |PARTITIONED|
+                window-aggregate [$$85] <- [win-mark-first-missing-impl($$76)] partition [$$75] order (DESC, $$76)
                 -- WINDOW_STREAM  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$75) (DESC, $$76)
                     -- STABLE_SORT [$$75(ASC), $$76(DESC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$75]  |PARTITIONED|
+                        select (eq($$D, $$78)) retain-untrue ($$76 <- missing) project: [$$75, $$76]
                         -- STREAM_SELECT  |PARTITIONED|
+                          outer-unnest $$D <- scan-collection($$79)
                           -- LEFT_OUTER_UNNEST  |PARTITIONED|
+                            assign [$$79] <- [$$C.getField(2)] project: [$$75, $$78, $$76, $$79]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$75, $$78, $$76, $$C])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                                  left-outer-unnest-map [$$76, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$84, 1, $$84, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      distinct ([$$84, $$75])
                                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          order (ASC, $$84) (ASC, $$75)
                                           -- STABLE_SORT [$$84(ASC), $$75(ASC)]  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$75, $$78, $$84])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                                  left-outer-unnest-map [$$83, $$84] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$78, 1, $$78, true, true, true)
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    exchange
                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                      assign [$$78] <- [$$M.getField(1)] project: [$$75, $$78]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                          data-scan []<-[$$75, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-2/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-2/query1.plan
index 9627fd2..59a4016 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-2/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-2/query1.plan
@@ -1,27 +1,54 @@
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"marker": $$46}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$D, $$48)) project: [$$46]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$50) project: [$$46, $$48, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$50] <- [$$C.getField(2).getField(0)] project: [$$46, $$48, $$50]
           -- ASSIGN  |PARTITIONED|
+            select (eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg"))
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$46, $$48, $$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$47, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$54, 1, $$54, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$54, $$46, $$48])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$54, $$55])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$54) (ASC, $$55)
                               -- STABLE_SORT [$$54(ASC), $$55(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$46, $$48, $$55, $$54])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                      unnest-map [$$53, $$54] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$48, 1, $$48, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          running-aggregate [$$55] <- [create-query-uid()]
                                           -- RUNNING_AGGREGATE  |PARTITIONED|
+                                            assign [$$48] <- [$$M.getField(2)] project: [$$46, $$48]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                data-scan []<-[$$46, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-2/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-2/query2.plan
index be41b71..e6d88cf 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-2/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-2/query2.plan
@@ -1,27 +1,54 @@
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"marker": $$46}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$D, $$48)) project: [$$46]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$50) project: [$$46, $$48, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$50] <- [$$C.getField(2).getField(0)] project: [$$46, $$48, $$50]
           -- ASSIGN  |PARTITIONED|
+            project ([$$46, $$48, $$C])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                unnest-map [$$47, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$54, 1, $$54, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$54, $$46, $$48])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$54, $$55])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$54) (ASC, $$55)
                             -- STABLE_SORT [$$54(ASC), $$55(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$46, $$48, $$55, $$54])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                    unnest-map [$$53, $$54] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$48, 1, $$48, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        running-aggregate [$$55] <- [create-query-uid()]
                                         -- RUNNING_AGGREGATE  |PARTITIONED|
+                                          select (eq($$M.getField(3), "19:49:16")) project: [$$46, $$48]
                                           -- STREAM_SELECT  |PARTITIONED|
+                                            assign [$$48] <- [$$M.getField(2)]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                data-scan []<-[$$46, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-2/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-2/query3.plan
index 57f75e8..8a370af 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-2/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-2/query3.plan
@@ -1,30 +1,60 @@
+distribute result [$$73]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$73] <- [{"$1": $$77}] project: [$$73]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$77] <- [agg-sql-sum($$80)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$80] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (eq($$D, $$76))
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$78) project: [$$76, $$D]
               -- UNNEST  |PARTITIONED|
+                assign [$$78] <- [$$C.getField(2).getField(0)] project: [$$76, $$78]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$76, $$C])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                      unnest-map [$$75, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$82, 1, $$82, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$82, $$76])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              distinct ([$$82, $$83])
                               -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$82) (ASC, $$83)
                                   -- STABLE_SORT [$$82(ASC), $$83(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$76, $$83, $$82])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                          unnest-map [$$81, $$82] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$76, 1, $$76, true, true, true)
+                                          -- BTREE_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              running-aggregate [$$83] <- [create-query-uid()]
                                               -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                assign [$$76] <- [$$M.getField(2)] project: [$$76]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  project ([$$M])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                      data-scan []<-[$$74, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-2/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-2/query4.plan
index 9762289..bf6e1a5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-2/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-2/query4.plan
@@ -1,32 +1,64 @@
+distribute result [$$75]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$75] <- [{"$1": $$78}] project: [$$75]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$78] <- [agg-sql-sum($$84)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$84] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$87)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$87])
               -- STREAM_PROJECT  |PARTITIONED|
+                window-aggregate [$$87] <- [win-mark-first-missing-impl($$77)] partition [$$76] order (DESC, $$77)
                 -- WINDOW_STREAM  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$76) (DESC, $$77)
                     -- STABLE_SORT [$$76(ASC), $$77(DESC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$76]  |PARTITIONED|
+                        select (eq($$D, $$79)) retain-untrue ($$77 <- missing) project: [$$76, $$77]
                         -- STREAM_SELECT  |PARTITIONED|
+                          outer-unnest $$D <- scan-collection($$80)
                           -- LEFT_OUTER_UNNEST  |PARTITIONED|
+                            assign [$$80] <- [$$C.getField(2).getField(0)] project: [$$76, $$79, $$77, $$80]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$76, $$79, $$77, $$C])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                                  left-outer-unnest-map [$$77, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$86, 1, $$86, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      distinct ([$$86, $$76])
                                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          order (ASC, $$86) (ASC, $$76)
                                           -- STABLE_SORT [$$86(ASC), $$76(ASC)]  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$76, $$79, $$86])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                                  left-outer-unnest-map [$$85, $$86] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$79, 1, $$79, true, true, true)
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    exchange
                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                      assign [$$79] <- [$$M.getField(2)] project: [$$76, $$79]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                          data-scan []<-[$$76, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query1.plan
index 1446a4f..cf83c12 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query1.plan
@@ -1,27 +1,54 @@
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"marker": $$46}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$D.getField(0), $$49)) project: [$$46]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$51) project: [$$46, $$49, $$D]
         -- UNNEST  |PARTITIONED|
+          select (eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg")) project: [$$46, $$49, $$51]
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$51] <- [$$C.getField(2)]
             -- ASSIGN  |PARTITIONED|
+              project ([$$46, $$49, $$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$47, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$54, 1, $$54, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$54, $$46, $$49])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$54, $$55])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$54) (ASC, $$55)
                               -- STABLE_SORT [$$54(ASC), $$55(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$46, $$49, $$55, $$54])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                      unnest-map [$$53, $$54] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$49, 1, $$49, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          running-aggregate [$$55] <- [create-query-uid()]
                                           -- RUNNING_AGGREGATE  |PARTITIONED|
+                                            assign [$$49] <- [$$M.getField(2)] project: [$$46, $$49]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                data-scan []<-[$$46, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query2.plan
index b5eeda1..e3fd84a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query2.plan
@@ -1,27 +1,54 @@
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"marker": $$46}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$D.getField(0), $$49)) project: [$$46]
       -- STREAM_SELECT  |PARTITIONED|
+        select (eq($$D.getField(1), "19:49:16"))
         -- STREAM_SELECT  |PARTITIONED|
+          unnest $$D <- scan-collection($$50) project: [$$46, $$49, $$D]
           -- UNNEST  |PARTITIONED|
+            assign [$$50] <- [$$C.getField(2)] project: [$$46, $$49, $$50]
             -- ASSIGN  |PARTITIONED|
+              project ([$$46, $$49, $$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$47, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$54, 1, $$54, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$54, $$46, $$49])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$54, $$55])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$54) (ASC, $$55)
                               -- STABLE_SORT [$$54(ASC), $$55(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$46, $$49, $$55, $$54])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                      unnest-map [$$53, $$54] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$49, 1, $$49, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          running-aggregate [$$55] <- [create-query-uid()]
                                           -- RUNNING_AGGREGATE  |PARTITIONED|
+                                            assign [$$49] <- [$$M.getField(2)] project: [$$46, $$49]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                data-scan []<-[$$46, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query3.plan
index be41b71..cf05b99 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query3.plan
@@ -1,27 +1,54 @@
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"marker": $$46}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$D.getField(0), $$49)) project: [$$46]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$51) project: [$$46, $$49, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$51] <- [$$C.getField(2)] project: [$$46, $$49, $$51]
           -- ASSIGN  |PARTITIONED|
+            project ([$$46, $$49, $$C])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                unnest-map [$$47, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$54, 1, $$54, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$54, $$46, $$49])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$54, $$55])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$54) (ASC, $$55)
                             -- STABLE_SORT [$$54(ASC), $$55(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$46, $$49, $$55, $$54])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                    unnest-map [$$53, $$54] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$49, 1, $$49, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        running-aggregate [$$55] <- [create-query-uid()]
                                         -- RUNNING_AGGREGATE  |PARTITIONED|
+                                          select (eq($$M.getField(3), "19:49:16")) project: [$$46, $$49]
                                           -- STREAM_SELECT  |PARTITIONED|
+                                            assign [$$49] <- [$$M.getField(2)]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                data-scan []<-[$$46, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query4.plan
index 57f75e8..c687e1d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query4.plan
@@ -1,30 +1,60 @@
+distribute result [$$74]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$74] <- [{"$1": $$78}] project: [$$74]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$78] <- [agg-sql-sum($$80)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$80] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (eq($$D.getField(0), $$77))
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$79) project: [$$77, $$D]
               -- UNNEST  |PARTITIONED|
+                assign [$$79] <- [$$C.getField(2)] project: [$$77, $$79]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$77, $$C])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                      unnest-map [$$76, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$82, 1, $$82, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$82, $$77])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              distinct ([$$82, $$83])
                               -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$82) (ASC, $$83)
                                   -- STABLE_SORT [$$82(ASC), $$83(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$77, $$83, $$82])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                          unnest-map [$$81, $$82] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$77, 1, $$77, true, true, true)
+                                          -- BTREE_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              running-aggregate [$$83] <- [create-query-uid()]
                                               -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                assign [$$77] <- [$$M.getField(2)] project: [$$77]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  project ([$$M])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                      data-scan []<-[$$75, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query5.plan
index 98dd5f0..10a50cc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-3/query5.plan
@@ -1,32 +1,64 @@
+distribute result [$$76]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$76] <- [{"$1": $$79}] project: [$$76]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$79] <- [agg-sql-sum($$84)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$84] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$87)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$87])
               -- STREAM_PROJECT  |PARTITIONED|
+                window-aggregate [$$87] <- [win-mark-first-missing-impl($$78)] partition [$$77] order (DESC, $$78)
                 -- WINDOW_STREAM  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$77) (DESC, $$78)
                     -- STABLE_SORT [$$77(ASC), $$78(DESC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$77]  |PARTITIONED|
+                        select (eq($$D.getField(0), $$80)) retain-untrue ($$78 <- missing) project: [$$77, $$78]
                         -- STREAM_SELECT  |PARTITIONED|
+                          outer-unnest $$D <- scan-collection($$81)
                           -- LEFT_OUTER_UNNEST  |PARTITIONED|
+                            assign [$$81] <- [$$C.getField(2)] project: [$$77, $$80, $$78, $$81]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$77, $$80, $$78, $$C])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                                  left-outer-unnest-map [$$78, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$86, 1, $$86, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      distinct ([$$86, $$77])
                                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          order (ASC, $$86) (ASC, $$77)
                                           -- STABLE_SORT [$$86(ASC), $$77(ASC)]  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$77, $$80, $$86])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                                  left-outer-unnest-map [$$85, $$86] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$80, 1, $$80, true, true, true)
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    exchange
                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                      assign [$$80] <- [$$M.getField(2)] project: [$$77, $$80]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                          data-scan []<-[$$77, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query1.plan
index 81495ee..9a96346 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query1.plan
@@ -1,29 +1,58 @@
+distribute result [$$56]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$56] <- [{"marker": $$57}] project: [$$56]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$D, $$59)) project: [$$57]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$62) project: [$$57, $$59, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$62] <- [$$CT.getField(1)] project: [$$57, $$59, $$62]
           -- ASSIGN  |PARTITIONED|
+            unnest $$CT <- scan-collection($$61) project: [$$57, $$59, $$CT]
             -- UNNEST  |PARTITIONED|
+              select (eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg")) project: [$$57, $$59, $$61]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$61] <- [$$C.getField(2)]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$57, $$59, $$C])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                      unnest-map [$$58, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$65, 1, $$65, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$65, $$57, $$59])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              distinct ([$$65, $$66])
                               -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$65) (ASC, $$66)
                                   -- STABLE_SORT [$$65(ASC), $$66(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$57, $$59, $$66, $$65])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                          unnest-map [$$64, $$65] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$59, 1, $$59, true, true, true)
+                                          -- BTREE_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              running-aggregate [$$66] <- [create-query-uid()]
                                               -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                assign [$$59] <- [$$M.getField(2)] project: [$$57, $$59]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                    data-scan []<-[$$57, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query2.plan
index 01f899a..d765c90 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query2.plan
@@ -1,30 +1,60 @@
+distribute result [$$58]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$58] <- [{"marker": $$59}] project: [$$58]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$D, $$61)) project: [$$59]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$65) project: [$$59, $$61, $$D]
         -- UNNEST  |PARTITIONED|
+          select (eq($$CT.getField(0), 1)) project: [$$59, $$61, $$65]
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$65] <- [$$CT.getField(1)]
             -- ASSIGN  |PARTITIONED|
+              unnest $$CT <- scan-collection($$63) project: [$$59, $$61, $$CT]
               -- UNNEST  |PARTITIONED|
+                select (eq($$C.getField(1), "--Ni3oJ4VOqfOEu7Sj2Vzg")) project: [$$59, $$61, $$63]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$63] <- [$$C.getField(2)]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$59, $$61, $$C])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                        unnest-map [$$60, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$68, 1, $$68, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$68, $$59, $$61])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                distinct ([$$68, $$69])
                                 -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$68) (ASC, $$69)
                                     -- STABLE_SORT [$$68(ASC), $$69(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        project ([$$59, $$61, $$69, $$68])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                            unnest-map [$$67, $$68] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$61, 1, $$61, true, true, true)
+                                            -- BTREE_SEARCH  |PARTITIONED|
+                                              exchange
                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                running-aggregate [$$69] <- [create-query-uid()]
                                                 -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                  assign [$$61] <- [$$M.getField(2)] project: [$$59, $$61]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                      data-scan []<-[$$59, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query3.plan
index ca0f198..43a9163 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query3.plan
@@ -1,29 +1,58 @@
+distribute result [$$56]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$56] <- [{"marker": $$57}] project: [$$56]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$D, $$59)) project: [$$57]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$62) project: [$$57, $$59, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$62] <- [$$CT.getField(1)] project: [$$57, $$59, $$62]
           -- ASSIGN  |PARTITIONED|
+            unnest $$CT <- scan-collection($$61) project: [$$57, $$59, $$CT]
             -- UNNEST  |PARTITIONED|
+              assign [$$61] <- [$$C.getField(2)] project: [$$57, $$59, $$61]
               -- ASSIGN  |PARTITIONED|
+                project ([$$57, $$59, $$C])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                    unnest-map [$$58, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$65, 1, $$65, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$65, $$57, $$59])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            distinct ([$$65, $$66])
                             -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$65) (ASC, $$66)
                                 -- STABLE_SORT [$$65(ASC), $$66(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$57, $$59, $$66, $$65])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                        unnest-map [$$64, $$65] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$59, 1, $$59, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            running-aggregate [$$66] <- [create-query-uid()]
                                             -- RUNNING_AGGREGATE  |PARTITIONED|
+                                              select (eq($$M.getField(3), "19:49:16")) project: [$$57, $$59]
                                               -- STREAM_SELECT  |PARTITIONED|
+                                                assign [$$59] <- [$$M.getField(2)]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                    data-scan []<-[$$57, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query4.plan
index 71f0b32..3e6aa20 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query4.plan
@@ -1,32 +1,64 @@
+distribute result [$$84]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$84] <- [{"$1": $$88}] project: [$$84]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$88] <- [agg-sql-sum($$91)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$91] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (eq($$D, $$87))
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$90) project: [$$87, $$D]
               -- UNNEST  |PARTITIONED|
+                assign [$$90] <- [$$CT.getField(1)] project: [$$87, $$90]
                 -- ASSIGN  |PARTITIONED|
+                  unnest $$CT <- scan-collection($$89) project: [$$87, $$CT]
                   -- UNNEST  |PARTITIONED|
+                    assign [$$89] <- [$$C.getField(2)] project: [$$87, $$89]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$87, $$C])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                          unnest-map [$$86, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$93, 1, $$93, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$93, $$87])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  distinct ([$$93, $$94])
                                   -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$93) (ASC, $$94)
                                       -- STABLE_SORT [$$93(ASC), $$94(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$87, $$94, $$93])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                              unnest-map [$$92, $$93] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$87, 1, $$87, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                  running-aggregate [$$94] <- [create-query-uid()]
                                                   -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                    assign [$$87] <- [$$M.getField(2)] project: [$$87]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$M])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                          data-scan []<-[$$85, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query5.plan
index d86fa28..a791537 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/join-unnest-queries/use-case-4/query5.plan
@@ -1,34 +1,68 @@
+distribute result [$$86]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$86] <- [{"$1": $$89}] project: [$$86]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$89] <- [agg-sql-sum($$95)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$95] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$98)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$98])
               -- STREAM_PROJECT  |PARTITIONED|
+                window-aggregate [$$98] <- [win-mark-first-missing-impl($$88)] partition [$$87] order (DESC, $$88)
                 -- WINDOW_STREAM  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$87) (DESC, $$88)
                     -- STABLE_SORT [$$87(ASC), $$88(DESC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$87]  |PARTITIONED|
+                        select (eq($$D, $$90)) retain-untrue ($$88 <- missing) project: [$$87, $$88]
                         -- STREAM_SELECT  |PARTITIONED|
+                          outer-unnest $$D <- scan-collection($$92)
                           -- LEFT_OUTER_UNNEST  |PARTITIONED|
+                            assign [$$92] <- [$$CT.getField(1)] project: [$$87, $$90, $$88, $$92]
                             -- ASSIGN  |PARTITIONED|
+                              outer-unnest $$CT <- scan-collection($$91)
                               -- LEFT_OUTER_UNNEST  |PARTITIONED|
+                                assign [$$91] <- [$$C.getField(2)] project: [$$87, $$90, $$88, $$91]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$87, $$90, $$88, $$C])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                                      left-outer-unnest-map [$$88, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", true, false, 1, $$97, 1, $$97, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          distinct ([$$97, $$87])
                                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              order (ASC, $$97) (ASC, $$87)
                                               -- STABLE_SORT [$$97(ASC), $$87(ASC)]  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  project ([$$87, $$90, $$97])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                                      left-outer-unnest-map [$$96, $$97] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", true, true, 1, $$90, 1, $$90, true, true, true)
+                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                        exchange
                                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                          assign [$$90] <- [$$M.getField(2)] project: [$$87, $$90]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN (TestYelp.YelpCheckinDateMarkers)  |PARTITIONED|
+                                                              data-scan []<-[$$87, $$M] <- TestYelp.YelpCheckinDateMarkers
+                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-indexes/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-indexes/query1.plan
index fd56b21..b930afb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-indexes/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-indexes/query1.plan
@@ -1,41 +1,79 @@
+distribute result [$$32]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"k": $$k}] project: [$$32]
     -- ASSIGN  |PARTITIONED|
+      select ($$30) project: [$$k]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$k, $$30])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$30] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (and(eq($$36, 284), eq($$35, 263)))
                       -- STREAM_SELECT  |LOCAL|
+                        assign [$$36, $$35] <- [$$v.getField("a"), $$v.getField("b")]
                         -- ASSIGN  |LOCAL|
+                          unnest $$v <- scan-collection($$34)
                           -- UNNEST  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$34] <- [$$k.getField("uarr_i")]
             -- ASSIGN  |PARTITIONED|
+              project ([$$k])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.KSI.KSI)  |PARTITIONED|
+                  unnest-map [$$33, $$k] <- index-search("KSI", 0, "Default", "test", "KSI", false, false, 1, $$45, 1, $$45, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      intersect [$$45] <- [[$$40], [$$44]]
                       -- INTERSECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$40])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$40)
                               -- STABLE_SORT [$$40(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$40])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.KSI.KS1_array_index1)  |PARTITIONED|
+                                      unnest-map [$$39, $$40] <- index-search("KS1_array_index1", 0, "Default", "test", "KSI", false, false, 1, $$37, 1, $$38, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$37, $$38] <- [284, 284]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$44])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$44)
                               -- STABLE_SORT [$$44(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$44])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.KSI.KS1_array_index2)  |PARTITIONED|
+                                      unnest-map [$$43, $$44] <- index-search("KS1_array_index2", 0, "Default", "test", "KSI", false, false, 1, $$41, 1, $$42, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$41, $$42] <- [263, 263]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-indexes/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-indexes/query2.plan
index e381267..a8e9cac 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-indexes/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-indexes/query2.plan
@@ -1,52 +1,101 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"k": $$k}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      select ($$32) project: [$$k]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$k, $$32])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$32] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (and(eq($$39, 284), eq($$38, 263), eq($$37, 123)))
                       -- STREAM_SELECT  |LOCAL|
+                        assign [$$39, $$38, $$37] <- [$$v.getField("a"), $$v.getField("b"), $$v.getField("c")]
                         -- ASSIGN  |LOCAL|
+                          unnest $$v <- scan-collection($$36)
                           -- UNNEST  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$36] <- [$$k.getField("uarr_i")]
             -- ASSIGN  |PARTITIONED|
+              project ([$$k])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.KSI.KSI)  |PARTITIONED|
+                  unnest-map [$$35, $$k] <- index-search("KSI", 0, "Default", "test", "KSI", false, false, 1, $$52, 1, $$52, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      intersect [$$52] <- [[$$43], [$$47], [$$51]]
                       -- INTERSECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$43])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$43)
                               -- STABLE_SORT [$$43(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$43])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.KSI.KS1_array_index1)  |PARTITIONED|
+                                      unnest-map [$$42, $$43] <- index-search("KS1_array_index1", 0, "Default", "test", "KSI", false, false, 1, $$40, 1, $$41, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$40, $$41] <- [284, 284]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$47])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$47)
                               -- STABLE_SORT [$$47(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$47])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.KSI.KS1_array_index2)  |PARTITIONED|
+                                      unnest-map [$$46, $$47] <- index-search("KS1_array_index2", 0, "Default", "test", "KSI", false, false, 1, $$44, 1, $$45, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$44, $$45] <- [263, 263]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$51])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$51)
                               -- STABLE_SORT [$$51(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$51])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.KSI.KS1_array_index3)  |PARTITIONED|
+                                      unnest-map [$$50, $$51] <- index-search("KS1_array_index3", 0, "Default", "test", "KSI", false, false, 1, $$48, 1, $$49, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$48, $$49] <- [123, 123]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query1.plan
index 305f6e9..6298ffb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query1.plan
@@ -1,29 +1,55 @@
+distribute result [$$42]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$42] <- [{"D1": $$D1}] project: [$$42]
     -- ASSIGN  |PARTITIONED|
+      select ($$40) project: [$$D1]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D1, $$40])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$40] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (eq($$J, 2))
                       -- STREAM_SELECT  |LOCAL|
+                        unnest $$J <- scan-collection($$45)
                         -- UNNEST  |LOCAL|
+                          select (eq($$I, 1))
                           -- STREAM_SELECT  |LOCAL|
+                            unnest $$I <- scan-collection($$44)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$45, $$44] <- [$$D1.getField("other_items"), $$D1.getField("items")]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$43, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$49, 1, $$49, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$49])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$49)
                           -- STABLE_SORT [$$49(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$49])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                  unnest-map [$$48, $$49] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$46, 1, $$47, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$46, $$47] <- [1, 1]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query10.plan
index 2fc7fad..588f524 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query10.plan
@@ -1,34 +1,62 @@
+distribute result [$$26]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$26] <- [{"D1": $$D1}] project: [$$26]
     -- ASSIGN  |PARTITIONED|
+      select ($$24) project: [$$D1]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D1, $$24])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$24] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (eq(true, $#2))
                       -- STREAM_SELECT  |LOCAL|
+                        unnest $#2 <- scan-collection(ordered-list-constructor(eq($$29, "a"), $$22))
                         -- UNNEST  |LOCAL|
-                          -- SUBPLAN  |LOCAL|
-                                  {
+                          subplan {
+                                    aggregate [$$22] <- [non-empty-stream()]
                                     -- AGGREGATE  |LOCAL|
+                                      select (eq("b", $#1))
                                       -- STREAM_SELECT  |LOCAL|
+                                        unnest $#1 <- scan-collection($$28)
                                         -- UNNEST  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
+                                 }
+                          -- SUBPLAN  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$29, $$28] <- [$$D1.getField("val"), $$D1.getField("items")]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$27, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$33, 1, $$33, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$33])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$33)
                           -- STABLE_SORT [$$33(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$33])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                  unnest-map [$$32, $$33] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$30, 1, $$31, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$30, $$31] <- ["b", "b"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query11.plan
index 8dacd0f..5581b76 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query11.plan
@@ -1,41 +1,73 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"D1": $$D1}] project: [$$33]
     -- ASSIGN  |PARTITIONED|
+      select ($$31) project: [$$D1]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D1, $$31])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$31] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (eq(true, $#3))
                       -- STREAM_SELECT  |LOCAL|
+                        unnest $#3 <- scan-collection(ordered-list-constructor(eq($$37, "a"), $$29))
                         -- UNNEST  |LOCAL|
-                          -- SUBPLAN  |LOCAL|
-                                  {
+                          subplan {
+                                    aggregate [$$29] <- [non-empty-stream()]
                                     -- AGGREGATE  |LOCAL|
+                                      select (eq(true, $#2))
                                       -- STREAM_SELECT  |LOCAL|
+                                        unnest $#2 <- scan-collection(ordered-list-constructor(eq($$36, "c"), $$27))
                                         -- UNNEST  |LOCAL|
-                                          -- SUBPLAN  |LOCAL|
-                                                  {
+                                          subplan {
+                                                    aggregate [$$27] <- [non-empty-stream()]
                                                     -- AGGREGATE  |LOCAL|
+                                                      select (eq("b", $#1))
                                                       -- STREAM_SELECT  |LOCAL|
+                                                        unnest $#1 <- scan-collection($$35)
                                                         -- UNNEST  |LOCAL|
+                                                          nested tuple source
                                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                  }
+                                                 }
+                                          -- SUBPLAN  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
+                                 }
+                          -- SUBPLAN  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$37, $$36, $$35] <- [$$D1.getField("val"), $$D1.getField("val2"), $$D1.getField("items")]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$34, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$41, 1, $$41, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$41])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$41)
                           -- STABLE_SORT [$$41(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$41])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                  unnest-map [$$40, $$41] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$38, 1, $$39, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$38, $$39] <- ["b", "b"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query2.plan
index 305f6e9..baede90 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query2.plan
@@ -1,29 +1,55 @@
+distribute result [$$42]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$42] <- [{"D1": $$D1}] project: [$$42]
     -- ASSIGN  |PARTITIONED|
+      select ($$40) project: [$$D1]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D1, $$40])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$40] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (eq($$J, 2))
                       -- STREAM_SELECT  |LOCAL|
+                        unnest $$J <- scan-collection($$45)
                         -- UNNEST  |LOCAL|
+                          select (eq($$I, 1))
                           -- STREAM_SELECT  |LOCAL|
+                            unnest $$I <- scan-collection($$44)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$45, $$44] <- [$$D1.getField("other_items"), $$D1.getField(1)]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$43, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$49, 1, $$49, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$49])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$49)
                           -- STABLE_SORT [$$49(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$49])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                  unnest-map [$$48, $$49] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$46, 1, $$47, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$46, $$47] <- [1, 1]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query3.plan
index 2f27a36..40eba97 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query3.plan
@@ -1,31 +1,59 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"D1": $$D1}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      select ($$42) project: [$$D1]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D1, $$42])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$42] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (eq($$49, 2))
                       -- STREAM_SELECT  |LOCAL|
+                        assign [$$49] <- [$$J.getField("item")]
                         -- ASSIGN  |LOCAL|
+                          unnest $$J <- scan-collection($$48)
                           -- UNNEST  |LOCAL|
+                            select (eq($$47, 1))
                             -- STREAM_SELECT  |LOCAL|
+                              assign [$$47] <- [$$I.getField("item")]
                               -- ASSIGN  |LOCAL|
+                                unnest $$I <- scan-collection($$46)
                                 -- UNNEST  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$48, $$46] <- [$$D1.getField("other_items"), $$D1.getField("items")]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$45, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$53, 1, $$53, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$53])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$53)
                           -- STABLE_SORT [$$53(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$53])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                  unnest-map [$$52, $$53] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$50, 1, $$51, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$50, $$51] <- [1, 1]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query4.plan
index 2f27a36..6fd232a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query4.plan
@@ -1,31 +1,59 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"D1": $$D1}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      select ($$42) project: [$$D1]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D1, $$42])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$42] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (eq($$49, 2))
                       -- STREAM_SELECT  |LOCAL|
+                        assign [$$49] <- [$$J.getField("item")]
                         -- ASSIGN  |LOCAL|
+                          unnest $$J <- scan-collection($$48)
                           -- UNNEST  |LOCAL|
+                            select (eq($$47, 1))
                             -- STREAM_SELECT  |LOCAL|
+                              assign [$$47] <- [$$I.getField(0)]
                               -- ASSIGN  |LOCAL|
+                                unnest $$I <- scan-collection($$46)
                                 -- UNNEST  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$48, $$46] <- [$$D1.getField("other_items"), $$D1.getField(1)]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$45, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$53, 1, $$53, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$53])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$53)
                           -- STABLE_SORT [$$53(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$53])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                  unnest-map [$$52, $$53] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$50, 1, $$51, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$50, $$51] <- [1, 1]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query5.plan
index 68e9493..feabc78 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query5.plan
@@ -1,42 +1,78 @@
+distribute result [$$72]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$72] <- [{"D1": $$D1}] project: [$$72]
     -- ASSIGN  |PARTITIONED|
+      select ($$70) project: [$$D1]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D1, $$70])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$70] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select ($$68)
                       -- STREAM_SELECT  |LOCAL|
-                        -- SUBPLAN  |LOCAL|
-                                {
+                        subplan {
+                                  aggregate [$$68] <- [non-empty-stream()]
                                   -- AGGREGATE  |LOCAL|
+                                    select (eq($$80, 2))
                                     -- STREAM_SELECT  |LOCAL|
+                                      assign [$$80] <- [$$J2.getField("item")]
                                       -- ASSIGN  |LOCAL|
+                                        unnest $$J2 <- scan-collection($$79)
                                         -- UNNEST  |LOCAL|
+                                          select (eq($$78, 1))
                                           -- STREAM_SELECT  |LOCAL|
+                                            assign [$$78] <- [$$I2.getField("item")]
                                             -- ASSIGN  |LOCAL|
+                                              unnest $$I2 <- scan-collection($$77)
                                               -- UNNEST  |LOCAL|
+                                                nested tuple source
                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SUBPLAN  |LOCAL|
+                          select (eq($$76, 2))
                           -- STREAM_SELECT  |LOCAL|
+                            assign [$$76] <- [$$J.getField("item")]
                             -- ASSIGN  |LOCAL|
+                              unnest $$J <- scan-collection($$75)
                               -- UNNEST  |LOCAL|
+                                assign [$$79, $$77] <- [$$I1.getField("other_inner_items"), $$I1.getField("inner_items")]
                                 -- ASSIGN  |LOCAL|
+                                  unnest $$I1 <- scan-collection($$74)
                                   -- UNNEST  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$75, $$74] <- [$$D1.getField("other_items"), $$D1.getField("outer_items")]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$73, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$86, 1, $$86, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$86])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$86)
                           -- STABLE_SORT [$$86(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$86])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                  unnest-map [$$85, $$86] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$83, 1, $$84, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$83, $$84] <- [1, 1]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query6.plan
index 68e9493..ebe4342 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query6.plan
@@ -1,42 +1,78 @@
+distribute result [$$72]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$72] <- [{"D1": $$D1}] project: [$$72]
     -- ASSIGN  |PARTITIONED|
+      select ($$70) project: [$$D1]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D1, $$70])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$70] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select ($$68)
                       -- STREAM_SELECT  |LOCAL|
-                        -- SUBPLAN  |LOCAL|
-                                {
+                        subplan {
+                                  aggregate [$$68] <- [non-empty-stream()]
                                   -- AGGREGATE  |LOCAL|
+                                    select (eq($$80, 2))
                                     -- STREAM_SELECT  |LOCAL|
+                                      assign [$$80] <- [$$J2.getField("item")]
                                       -- ASSIGN  |LOCAL|
+                                        unnest $$J2 <- scan-collection($$79)
                                         -- UNNEST  |LOCAL|
+                                          select (eq($$78, 1))
                                           -- STREAM_SELECT  |LOCAL|
+                                            assign [$$78] <- [$$I2.getField(0)]
                                             -- ASSIGN  |LOCAL|
+                                              unnest $$I2 <- scan-collection($$77)
                                               -- UNNEST  |LOCAL|
+                                                nested tuple source
                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SUBPLAN  |LOCAL|
+                          select (eq($$76, 2))
                           -- STREAM_SELECT  |LOCAL|
+                            assign [$$76] <- [$$J.getField("item")]
                             -- ASSIGN  |LOCAL|
+                              unnest $$J <- scan-collection($$75)
                               -- UNNEST  |LOCAL|
+                                assign [$$79, $$77] <- [$$I1.getField("other_inner_items"), $$I1.getField(0)]
                                 -- ASSIGN  |LOCAL|
+                                  unnest $$I1 <- scan-collection($$74)
                                   -- UNNEST  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$75, $$74] <- [$$D1.getField("other_items"), $$D1.getField(1)]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$73, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$86, 1, $$86, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$86])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$86)
                           -- STABLE_SORT [$$86(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$86])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                  unnest-map [$$85, $$86] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$83, 1, $$84, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$83, $$84] <- [1, 1]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query7.plan
index 4f6e5e9..6f45c65 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query7.plan
@@ -1,29 +1,55 @@
+distribute result [$$46]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$46] <- [{"D1": $$D1}] project: [$$46]
     -- ASSIGN  |PARTITIONED|
+      select (and($$42, eq($$43, 0))) project: [$$D1]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D1, $$42, $$43])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$42, $$43] <- [non-empty-stream(), agg-sql-count(switch-case(and(eq($$50, 1), eq($$51, 2)), true, null, true))]
                     -- AGGREGATE  |LOCAL|
+                      assign [$$51] <- [$$J.getField("item")]
                       -- ASSIGN  |LOCAL|
+                        unnest $$J <- scan-collection($$49)
                         -- UNNEST  |LOCAL|
+                          assign [$$50] <- [$$I.getField(0)]
                           -- ASSIGN  |LOCAL|
+                            unnest $$I <- scan-collection($$48)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$49, $$48] <- [$$D1.getField("other_items"), $$D1.getField(1)]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$47, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$55, 1, $$55, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$55])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$55)
                           -- STABLE_SORT [$$55(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$55])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                  unnest-map [$$54, $$55] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$52, 1, $$53, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$52, $$53] <- [1, 1]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query8.plan
index 95e3750..9563f8f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query8.plan
@@ -1,38 +1,70 @@
+distribute result [$$76]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$76] <- [{"D1": $$D1}] project: [$$76]
     -- ASSIGN  |PARTITIONED|
+      select (and($$72, eq($$73, 0))) project: [$$D1]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D1, $$72, $$73])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$72, $$73] <- [non-empty-stream(), agg-sql-count(switch-case(and(eq($$84, 2), and($$68, eq($$69, 0))), true, null, true))]
                     -- AGGREGATE  |LOCAL|
-                      -- SUBPLAN  |LOCAL|
-                              {
+                      subplan {
+                                aggregate [$$68, $$69] <- [non-empty-stream(), agg-sql-count(switch-case(and(eq($$82, 1), eq($$83, 2)), true, null, true))]
                                 -- AGGREGATE  |LOCAL|
+                                  assign [$$83] <- [$$J2.getField("item")]
                                   -- ASSIGN  |LOCAL|
+                                    unnest $$J2 <- scan-collection($$81)
                                     -- UNNEST  |LOCAL|
+                                      assign [$$82] <- [$$I2.getField(0)]
                                       -- ASSIGN  |LOCAL|
+                                        unnest $$I2 <- scan-collection($$80)
                                         -- UNNEST  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- SUBPLAN  |LOCAL|
+                        assign [$$84] <- [$$J.getField("item")]
                         -- ASSIGN  |LOCAL|
+                          unnest $$J <- scan-collection($$79)
                           -- UNNEST  |LOCAL|
+                            assign [$$81, $$80] <- [$$I1.getField("other_inner_items"), $$I1.getField(0)]
                             -- ASSIGN  |LOCAL|
+                              unnest $$I1 <- scan-collection($$78)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$79, $$78] <- [$$D1.getField("other_items"), $$D1.getField(1)]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$77, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$90, 1, $$90, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$90])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$90)
                           -- STABLE_SORT [$$90(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$90])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                  unnest-map [$$89, $$90] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$87, 1, $$88, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$87, $$88] <- [1, 1]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query9.plan
index 1c9bce9..628fa95 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query9.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/multiple-quantifiers/query9.plan
@@ -1,38 +1,70 @@
+distribute result [$$78]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$78] <- [{"D1": $$D1}] project: [$$78]
     -- ASSIGN  |PARTITIONED|
+      select (and($$74, eq($$75, 0))) project: [$$D1]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D1, $$74, $$75])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$74, $$75] <- [non-empty-stream(), agg-sql-count(switch-case(and(eq($$86, 2), eq($$87, 3), and($$70, eq($$71, 0))), true, null, true))]
                     -- AGGREGATE  |LOCAL|
-                      -- SUBPLAN  |LOCAL|
-                              {
+                      subplan {
+                                aggregate [$$70, $$71] <- [non-empty-stream(), agg-sql-count(switch-case(and(eq($$84, 1), eq($$85, 2)), true, null, true))]
                                 -- AGGREGATE  |LOCAL|
+                                  assign [$$85] <- [$$J2.getField("item")]
                                   -- ASSIGN  |LOCAL|
+                                    unnest $$J2 <- scan-collection($$83)
                                     -- UNNEST  |LOCAL|
+                                      assign [$$84] <- [$$I2.getField(0)]
                                       -- ASSIGN  |LOCAL|
+                                        unnest $$I2 <- scan-collection($$82)
                                         -- UNNEST  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- SUBPLAN  |LOCAL|
+                        assign [$$86] <- [$$J.getField("item")]
                         -- ASSIGN  |LOCAL|
+                          unnest $$J <- scan-collection($$81)
                           -- UNNEST  |LOCAL|
+                            assign [$$87, $$83, $$82] <- [$$I1.getField(0), $$I1.getField("other_inner_items"), $$I1.getField(1)]
                             -- ASSIGN  |LOCAL|
+                              unnest $$I1 <- scan-collection($$80)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$81, $$80] <- [$$D1.getField("other_items"), $$D1.getField(1)]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$79, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$93, 1, $$93, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$93])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$93)
                           -- STABLE_SORT [$$93(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$93])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                  unnest-map [$$92, $$93] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", false, false, 1, $$90, 1, $$91, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$90, $$91] <- [1, 1]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query1.plan
index cec77d1..8b34dc9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query1.plan
@@ -1,27 +1,51 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$20] <- [{"business_id": $$23}] project: [$$20]
     -- ASSIGN  |PARTITIONED|
+      select ($$17) project: [$$23]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$23, $$17])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$17] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (eq("2016-04-26 19:49:16", $#1))
                       -- STREAM_SELECT  |LOCAL|
+                        unnest $#1 <- scan-collection($$22)
                         -- UNNEST  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$23, $$22] <- [$$C.getField(1), $$C.getField(2)] project: [$$23, $$22]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$21, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$27, 1, $$27, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$27])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$27)
                           -- STABLE_SORT [$$27(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$27])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                  unnest-map [$$26, $$27] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$24, 1, $$25, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$24, $$25] <- ["2016-04-26 19:49:16", "2016-04-26 19:49:16"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query2.plan
index a0b5dd6..9e6bfe1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query2.plan
@@ -1,30 +1,57 @@
+distribute result [$$50]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$50] <- [{"$1": $$52}] project: [$$50]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$52] <- [agg-sql-sum($$54)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$54] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$43)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$43])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$43] <- [non-empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select (and(gt($$D, "2016"), lt($$D, "2017")))
                             -- STREAM_SELECT  |LOCAL|
+                              unnest $$D <- scan-collection($$53)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  assign [$$53] <- [$$C.getField(2)] project: [$$53]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                        unnest-map [$$51, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$58, 1, $$58, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            distinct ([$$58])
                             -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$58)
                                 -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$58])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                        unnest-map [$$57, $$58] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$55, 1, $$56, false, false, false)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$55, $$56] <- ["2016", "2017"]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query3.plan
index 247ddd3..c867b71 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query3.plan
@@ -1,31 +1,59 @@
+distribute result [$$54]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$54] <- [{"$1": $$56}] project: [$$54]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$56] <- [agg-sql-sum($$59)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$59] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$46)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$46])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$46] <- [empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select (not(if-missing-or-null(and(gt($$D, "2016"), lt($$D, "2017")), false)))
                             -- STREAM_SELECT  |LOCAL|
+                              unnest $$D <- scan-collection($$57)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  select (lt(0, len($$57)))
                   -- STREAM_SELECT  |PARTITIONED|
+                    assign [$$57] <- [$$C.getField(2)] project: [$$57]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$C])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                          unnest-map [$$55, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$63, 1, $$63, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              distinct ([$$63])
                               -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$63)
                                   -- STABLE_SORT [$$63(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$63])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                          unnest-map [$$62, $$63] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$60, 1, $$61, false, false, false)
+                                          -- BTREE_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$60, $$61] <- ["2016", "2017"]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query4.plan
index 767e1cc..47421df 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query4.plan
@@ -1,29 +1,55 @@
+distribute result [$$52]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$52] <- [{"$1": $$54}] project: [$$52]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$54] <- [agg-sql-sum($$56)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$56] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and($$43, eq($$44, 0)))
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$43, $$44])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$43, $$44] <- [non-empty-stream(), agg-sql-count(switch-case(and(gt($$D, "2016"), lt($$D, "2017")), true, null, true))]
                           -- AGGREGATE  |LOCAL|
+                            unnest $$D <- scan-collection($$55)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  assign [$$55] <- [$$C.getField(2)] project: [$$55]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                        unnest-map [$$53, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$60, 1, $$60, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            distinct ([$$60])
                             -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$60)
                                 -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$60])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                        unnest-map [$$59, $$60] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$57, 1, $$58, false, false, false)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$57, $$58] <- ["2016", "2017"]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query5.plan
index 219bd40..5c67893 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-1/query5.plan
@@ -1,22 +1,41 @@
+distribute result [$$57]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$57] <- [{"$1": $$59}] project: [$$57]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$59] <- [agg-sql-sum($$63)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$63] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$49)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$49])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$49] <- [empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select (not(if-missing-or-null(and(gt($$D, "2016"), lt($$D, "2017")), false)))
                             -- STREAM_SELECT  |LOCAL|
+                              unnest $$D <- scan-collection($$62)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  select (and(lt(0, len($$C.getField("dates_notindexed"))), lt(0, len($$C.getField("dates_notindexed_2"))))) project: [$$62]
                   -- STREAM_SELECT  |PARTITIONED|
+                    assign [$$62] <- [$$C.getField(2)]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$C])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                          data-scan []<-[$$58, $$C] <- TestYelp.YelpCheckin
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query1.plan
index 2945638..83042d4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query1.plan
@@ -1,27 +1,51 @@
+distribute result [$$21]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$21] <- [{"business_id": $$24}] project: [$$21]
     -- ASSIGN  |PARTITIONED|
+      select ($$18) project: [$$24]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$24, $$18])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$18] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (eq("2016-04-26", $#1))
                       -- STREAM_SELECT  |LOCAL|
+                        unnest $#1 <- scan-collection($$23)
                         -- UNNEST  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$23, $$24] <- [$$C.getField(2).getField(0), $$C.getField(1)] project: [$$24, $$23]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$22, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$29, 1, $$29, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$29])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$29)
                           -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$29])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                  unnest-map [$$28, $$29] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$26, 1, $$27, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$26, $$27] <- ["2016-04-26", "2016-04-26"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query2.plan
index 6f63beb..6186d80 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query2.plan
@@ -1,30 +1,57 @@
+distribute result [$$51]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$51] <- [{"$1": $$53}] project: [$$51]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$53] <- [agg-sql-sum($$56)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$56] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select ($$44)
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$44])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$44] <- [non-empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select (and(gt($$D, "2016"), lt($$D, "2017")))
                             -- STREAM_SELECT  |LOCAL|
+                              unnest $$D <- scan-collection($$54)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  assign [$$54] <- [$$C.getField(2).getField(0)] project: [$$54]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                        unnest-map [$$52, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$60, 1, $$60, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            distinct ([$$60])
                             -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$60)
                                 -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$60])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                        unnest-map [$$59, $$60] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$57, 1, $$58, false, false, false)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$57, $$58] <- ["2016", "2017"]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query3.plan
index 63f05f1..ebc473b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query3.plan
@@ -1,29 +1,55 @@
+distribute result [$$53]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$53] <- [{"$1": $$55}] project: [$$53]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$55] <- [agg-sql-sum($$58)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$58] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and($$44, eq($$45, 0)))
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$44, $$45])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$44, $$45] <- [non-empty-stream(), agg-sql-count(switch-case(and(gt($$D, "2016"), lt($$D, "2017")), true, null, true))]
                           -- AGGREGATE  |LOCAL|
+                            unnest $$D <- scan-collection($$56)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  assign [$$56] <- [$$C.getField(2).getField(0)] project: [$$56]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                        unnest-map [$$54, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$62, 1, $$62, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            distinct ([$$62])
                             -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$62)
                                 -- STABLE_SORT [$$62(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$62])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                        unnest-map [$$61, $$62] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$59, 1, $$60, false, false, false)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$59, $$60] <- ["2016", "2017"]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query4.plan
index 48dfd6c..8ea231a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query4.plan
@@ -1,20 +1,37 @@
+distribute result [$$53]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$53] <- [{"$1": $$55}] project: [$$53]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$55] <- [agg-sql-sum($$58)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$58] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and($$44, eq($$45, 0)))
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$44, $$45])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$44, $$45] <- [non-empty-stream(), agg-sql-count(switch-case(and(gt($$D, "2016"), lt($$D, "2017")), true, null, true))]
                           -- AGGREGATE  |LOCAL|
+                            unnest $$D <- scan-collection($$56)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  assign [$$56] <- [$$C.getField(2).getField("dates_notindexed")] project: [$$56]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                        data-scan []<-[$$54, $$C] <- TestYelp.YelpCheckin
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query5.plan
index 48dfd6c..9baec23 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-2/query5.plan
@@ -1,20 +1,37 @@
+distribute result [$$52]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$52] <- [{"$1": $$54}] project: [$$52]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$54] <- [agg-sql-sum($$57)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$57] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and($$43, eq($$44, 0)))
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$43, $$44])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$43, $$44] <- [non-empty-stream(), agg-sql-count(switch-case(eq(lowercase($$D), "2016"), true, null, true))]
                           -- AGGREGATE  |LOCAL|
+                            unnest $$D <- scan-collection($$55)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  assign [$$55] <- [$$C.getField(2).getField(0)] project: [$$55]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                        data-scan []<-[$$53, $$C] <- TestYelp.YelpCheckin
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-3/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-3/query1.plan
index a600cfb..42318aa 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-3/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-3/query1.plan
@@ -1,28 +1,53 @@
+distribute result [$$30]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$30] <- [{"business_id": $$34}] project: [$$30]
     -- ASSIGN  |PARTITIONED|
+      select ($$27) project: [$$34]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$34, $$27])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$27] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (eq("2016-04-26", $$33))
                       -- STREAM_SELECT  |LOCAL|
+                        assign [$$33] <- [$$D.getField(0)]
                         -- ASSIGN  |LOCAL|
+                          unnest $$D <- scan-collection($$32)
                           -- UNNEST  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$34, $$32] <- [$$C.getField(1), $$C.getField(2)] project: [$$34, $$32]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$31, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$38, 1, $$38, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$38])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$38)
                           -- STABLE_SORT [$$38(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$38])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                  unnest-map [$$37, $$38] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$35, 1, $$36, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$35, $$36] <- ["2016-04-26", "2016-04-26"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-3/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-3/query2.plan
index db9661a..b18026c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-3/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-3/query2.plan
@@ -1,28 +1,53 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"business_id": $$38}] project: [$$33]
     -- ASSIGN  |PARTITIONED|
+      select ($$30) project: [$$38]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$38, $$30])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$30] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (and(eq($$37, "2016-04-26"), eq($$36, "19:49:16")))
                       -- STREAM_SELECT  |LOCAL|
+                        assign [$$37, $$36] <- [$$D.getField(0), $$D.getField(1)]
                         -- ASSIGN  |LOCAL|
+                          unnest $$D <- scan-collection($$35)
                           -- UNNEST  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$38, $$35] <- [$$C.getField(1), $$C.getField(2)] project: [$$38, $$35]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$34, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$42, 1, $$42, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$42])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$42)
                           -- STABLE_SORT [$$42(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$42])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                  unnest-map [$$41, $$42] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$39, 1, $$40, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$39, $$40] <- ["2016-04-26", "2016-04-26"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-3/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-3/query3.plan
index 387d9d4..a0d16c7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-3/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-3/query3.plan
@@ -1,27 +1,51 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"business_id": $$40}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      select (and($$30, eq($$31, 0))) project: [$$40]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$40, $$30, $$31])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$30, $$31] <- [non-empty-stream(), agg-sql-count(switch-case(and(ge($$38, "2016"), le($$38, "2017")), true, null, true))]
                     -- AGGREGATE  |LOCAL|
+                      assign [$$38] <- [$$D.getField(0)]
                       -- ASSIGN  |LOCAL|
+                        unnest $$D <- scan-collection($$37)
                         -- UNNEST  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$40, $$37] <- [$$C.getField(1), $$C.getField(2)] project: [$$40, $$37]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$36, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$44, 1, $$44, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$44])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$44)
                           -- STABLE_SORT [$$44(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$44])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                  unnest-map [$$43, $$44] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$41, 1, $$42, true, true, false)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$41, $$42] <- ["2016", "2017"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-3/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-3/query4.plan
index ff93394..08f5c1d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-3/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-3/query4.plan
@@ -1,18 +1,33 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"business_id": $$40}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      select (and($$30, eq($$31, 0))) project: [$$40]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$40, $$30, $$31])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$30, $$31] <- [non-empty-stream(), agg-sql-count(switch-case(and(ge($$38, "2016"), le($$38, "2017")), true, null, true))]
                     -- AGGREGATE  |LOCAL|
+                      assign [$$38] <- [$$D.getField("date_notindexed")]
                       -- ASSIGN  |LOCAL|
+                        unnest $$D <- scan-collection($$37)
                         -- UNNEST  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$40, $$37] <- [$$C.getField(1), $$C.getField(2)] project: [$$40, $$37]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                  data-scan []<-[$$36, $$C] <- TestYelp.YelpCheckin
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query1.plan
index 82fc9d4..5984a7f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query1.plan
@@ -1,35 +1,64 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"business_id": $$37}] project: [$$33]
     -- ASSIGN  |PARTITIONED|
+      select ($$30) project: [$$37]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$37, $$30])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$30] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select ($$29)
                       -- STREAM_SELECT  |LOCAL|
-                        -- SUBPLAN  |LOCAL|
-                                {
+                        subplan {
+                                  aggregate [$$29] <- [non-empty-stream()]
                                   -- AGGREGATE  |LOCAL|
+                                    select (eq("2016-04-26", $#1))
                                     -- STREAM_SELECT  |LOCAL|
+                                      unnest $#1 <- scan-collection($$36)
                                       -- UNNEST  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SUBPLAN  |LOCAL|
+                          assign [$$36] <- [$$D.getField(0)]
                           -- ASSIGN  |LOCAL|
+                            unnest $$D <- scan-collection($$35)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$37, $$35] <- [$$C.getField(1), $$C.getField(2)] project: [$$37, $$35]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$34, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$43, 1, $$43, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$43])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$43)
                           -- STABLE_SORT [$$43(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$43])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                  unnest-map [$$42, $$43] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$40, 1, $$41, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$40, $$41] <- ["2016-04-26", "2016-04-26"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query2.plan
index 8b84234..0be5838 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query2.plan
@@ -1,35 +1,64 @@
+distribute result [$$42]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$42] <- [{"business_id": $$46}] project: [$$42]
     -- ASSIGN  |PARTITIONED|
+      select ($$39) project: [$$46]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$46, $$39])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$39] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select ($$38)
                       -- STREAM_SELECT  |LOCAL|
-                        -- SUBPLAN  |LOCAL|
-                                {
+                        subplan {
+                                  aggregate [$$38] <- [non-empty-stream()]
                                   -- AGGREGATE  |LOCAL|
+                                    select (eq($$D, "2016-04-26"))
                                     -- STREAM_SELECT  |LOCAL|
+                                      unnest $$D <- scan-collection($$45)
                                       -- UNNEST  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SUBPLAN  |LOCAL|
+                          assign [$$45] <- [$$CT.getField(0)]
                           -- ASSIGN  |LOCAL|
+                            unnest $$CT <- scan-collection($$44)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$46, $$44] <- [$$C.getField(1), $$C.getField(2)] project: [$$46, $$44]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$43, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$52, 1, $$52, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$52])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$52)
                           -- STABLE_SORT [$$52(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$52])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                  unnest-map [$$51, $$52] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$49, 1, $$50, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$49, $$50] <- ["2016-04-26", "2016-04-26"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query3.plan
index 387dacd..8fab13b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query3.plan
@@ -1,34 +1,62 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"business_id": $$48}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      select (and($$39, eq($$40, 0))) project: [$$48]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$48, $$39, $$40])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$39, $$40] <- [non-empty-stream(), agg-sql-count(switch-case($$38, true, null, true))]
                     -- AGGREGATE  |LOCAL|
-                      -- SUBPLAN  |LOCAL|
-                              {
+                      subplan {
+                                aggregate [$$38] <- [non-empty-stream()]
                                 -- AGGREGATE  |LOCAL|
+                                  select (eq("2019-06-07", $$D))
                                   -- STREAM_SELECT  |LOCAL|
+                                    unnest $$D <- scan-collection($$47)
                                     -- UNNEST  |LOCAL|
+                                      nested tuple source
                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- SUBPLAN  |LOCAL|
+                        assign [$$47] <- [$$CT.getField(0)]
                         -- ASSIGN  |LOCAL|
+                          unnest $$CT <- scan-collection($$46)
                           -- UNNEST  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$48, $$46] <- [$$C.getField(1), $$C.getField(2)] project: [$$48, $$46]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$45, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$54, 1, $$54, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$54])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$54)
                           -- STABLE_SORT [$$54(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$54])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                  unnest-map [$$53, $$54] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$51, 1, $$52, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$51, $$52] <- ["2019-06-07", "2019-06-07"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query4.plan
index 7bba772..f623f98 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query4.plan
@@ -1,34 +1,62 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"business_id": $$48}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      select ($$41) project: [$$48]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$48, $$41])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$41] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (and($$38, eq($$39, 0)))
                       -- STREAM_SELECT  |LOCAL|
-                        -- SUBPLAN  |LOCAL|
-                                {
+                        subplan {
+                                  aggregate [$$38, $$39] <- [non-empty-stream(), agg-sql-count(switch-case(gt($$D, "2019-06-07"), true, null, true))]
                                   -- AGGREGATE  |LOCAL|
+                                    unnest $$D <- scan-collection($$47)
                                     -- UNNEST  |LOCAL|
+                                      nested tuple source
                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SUBPLAN  |LOCAL|
+                          assign [$$47] <- [$$CT.getField(0)]
                           -- ASSIGN  |LOCAL|
+                            unnest $$CT <- scan-collection($$46)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$48, $$46] <- [$$C.getField(1), $$C.getField(2)] project: [$$48, $$46]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$45, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$53, 1, $$53, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$53])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$53)
                           -- STABLE_SORT [$$53(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$53])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                  unnest-map [$$52, $$53] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$51, 0, false, true, false)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$51] <- ["2019-06-07"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query5.plan
index 2342669..b8831e0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query5.plan
@@ -1,33 +1,60 @@
+distribute result [$$46]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$46] <- [{"business_id": $$50}] project: [$$46]
     -- ASSIGN  |PARTITIONED|
+      select (and($$41, eq($$42, 0))) project: [$$50]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$50, $$41, $$42])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$41, $$42] <- [non-empty-stream(), agg-sql-count(switch-case(and($$38, eq($$39, 0)), true, null, true))]
                     -- AGGREGATE  |LOCAL|
-                      -- SUBPLAN  |LOCAL|
-                              {
+                      subplan {
+                                aggregate [$$38, $$39] <- [non-empty-stream(), agg-sql-count(switch-case(gt($$D, "2019-06-07"), true, null, true))]
                                 -- AGGREGATE  |LOCAL|
+                                  unnest $$D <- scan-collection($$49)
                                   -- UNNEST  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- SUBPLAN  |LOCAL|
+                        assign [$$49] <- [$$CT.getField(0)]
                         -- ASSIGN  |LOCAL|
+                          unnest $$CT <- scan-collection($$48)
                           -- UNNEST  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$50, $$48] <- [$$C.getField(1), $$C.getField(2)] project: [$$50, $$48]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$47, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$55, 1, $$55, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$55])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$55)
                           -- STABLE_SORT [$$55(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$55])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                  unnest-map [$$54, $$55] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$53, 0, false, true, false)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$53] <- ["2019-06-07"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query6.plan
index 9d9cc3f..e3a147f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query6.plan
@@ -1,26 +1,46 @@
+distribute result [$$46]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$46] <- [{"business_id": $$51}] project: [$$46]
     -- ASSIGN  |PARTITIONED|
+      select ($$43) project: [$$51]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$51, $$43])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$43] <- [empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (not(if-missing-or-null(and(gt(len($$49), 0), $$41), false)))
                       -- STREAM_SELECT  |LOCAL|
-                        -- SUBPLAN  |LOCAL|
-                                {
+                        subplan {
+                                  aggregate [$$41] <- [empty-stream()]
                                   -- AGGREGATE  |LOCAL|
+                                    select (not(if-missing-or-null(gt($$D, "2019-06-07"), false)))
                                     -- STREAM_SELECT  |LOCAL|
+                                      unnest $$D <- scan-collection($$49)
                                       -- UNNEST  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SUBPLAN  |LOCAL|
+                          assign [$$49] <- [$$CT.getField(0)]
                           -- ASSIGN  |LOCAL|
+                            unnest $$CT <- scan-collection($$48)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$51, $$48] <- [$$C.getField(1), $$C.getField(2)] project: [$$51, $$48]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                  data-scan []<-[$$47, $$C] <- TestYelp.YelpCheckin
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query7.plan
index 96808dc..cebca6e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-quantified-queries/use-case-4/query7.plan
@@ -1,36 +1,66 @@
+distribute result [$$53]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$53] <- [{"business_id": $$60}] project: [$$53]
     -- ASSIGN  |PARTITIONED|
+      select ($$49) project: [$$60]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$60, $$49])
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$49] <- [empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (not(if-missing-or-null(and(gt(abs($$58), 0), lt(0, len($$57)), $$47), false)))
                       -- STREAM_SELECT  |LOCAL|
-                        -- SUBPLAN  |LOCAL|
-                                {
+                        subplan {
+                                  aggregate [$$47] <- [empty-stream()]
                                   -- AGGREGATE  |LOCAL|
+                                    select (not(if-missing-or-null(gt($$D, "2019-06-07"), false)))
                                     -- STREAM_SELECT  |LOCAL|
+                                      unnest $$D <- scan-collection($$57)
                                       -- UNNEST  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SUBPLAN  |LOCAL|
+                          assign [$$58, $$57] <- [$$CT.getField("num"), $$CT.getField(0)]
                           -- ASSIGN  |LOCAL|
+                            unnest $$CT <- scan-collection($$55)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            select (lt(0, len($$55)))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$60, $$55] <- [$$C.getField(1), $$C.getField(2)] project: [$$60, $$55]
               -- ASSIGN  |PARTITIONED|
+                project ([$$C])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                    unnest-map [$$54, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$65, 1, $$65, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$65])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$65)
                             -- STABLE_SORT [$$65(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$65])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                    unnest-map [$$64, $$65] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$63, 0, false, true, false)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$63] <- ["2019-06-07"]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-1/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-1/query1.plan
index 180df58..3ea0483 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-1/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-1/query1.plan
@@ -1,20 +1,40 @@
+distribute result [$$28]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$28] <- [{"business_id": $$31}] project: [$$28]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26 19:49:16", $$D)) project: [$$31]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$30) project: [$$31, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$31, $$30] <- [$$C.getField(1), $$C.getField(2)] project: [$$31, $$30]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                unnest-map [$$29, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$35, 1, $$35, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    distinct ([$$35])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$35)
                         -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$35])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                unnest-map [$$34, $$35] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$32, 1, $$33, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$32, $$33] <- ["2016-04-26 19:49:16", "2016-04-26 19:49:16"]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-1/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-1/query2.plan
index d18544a..ffcf31c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-1/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-1/query2.plan
@@ -1,23 +1,46 @@
+distribute result [$$49]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$49] <- [{"$1": $$51}] project: [$$49]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$51] <- [agg-sql-sum($$53)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$53] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017")))
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$52) project: [$$D]
               -- UNNEST  |PARTITIONED|
+                assign [$$52] <- [$$C.getField(2)] project: [$$52]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$C])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                      unnest-map [$$50, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$57, 1, $$57, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$57])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$57)
                               -- STABLE_SORT [$$57(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$57])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                      unnest-map [$$56, $$57] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$54, 1, $$55, false, false, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$54, $$55] <- ["2016", "2017"]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-2/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-2/query1.plan
index 18867f9..15d9b8e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-2/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-2/query1.plan
@@ -1,20 +1,40 @@
+distribute result [$$29]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"business_id": $$32}] project: [$$29]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26", $$D)) project: [$$32]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$31) project: [$$32, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$31, $$32] <- [$$C.getField(2).getField(0), $$C.getField(1)] project: [$$31, $$32]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                unnest-map [$$30, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$37, 1, $$37, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    distinct ([$$37])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$37)
                         -- STABLE_SORT [$$37(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$37])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                unnest-map [$$36, $$37] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$34, 1, $$35, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$34, $$35] <- ["2016-04-26", "2016-04-26"]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-2/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-2/query2.plan
index aec2f23..f955f2b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-2/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-2/query2.plan
@@ -1,23 +1,46 @@
+distribute result [$$50]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$50] <- [{"$1": $$52}] project: [$$50]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$52] <- [agg-sql-sum($$55)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$55] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017")))
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$53) project: [$$D]
               -- UNNEST  |PARTITIONED|
+                assign [$$53] <- [$$C.getField(2).getField(0)] project: [$$53]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$C])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                      unnest-map [$$51, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$59, 1, $$59, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$59])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$59)
                               -- STABLE_SORT [$$59(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$59])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                      unnest-map [$$58, $$59] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$56, 1, $$57, false, false, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$56, $$57] <- ["2016", "2017"]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-3/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-3/query1.plan
index 18867f9..6c8bbb7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-3/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-3/query1.plan
@@ -1,20 +1,40 @@
+distribute result [$$29]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"business_id": $$33}] project: [$$29]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26", $$D.getField(0))) project: [$$33]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$31) project: [$$33, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$33, $$31] <- [$$C.getField(1), $$C.getField(2)] project: [$$33, $$31]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                unnest-map [$$30, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$37, 1, $$37, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    distinct ([$$37])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$37)
                         -- STABLE_SORT [$$37(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$37])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                unnest-map [$$36, $$37] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$34, 1, $$35, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$34, $$35] <- ["2016-04-26", "2016-04-26"]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-3/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-3/query2.plan
index ebbf2ae..c6825b6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-3/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-3/query2.plan
@@ -1,24 +1,48 @@
+distribute result [$$51]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$51] <- [{"$1": $$54}] project: [$$51]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$54] <- [agg-sql-sum($$56)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$56] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$52, "2016"), lt($$52, "2017")))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$52] <- [$$D.getField(0)] project: [$$52]
               -- ASSIGN  |PARTITIONED|
+                unnest $$D <- scan-collection($$55) project: [$$D]
                 -- UNNEST  |PARTITIONED|
+                  assign [$$55] <- [$$C.getField(2)] project: [$$55]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                        unnest-map [$$53, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$60, 1, $$60, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            distinct ([$$60])
                             -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$60)
                                 -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$60])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                        unnest-map [$$59, $$60] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$57, 1, $$58, false, false, false)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$57, $$58] <- ["2016", "2017"]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-3/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-3/query3.plan
index f7d515f..dd7e579 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-3/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-3/query3.plan
@@ -1,20 +1,40 @@
+distribute result [$$32]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"business_id": $$37}] project: [$$32]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq("2016-04-26", $$D.getField(0)), eq($$D.getField(1), "19:49:16"))) project: [$$37]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$34) project: [$$37, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$37, $$34] <- [$$C.getField(1), $$C.getField(2)] project: [$$37, $$34]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                unnest-map [$$33, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$41, 1, $$41, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    distinct ([$$41])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$41)
                         -- STABLE_SORT [$$41(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$41])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                unnest-map [$$40, $$41] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$38, 1, $$39, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$38, $$39] <- ["2016-04-26", "2016-04-26"]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-4/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-4/query1.plan
index 2d66d75..bcab3cd 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-4/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-4/query1.plan
@@ -1,22 +1,44 @@
+distribute result [$$40]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$40] <- [{"business_id": $$44}] project: [$$40]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26", $$D)) project: [$$44]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$43) project: [$$44, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$43] <- [$$CT.getField(0)] project: [$$44, $$43]
           -- ASSIGN  |PARTITIONED|
+            unnest $$CT <- scan-collection($$42) project: [$$44, $$CT]
             -- UNNEST  |PARTITIONED|
+              assign [$$44, $$42] <- [$$C.getField(1), $$C.getField(2)] project: [$$44, $$42]
               -- ASSIGN  |PARTITIONED|
+                project ([$$C])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                    unnest-map [$$41, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$48, 1, $$48, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$48])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$48)
                             -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$48])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                    unnest-map [$$47, $$48] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$45, 1, $$46, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$45, $$46] <- ["2016-04-26", "2016-04-26"]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-4/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-4/query2.plan
index 1363a50..7b5e2b5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-4/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/use-case-4/query2.plan
@@ -1,25 +1,50 @@
+distribute result [$$61]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$61] <- [{"$1": $$63}] project: [$$61]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$63] <- [agg-sql-sum($$66)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$66] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017")))
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$65) project: [$$D]
               -- UNNEST  |PARTITIONED|
+                assign [$$65] <- [$$CT.getField(0)] project: [$$65]
                 -- ASSIGN  |PARTITIONED|
+                  unnest $$CT <- scan-collection($$64) project: [$$CT]
                   -- UNNEST  |PARTITIONED|
+                    assign [$$64] <- [$$C.getField(2)] project: [$$64]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$C])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                          unnest-map [$$62, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$70, 1, $$70, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              distinct ([$$70])
                               -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$70)
                                   -- STABLE_SORT [$$70(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$70])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                          unnest-map [$$69, $$70] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$67, 1, $$68, false, false, false)
+                                          -- BTREE_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$67, $$68] <- ["2016", "2017"]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-3-level-record-path/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-3-level-record-path/query1.plan
index f7d515f..d89180e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-3-level-record-path/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-3-level-record-path/query1.plan
@@ -1,20 +1,40 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"business_id": $$34}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26", $$D)) project: [$$34]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$33) project: [$$34, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$33, $$34] <- [$$C.getField(2).getField(0).getField(0).getField(0), $$C.getField(1)] project: [$$33, $$34]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                unnest-map [$$32, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$41, 1, $$41, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    distinct ([$$41])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$41)
                         -- STABLE_SORT [$$41(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$41])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                unnest-map [$$40, $$41] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$38, 1, $$39, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$38, $$39] <- ["2016-04-26", "2016-04-26"]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-3-level-record-path/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-3-level-record-path/query2.plan
index 380c782..5ee4581 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-3-level-record-path/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-3-level-record-path/query2.plan
@@ -1,23 +1,46 @@
+distribute result [$$52]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$52] <- [{"$1": $$54}] project: [$$52]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$54] <- [agg-sql-sum($$59)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$59] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017")))
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$55) project: [$$D]
               -- UNNEST  |PARTITIONED|
+                assign [$$55] <- [$$C.getField(2).getField(0).getField(0).getField(0)] project: [$$55]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$C])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                      unnest-map [$$53, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$63, 1, $$63, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$63])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$63)
                               -- STABLE_SORT [$$63(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$63])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                      unnest-map [$$62, $$63] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$60, 1, $$61, false, false, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$60, $$61] <- ["2016", "2017"]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-pk/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-pk/query1.plan
index 6835463..d4392c1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-pk/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-pk/query1.plan
@@ -1,20 +1,40 @@
+distribute result [$$28]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$28] <- [{"business_id": $$30}] project: [$$28]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26 19:49:16", $$D)) project: [$$30]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$31) project: [$$30, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$31] <- [$$C.getField(2)] project: [$$30, $$31]
           -- ASSIGN  |PARTITIONED|
+            project ([$$30, $$C])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                unnest-map [$$29, $$30, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 2, $$36, $$37, 2, $$36, $$37, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    distinct ([$$36, $$37])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$36) (ASC, $$37)
                         -- STABLE_SORT [$$36(ASC), $$37(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$36, $$37])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                unnest-map [$$35, $$36, $$37] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$33, 1, $$34, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$33, $$34] <- ["2016-04-26 19:49:16", "2016-04-26 19:49:16"]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-pk/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-pk/query2.plan
index c565154..e20ef6d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-pk/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-pk/query2.plan
@@ -1,23 +1,46 @@
+distribute result [$$49]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$49] <- [{"$1": $$52}] project: [$$49]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$52] <- [agg-sql-sum($$54)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$54] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017")))
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$53) project: [$$D]
               -- UNNEST  |PARTITIONED|
+                assign [$$53] <- [$$C.getField(2)] project: [$$53]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$C])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                      unnest-map [$$50, $$51, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 2, $$58, $$59, 2, $$58, $$59, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$58, $$59])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$58) (ASC, $$59)
                               -- STABLE_SORT [$$58(ASC), $$59(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$58, $$59])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                      unnest-map [$$57, $$58, $$59] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$55, 1, $$56, false, false, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$55, $$56] <- ["2016", "2017"]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-sk/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-sk/query1.plan
index 560f87d..ad74dd7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-sk/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-sk/query1.plan
@@ -1,21 +1,42 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"business_id": $$35}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq("2016-04-26", $$D.getField(0)), eq("19:49:16", $$D.getField(1)))) project: [$$35]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$37) project: [$$35, $$D]
         -- UNNEST  |PARTITIONED|
+          select (eq("--1UhMGODdWsrMastO9DZw", $$35))
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$35, $$37] <- [$$C.getField(1), $$C.getField(2)] project: [$$35, $$37]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$36, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$46, 1, $$46, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$46])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$46)
                           -- STABLE_SORT [$$46(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$46])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDatesTimes)  |PARTITIONED|
+                                  unnest-map [$$44, $$45, $$46] <- index-search("IdxYelpCheckinDatesTimes", 0, "Default", "TestYelp", "YelpCheckin", false, false, 2, $$40, $$41, 2, $$42, $$43, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$40, $$41, $$42, $$43] <- ["2016-04-26", "19:49:16", "2016-04-26", "19:49:16"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-sk/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-sk/query2.plan
index 9c70594..c266452 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-sk/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-sk/query2.plan
@@ -1,24 +1,48 @@
+distribute result [$$51]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$51] <- [{"$1": $$54}] project: [$$51]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$54] <- [agg-sql-sum($$56)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$56] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$52, "2016"), lt($$52, "2017")))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$52] <- [$$D.getField(0)] project: [$$52]
               -- ASSIGN  |PARTITIONED|
+                unnest $$D <- scan-collection($$55) project: [$$D]
                 -- UNNEST  |PARTITIONED|
+                  assign [$$55] <- [$$C.getField(2)] project: [$$55]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                        unnest-map [$$53, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$61, 1, $$61, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            distinct ([$$61])
                             -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$61)
                                 -- STABLE_SORT [$$61(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$61])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDatesTimes)  |PARTITIONED|
+                                        unnest-map [$$59, $$60, $$61] <- index-search("IdxYelpCheckinDatesTimes", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$57, 1, $$58, false, false, false)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$57, $$58] <- ["2016", "2017"]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-sk/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-sk/query3.plan
index a2530d6..ca39a86 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-sk/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-composite-sk/query3.plan
@@ -1,15 +1,30 @@
+distribute result [$$57]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$57] <- [{"$1": $$61}] project: [$$57]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$61] <- [agg-sql-sum($$63)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$63] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(ge($$58, "00:00:00"), le($$58, "12:00:00"), le($$59, "2017"), ge($$59, "2016")))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$59, $$58] <- [$$D.getField("date_notindexed"), $$D.getField(1)] project: [$$59, $$58]
               -- ASSIGN  |PARTITIONED|
+                unnest $$D <- scan-collection($$62) project: [$$D]
                 -- UNNEST  |PARTITIONED|
+                  assign [$$62] <- [$$C.getField(2)] project: [$$62]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                        data-scan []<-[$$60, $$C] <- TestYelp.YelpCheckin
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-filter-fields/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-filter-fields/query1.plan
index 9e3ae2b..e76a384 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-filter-fields/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-filter-fields/query1.plan
@@ -1,21 +1,42 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"business_id": $$32}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26 19:49:16", $$D)) project: [$$32]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$34) project: [$$32, $$D]
         -- UNNEST  |PARTITIONED|
+          select (eq($$32, "--1UhMGODdWsrMastO9DZw"))
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$32, $$34] <- [$$C.getField(1), $$C.getField(2)] project: [$$32, $$34]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$33, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$38, 1, $$38, true, true, true) with filter on min:[$$39] max:[$$40]
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$38])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$38)
                           -- STABLE_SORT [$$38(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$38, $$39, $$40])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                  unnest-map [$$37, $$38, $$39, $$40] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$35, 1, $$36, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$35, $$36] <- ["2016-04-26 19:49:16", "2016-04-26 19:49:16"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-filter-fields/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-filter-fields/query2.plan
index d18544a..0f05f88 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-filter-fields/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/closed/with-filter-fields/query2.plan
@@ -1,23 +1,46 @@
+distribute result [$$49]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$49] <- [{"$1": $$51}] project: [$$49]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$51] <- [agg-sql-sum($$53)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$53] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017")))
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$52) project: [$$D]
               -- UNNEST  |PARTITIONED|
+                assign [$$52] <- [$$C.getField(2)] project: [$$52]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$C])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                      unnest-map [$$50, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$57, 1, $$57, true, true, true) with filter on min:[$$58] max:[$$59]
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$57])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$57)
                               -- STABLE_SORT [$$57(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$57, $$58, $$59])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                      unnest-map [$$56, $$57, $$58, $$59] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$54, 1, $$55, false, false, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$54, $$55] <- ["2016", "2017"]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query1.plan
index a585a44..452bc53 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query1.plan
@@ -1,20 +1,40 @@
+distribute result [$$29]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"D": $$D, "F": $$F}] project: [$$29]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$F.getField("open_field_3a"), 0))
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$F <- scan-collection($$31) project: [$$D, $$F]
         -- UNNEST  |PARTITIONED|
+          assign [$$31] <- [$$D.getField("open_field_1").getField("open_field_2")]
           -- ASSIGN  |PARTITIONED|
+            project ([$$D])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestDataverse.TestDataset.TestDataset)  |PARTITIONED|
+                unnest-map [$$30, $$D] <- index-search("TestDataset", 0, "Default", "TestDataverse", "TestDataset", false, false, 1, $$36, 1, $$36, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    distinct ([$$36])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$36)
                         -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$36])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (TestDataverse.TestDataset.testIndex1)  |PARTITIONED|
+                                unnest-map [$$35, $$36] <- index-search("testIndex1", 0, "Default", "TestDataverse", "TestDataset", false, false, 1, $$34, 0, true, true, false)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$34] <- [0]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query2.plan
index 4c51096..4ba2545 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query2.plan
@@ -1,20 +1,40 @@
+distribute result [$$30]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$30] <- [{"D": $$D, "F": $$F}] project: [$$30]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$F.getField("open_field_3b").getField("open_field_4"), 0))
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$F <- scan-collection($$32) project: [$$D, $$F]
         -- UNNEST  |PARTITIONED|
+          assign [$$32] <- [$$D.getField("open_field_1").getField("open_field_2")]
           -- ASSIGN  |PARTITIONED|
+            project ([$$D])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestDataverse.TestDataset.TestDataset)  |PARTITIONED|
+                unnest-map [$$31, $$D] <- index-search("TestDataset", 0, "Default", "TestDataverse", "TestDataset", false, false, 1, $$38, 1, $$38, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    distinct ([$$38])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$38)
                         -- STABLE_SORT [$$38(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$38])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (TestDataverse.TestDataset.testIndex2)  |PARTITIONED|
+                                unnest-map [$$37, $$38] <- index-search("testIndex2", 0, "Default", "TestDataverse", "TestDataset", false, false, 1, $$36, 0, true, true, false)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$36] <- [0]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query3.plan
index d576fc3..9f19e66 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query3.plan
@@ -1,22 +1,44 @@
+distribute result [$$41]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$41] <- [{"D": $$D, "F1": $$F1, "F2": $$F2}] project: [$$41]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$F2, 0))
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$F2 <- scan-collection($$44) project: [$$D, $$F1, $$F2]
         -- UNNEST  |PARTITIONED|
+          assign [$$44] <- [$$F1.getField("open_field_3c").getField("open_field_4a")]
           -- ASSIGN  |PARTITIONED|
+            unnest $$F1 <- scan-collection($$43) project: [$$D, $$F1]
             -- UNNEST  |PARTITIONED|
+              assign [$$43] <- [$$D.getField("open_field_1").getField("open_field_2")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$D])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (TestDataverse.TestDataset.TestDataset)  |PARTITIONED|
+                    unnest-map [$$42, $$D] <- index-search("TestDataset", 0, "Default", "TestDataverse", "TestDataset", false, false, 1, $$49, 1, $$49, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$49])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$49)
                             -- STABLE_SORT [$$49(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$49])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (TestDataverse.TestDataset.testIndex3)  |PARTITIONED|
+                                    unnest-map [$$48, $$49] <- index-search("testIndex3", 0, "Default", "TestDataverse", "TestDataset", false, false, 1, $$47, 0, true, true, false)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$47] <- [0]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query4.plan
index f22a65a..c9cc509 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query4.plan
@@ -1,22 +1,44 @@
+distribute result [$$42]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$42] <- [{"D": $$D, "F1": $$F1, "F2": $$F2}] project: [$$42]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$F2.getField("open_field_5"), 0))
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$F2 <- scan-collection($$45) project: [$$D, $$F1, $$F2]
         -- UNNEST  |PARTITIONED|
+          assign [$$45] <- [$$F1.getField("open_field_3c").getField("open_field_4b")]
           -- ASSIGN  |PARTITIONED|
+            unnest $$F1 <- scan-collection($$44) project: [$$D, $$F1]
             -- UNNEST  |PARTITIONED|
+              assign [$$44] <- [$$D.getField("open_field_1").getField("open_field_2")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$D])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (TestDataverse.TestDataset.TestDataset)  |PARTITIONED|
+                    unnest-map [$$43, $$D] <- index-search("TestDataset", 0, "Default", "TestDataverse", "TestDataset", false, false, 1, $$51, 1, $$51, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$51])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$51)
                             -- STABLE_SORT [$$51(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$51])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (TestDataverse.TestDataset.testIndex4)  |PARTITIONED|
+                                    unnest-map [$$50, $$51] <- index-search("testIndex4", 0, "Default", "TestDataverse", "TestDataset", false, false, 1, $$49, 0, true, true, false)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$49] <- [0]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query5.plan
index 85d939a..fe1c1da 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query5.plan
@@ -1,20 +1,40 @@
+distribute result [$$29]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"D": $$D, "F": $$F}] project: [$$29]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$F.getField("open_field_3a"), 0))
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$F <- scan-collection($$31) project: [$$D, $$F]
         -- UNNEST  |PARTITIONED|
+          assign [$$31] <- [$$D.getField(1).getField("open_field_2")]
           -- ASSIGN  |PARTITIONED|
+            project ([$$D])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestDataverse.TestDataset.TestDataset)  |PARTITIONED|
+                unnest-map [$$30, $$D] <- index-search("TestDataset", 0, "Default", "TestDataverse", "TestDataset", false, false, 1, $$36, 1, $$36, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    distinct ([$$36])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$36)
                         -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$36])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (TestDataverse.TestDataset.testIndex1c)  |PARTITIONED|
+                                unnest-map [$$35, $$36] <- index-search("testIndex1c", 0, "Default", "TestDataverse", "TestDataset", false, false, 1, $$34, 0, true, true, false)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$34] <- [0]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query6.plan
index 1b44a26..6858fcf 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query6.plan
@@ -1,20 +1,40 @@
+distribute result [$$30]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$30] <- [{"D": $$D, "F": $$F}] project: [$$30]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$F.getField("open_field_3b").getField("open_field_4"), 0))
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$F <- scan-collection($$32) project: [$$D, $$F]
         -- UNNEST  |PARTITIONED|
+          assign [$$32] <- [$$D.getField(1).getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$D])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestDataverse.TestDataset.TestDataset)  |PARTITIONED|
+                unnest-map [$$31, $$D] <- index-search("TestDataset", 0, "Default", "TestDataverse", "TestDataset", false, false, 1, $$38, 1, $$38, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    distinct ([$$38])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$38)
                         -- STABLE_SORT [$$38(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$38])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (TestDataverse.TestDataset.testIndex2c)  |PARTITIONED|
+                                unnest-map [$$37, $$38] <- index-search("testIndex2c", 0, "Default", "TestDataverse", "TestDataset", false, false, 1, $$36, 0, true, true, false)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$36] <- [0]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query7.plan
index 9ecb9c8..66af149 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query7.plan
@@ -1,22 +1,44 @@
+distribute result [$$41]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$41] <- [{"D": $$D, "F1": $$F1, "F2": $$F2}] project: [$$41]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$F2, 0))
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$F2 <- scan-collection($$44) project: [$$D, $$F1, $$F2]
         -- UNNEST  |PARTITIONED|
+          assign [$$44] <- [$$F1.getField(0).getField("open_field_4a")]
           -- ASSIGN  |PARTITIONED|
+            unnest $$F1 <- scan-collection($$43) project: [$$D, $$F1]
             -- UNNEST  |PARTITIONED|
+              assign [$$43] <- [$$D.getField(1).getField(0)]
               -- ASSIGN  |PARTITIONED|
+                project ([$$D])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (TestDataverse.TestDataset.TestDataset)  |PARTITIONED|
+                    unnest-map [$$42, $$D] <- index-search("TestDataset", 0, "Default", "TestDataverse", "TestDataset", false, false, 1, $$49, 1, $$49, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$49])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$49)
                             -- STABLE_SORT [$$49(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$49])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (TestDataverse.TestDataset.testIndex3c)  |PARTITIONED|
+                                    unnest-map [$$48, $$49] <- index-search("testIndex3c", 0, "Default", "TestDataverse", "TestDataset", false, false, 1, $$47, 0, true, true, false)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$47] <- [0]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query8.plan
index b6c6d86..0437492 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/complex-structures/query8.plan
@@ -1,22 +1,44 @@
+distribute result [$$42]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$42] <- [{"D": $$D, "F1": $$F1, "F2": $$F2}] project: [$$42]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$F2.getField("open_field_5"), 0))
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$F2 <- scan-collection($$45) project: [$$D, $$F1, $$F2]
         -- UNNEST  |PARTITIONED|
+          assign [$$45] <- [$$F1.getField(0).getField(0)]
           -- ASSIGN  |PARTITIONED|
+            unnest $$F1 <- scan-collection($$44) project: [$$D, $$F1]
             -- UNNEST  |PARTITIONED|
+              assign [$$44] <- [$$D.getField(1).getField(0)]
               -- ASSIGN  |PARTITIONED|
+                project ([$$D])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (TestDataverse.TestDataset.TestDataset)  |PARTITIONED|
+                    unnest-map [$$43, $$D] <- index-search("TestDataset", 0, "Default", "TestDataverse", "TestDataset", false, false, 1, $$51, 1, $$51, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$51])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$51)
                             -- STABLE_SORT [$$51(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$51])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (TestDataverse.TestDataset.testIndex4c)  |PARTITIONED|
+                                    unnest-map [$$50, $$51] <- index-search("testIndex4c", 0, "Default", "TestDataverse", "TestDataset", false, false, 1, $$49, 0, true, true, false)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$49] <- [0]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/multiple-indexes/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/multiple-indexes/query1.plan
index 6b57fed..1cbe4f4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/multiple-indexes/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/multiple-indexes/query1.plan
@@ -1,33 +1,66 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"k": $$k, "v": $$v}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq($$v.getField("a"), 284), eq($$v.getField("b"), 263)))
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$v <- scan-collection($$33) project: [$$k, $$v]
         -- UNNEST  |PARTITIONED|
+          assign [$$33] <- [$$k.getField("uarr_i")]
           -- ASSIGN  |PARTITIONED|
+            project ([$$k])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.KSI.KSI)  |PARTITIONED|
+                unnest-map [$$32, $$k] <- index-search("KSI", 0, "Default", "test", "KSI", false, false, 1, $$44, 1, $$44, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    intersect [$$44] <- [[$$39], [$$43]]
                     -- INTERSECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$39])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$39)
                             -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$39])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.KSI.KS1_array_index1)  |PARTITIONED|
+                                    unnest-map [$$38, $$39] <- index-search("KS1_array_index1", 0, "Default", "test", "KSI", false, false, 1, $$36, 1, $$37, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$36, $$37] <- [284, 284]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$43])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$43)
                             -- STABLE_SORT [$$43(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$43])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.KSI.KS1_array_index2)  |PARTITIONED|
+                                    unnest-map [$$42, $$43] <- index-search("KS1_array_index2", 0, "Default", "test", "KSI", false, false, 1, $$40, 1, $$41, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$40, $$41] <- [263, 263]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/multiple-indexes/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/multiple-indexes/query2.plan
index c8fbf32..cb4d784 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/multiple-indexes/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/multiple-indexes/query2.plan
@@ -1,44 +1,88 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"k": $$k, "v": $$v}] project: [$$33]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq($$v.getField("a"), 284), eq($$v.getField("b"), 263), eq($$v.getField("c"), 123)))
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$v <- scan-collection($$35) project: [$$k, $$v]
         -- UNNEST  |PARTITIONED|
+          assign [$$35] <- [$$k.getField("uarr_i")]
           -- ASSIGN  |PARTITIONED|
+            project ([$$k])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.KSI.KSI)  |PARTITIONED|
+                unnest-map [$$34, $$k] <- index-search("KSI", 0, "Default", "test", "KSI", false, false, 1, $$51, 1, $$51, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    intersect [$$51] <- [[$$42], [$$46], [$$50]]
                     -- INTERSECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$42])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$42)
                             -- STABLE_SORT [$$42(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$42])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.KSI.KS1_array_index1)  |PARTITIONED|
+                                    unnest-map [$$41, $$42] <- index-search("KS1_array_index1", 0, "Default", "test", "KSI", false, false, 1, $$39, 1, $$40, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$39, $$40] <- [284, 284]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$46])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$46)
                             -- STABLE_SORT [$$46(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$46])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.KSI.KS1_array_index2)  |PARTITIONED|
+                                    unnest-map [$$45, $$46] <- index-search("KS1_array_index2", 0, "Default", "test", "KSI", false, false, 1, $$43, 1, $$44, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$43, $$44] <- [263, 263]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$50])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$50)
                             -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$50])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.KSI.KS1_array_index3)  |PARTITIONED|
+                                    unnest-map [$$49, $$50] <- index-search("KS1_array_index3", 0, "Default", "test", "KSI", false, false, 1, $$47, 1, $$48, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$47, $$48] <- [123, 123]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-1/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-1/query1.plan
index 180df58..b50efb7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-1/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-1/query1.plan
@@ -1,20 +1,40 @@
+distribute result [$$28]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$28] <- [{"business_id": $$31}] project: [$$28]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26 19:49:16", $$D)) project: [$$31]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$30) project: [$$31, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$31, $$30] <- [$$C.getField("business_id"), $$C.getField("dates")] project: [$$31, $$30]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                unnest-map [$$29, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$35, 1, $$35, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    distinct ([$$35])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$35)
                         -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$35])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                unnest-map [$$34, $$35] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$32, 1, $$33, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$32, $$33] <- ["2016-04-26 19:49:16", "2016-04-26 19:49:16"]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-1/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-1/query2.plan
index d18544a..08497ff 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-1/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-1/query2.plan
@@ -1,23 +1,46 @@
+distribute result [$$49]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$49] <- [{"$1": $$51}] project: [$$49]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$51] <- [agg-sql-sum($$53)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$53] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017")))
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$52) project: [$$D]
               -- UNNEST  |PARTITIONED|
+                assign [$$52] <- [$$C.getField("dates")] project: [$$52]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$C])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                      unnest-map [$$50, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$57, 1, $$57, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$57])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$57)
                               -- STABLE_SORT [$$57(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$57])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                      unnest-map [$$56, $$57] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$54, 1, $$55, false, false, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$54, $$55] <- ["2016", "2017"]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-2/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-2/query1.plan
index 18867f9..64ce760 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-2/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-2/query1.plan
@@ -1,20 +1,40 @@
+distribute result [$$29]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"business_id": $$32}] project: [$$29]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26", $$D)) project: [$$32]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$31) project: [$$32, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$31, $$32] <- [$$C.getField("checkin_times").getField("dates"), $$C.getField("business_id")] project: [$$31, $$32]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                unnest-map [$$30, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$37, 1, $$37, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    distinct ([$$37])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$37)
                         -- STABLE_SORT [$$37(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$37])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                unnest-map [$$36, $$37] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$34, 1, $$35, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$34, $$35] <- ["2016-04-26", "2016-04-26"]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-2/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-2/query2.plan
index aec2f23..898ef4f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-2/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-2/query2.plan
@@ -1,23 +1,46 @@
+distribute result [$$50]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$50] <- [{"$1": $$52}] project: [$$50]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$52] <- [agg-sql-sum($$55)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$55] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017")))
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$53) project: [$$D]
               -- UNNEST  |PARTITIONED|
+                assign [$$53] <- [$$C.getField("checkin_times").getField("dates")] project: [$$53]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$C])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                      unnest-map [$$51, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$59, 1, $$59, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$59])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$59)
                               -- STABLE_SORT [$$59(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$59])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                      unnest-map [$$58, $$59] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$56, 1, $$57, false, false, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$56, $$57] <- ["2016", "2017"]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-3/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-3/query1.plan
index 18867f9..cd35b00 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-3/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-3/query1.plan
@@ -1,20 +1,40 @@
+distribute result [$$29]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"business_id": $$33}] project: [$$29]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26", $$D.getField("date"))) project: [$$33]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$31) project: [$$33, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$33, $$31] <- [$$C.getField("business_id"), $$C.getField("checkin_times")] project: [$$33, $$31]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                unnest-map [$$30, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$37, 1, $$37, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    distinct ([$$37])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$37)
                         -- STABLE_SORT [$$37(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$37])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                unnest-map [$$36, $$37] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$34, 1, $$35, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$34, $$35] <- ["2016-04-26", "2016-04-26"]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-3/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-3/query2.plan
index ebbf2ae..235d0d1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-3/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-3/query2.plan
@@ -1,24 +1,48 @@
+distribute result [$$51]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$51] <- [{"$1": $$54}] project: [$$51]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$54] <- [agg-sql-sum($$56)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$56] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$52, "2016"), lt($$52, "2017")))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$52] <- [$$D.getField("date")] project: [$$52]
               -- ASSIGN  |PARTITIONED|
+                unnest $$D <- scan-collection($$55) project: [$$D]
                 -- UNNEST  |PARTITIONED|
+                  assign [$$55] <- [$$C.getField("checkin_times")] project: [$$55]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                        unnest-map [$$53, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$60, 1, $$60, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            distinct ([$$60])
                             -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$60)
                                 -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$60])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                        unnest-map [$$59, $$60] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$57, 1, $$58, false, false, false)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$57, $$58] <- ["2016", "2017"]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-3/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-3/query3.plan
index f7d515f..3fa0df1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-3/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-3/query3.plan
@@ -1,20 +1,40 @@
+distribute result [$$32]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"business_id": $$37}] project: [$$32]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq("2016-04-26", $$D.getField("date")), eq($$D.getField("time"), "19:49:16"))) project: [$$37]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$34) project: [$$37, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$37, $$34] <- [$$C.getField("business_id"), $$C.getField("checkin_times")] project: [$$37, $$34]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                unnest-map [$$33, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$41, 1, $$41, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    distinct ([$$41])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$41)
                         -- STABLE_SORT [$$41(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$41])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                unnest-map [$$40, $$41] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$38, 1, $$39, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$38, $$39] <- ["2016-04-26", "2016-04-26"]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-4/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-4/query1.plan
index 2d66d75..fb1ac2c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-4/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-4/query1.plan
@@ -1,22 +1,44 @@
+distribute result [$$40]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$40] <- [{"business_id": $$44}] project: [$$40]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26", $$D)) project: [$$44]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$43) project: [$$44, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$43] <- [$$CT.getField("dates")] project: [$$44, $$43]
           -- ASSIGN  |PARTITIONED|
+            unnest $$CT <- scan-collection($$42) project: [$$44, $$CT]
             -- UNNEST  |PARTITIONED|
+              assign [$$44, $$42] <- [$$C.getField("business_id"), $$C.getField("checkin_times")] project: [$$44, $$42]
               -- ASSIGN  |PARTITIONED|
+                project ([$$C])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                    unnest-map [$$41, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$48, 1, $$48, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        distinct ([$$48])
                         -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$48)
                             -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$48])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                    unnest-map [$$47, $$48] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$45, 1, $$46, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$45, $$46] <- ["2016-04-26", "2016-04-26"]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-4/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-4/query2.plan
index 1363a50..67c97ad 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-4/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/use-case-4/query2.plan
@@ -1,25 +1,50 @@
+distribute result [$$61]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$61] <- [{"$1": $$63}] project: [$$61]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$63] <- [agg-sql-sum($$66)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$66] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017")))
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$65) project: [$$D]
               -- UNNEST  |PARTITIONED|
+                assign [$$65] <- [$$CT.getField("dates")] project: [$$65]
                 -- ASSIGN  |PARTITIONED|
+                  unnest $$CT <- scan-collection($$64) project: [$$CT]
                   -- UNNEST  |PARTITIONED|
+                    assign [$$64] <- [$$C.getField("checkin_times")] project: [$$64]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$C])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                          unnest-map [$$62, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$70, 1, $$70, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              distinct ([$$70])
                               -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$70)
                                   -- STABLE_SORT [$$70(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$70])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                          unnest-map [$$69, $$70] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$67, 1, $$68, false, false, false)
+                                          -- BTREE_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$67, $$68] <- ["2016", "2017"]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/with-3-level-record-path/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/with-3-level-record-path/query1.plan
index f7d515f..cf25b9a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/with-3-level-record-path/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/with-3-level-record-path/query1.plan
@@ -1,20 +1,40 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"business_id": $$34}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26", $$D)) project: [$$34]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$33) project: [$$34, $$D]
         -- UNNEST  |PARTITIONED|
+          assign [$$33, $$34] <- [$$C.getField("checkin_data").getField("checkin_temporal").getField("checkin_times").getField("dates"), $$C.getField("business_id")] project: [$$33, $$34]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                unnest-map [$$32, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$41, 1, $$41, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    distinct ([$$41])
                     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$41)
                         -- STABLE_SORT [$$41(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$41])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                unnest-map [$$40, $$41] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$38, 1, $$39, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$38, $$39] <- ["2016-04-26", "2016-04-26"]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/with-3-level-record-path/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/with-3-level-record-path/query2.plan
index 380c782..0455943 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/with-3-level-record-path/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/with-3-level-record-path/query2.plan
@@ -1,23 +1,46 @@
+distribute result [$$52]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$52] <- [{"$1": $$54}] project: [$$52]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$54] <- [agg-sql-sum($$59)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$59] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017")))
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$55) project: [$$D]
               -- UNNEST  |PARTITIONED|
+                assign [$$55] <- [$$C.getField("checkin_data").getField("checkin_temporal").getField("checkin_times").getField("dates")] project: [$$55]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$C])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                      unnest-map [$$53, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$63, 1, $$63, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$63])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$63)
                               -- STABLE_SORT [$$63(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$63])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDates)  |PARTITIONED|
+                                      unnest-map [$$62, $$63] <- index-search("IdxYelpCheckinDates", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$60, 1, $$61, false, false, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$60, $$61] <- ["2016", "2017"]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/with-composite-sk/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/with-composite-sk/query1.plan
index 560f87d..09847b9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/with-composite-sk/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/array-index/select-unnest-queries/open/with-composite-sk/query1.plan
@@ -1,21 +1,42 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"business_id": $$35}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq("2016-04-26", $$D.getField("date")), eq("19:49:16", $$D.getField("time")))) project: [$$35]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$37) project: [$$35, $$D]
         -- UNNEST  |PARTITIONED|
+          select (eq("--1UhMGODdWsrMastO9DZw", $$35))
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$35, $$37] <- [$$C.getField("business_id"), $$C.getField("checkin_times")] project: [$$35, $$37]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestYelp.YelpCheckin.YelpCheckin)  |PARTITIONED|
+                  unnest-map [$$36, $$C] <- index-search("YelpCheckin", 0, "Default", "TestYelp", "YelpCheckin", false, false, 1, $$46, 1, $$46, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      distinct ([$$46])
                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$46)
                           -- STABLE_SORT [$$46(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$46])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (TestYelp.YelpCheckin.IdxYelpCheckinDatesTimes)  |PARTITIONED|
+                                  unnest-map [$$44, $$45, $$46] <- index-search("IdxYelpCheckinDatesTimes", 0, "Default", "TestYelp", "YelpCheckin", false, false, 2, $$40, $$41, 2, $$42, $$43, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$40, $$41, $$42, $$43] <- ["2016-04-26", "19:49:16", "2016-04-26", "19:49:16"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-3.plan
index 4e9bc29..b4cc0b8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-3.plan
@@ -1,23 +1,46 @@
+distribute result [$$39]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$39(ASC) ]  |PARTITIONED|
+    order (ASC, $$39)
     -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$36, $$tenk2.getField(7))) project: [$$39]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$39] <- [$$tenk2.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$36, $$tenk2])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk2.tenk2)  |PARTITIONED|
+                unnest-map [$$35, $$tenk2] <- index-search("tenk2", 0, "Default", "test", "tenk2", true, false, 1, $$45, 1, $$45, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$45)
                     -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$36, $$45])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk2.idx_tenk2_1k_2k)  |PARTITIONED|
+                            unnest-map [$$43, $$44, $$45] <- index-search("idx_tenk2_1k_2k", 0, "Default", "test", "tenk2", true, true, 1, $$36, 1, $$36, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$36] <- [$$tenk1.getField(7)] project: [$$36]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$tenk1])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.tenk1.tenk1)  |PARTITIONED|
+                                      unnest-map [$$34, $$tenk1] <- index-search("tenk1", 0, "Default", "test", "tenk1", false, false, 0, 1, $$40, true, false, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$40] <- [1]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-4.plan
index acfe0c3..066de35 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-4.plan
@@ -1,22 +1,44 @@
+distribute result [$$39]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$39(ASC) ]  |PARTITIONED|
+    order (ASC, $$39)
     -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        project ([$$39])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$36, $$37))
             -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                assign [$$36] <- [$$tenk1.getField(7)] project: [$$36]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk1])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.tenk1.tenk1)  |PARTITIONED|
+                      unnest-map [$$34, $$tenk1] <- index-search("tenk1", 0, "Default", "test", "tenk1", false, false, 0, 1, $$40, true, false, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$40] <- [1]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                assign [$$39, $$37] <- [$$tenk2.getField(0), $$tenk2.getField(7)] project: [$$39, $$37]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk2])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.tenk2)  |PARTITIONED|
+                      data-scan []<-[$$35, $$tenk2] <- test.tenk2
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-5.plan
index acfe0c3..066de35 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-5.plan
@@ -1,22 +1,44 @@
+distribute result [$$39]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$39(ASC) ]  |PARTITIONED|
+    order (ASC, $$39)
     -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        project ([$$39])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$36, $$37))
             -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                assign [$$36] <- [$$tenk1.getField(7)] project: [$$36]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk1])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.tenk1.tenk1)  |PARTITIONED|
+                      unnest-map [$$34, $$tenk1] <- index-search("tenk1", 0, "Default", "test", "tenk1", false, false, 0, 1, $$40, true, false, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$40] <- [1]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                assign [$$39, $$37] <- [$$tenk2.getField(0), $$tenk2.getField(7)] project: [$$39, $$37]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk2])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.tenk2)  |PARTITIONED|
+                      data-scan []<-[$$35, $$tenk2] <- test.tenk2
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-6.plan
index acfe0c3..066de35 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-6.plan
@@ -1,22 +1,44 @@
+distribute result [$$39]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$39(ASC) ]  |PARTITIONED|
+    order (ASC, $$39)
     -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        project ([$$39])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$36, $$37))
             -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                assign [$$36] <- [$$tenk1.getField(7)] project: [$$36]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk1])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.tenk1.tenk1)  |PARTITIONED|
+                      unnest-map [$$34, $$tenk1] <- index-search("tenk1", 0, "Default", "test", "tenk1", false, false, 0, 1, $$40, true, false, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$40] <- [1]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                assign [$$39, $$37] <- [$$tenk2.getField(0), $$tenk2.getField(7)] project: [$$39, $$37]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk2])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.tenk2)  |PARTITIONED|
+                      data-scan []<-[$$35, $$tenk2] <- test.tenk2
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-7.plan
index acfe0c3..066de35 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-7.plan
@@ -1,22 +1,44 @@
+distribute result [$$39]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$39(ASC) ]  |PARTITIONED|
+    order (ASC, $$39)
     -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        project ([$$39])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$36, $$37))
             -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                assign [$$36] <- [$$tenk1.getField(7)] project: [$$36]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk1])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.tenk1.tenk1)  |PARTITIONED|
+                      unnest-map [$$34, $$tenk1] <- index-search("tenk1", 0, "Default", "test", "tenk1", false, false, 0, 1, $$40, true, false, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$40] <- [1]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                assign [$$39, $$37] <- [$$tenk2.getField(0), $$tenk2.getField(7)] project: [$$39, $$37]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk2])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.tenk2)  |PARTITIONED|
+                      data-scan []<-[$$35, $$tenk2] <- test.tenk2
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-8.plan
index 8c3f5e9..c089daa 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/hints-indexnl-params/hints-indexnl-params-8.plan
@@ -1,23 +1,46 @@
+distribute result [$$39]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$39(ASC) ]  |PARTITIONED|
+    order (ASC, $$39)
     -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$36, $$tenk2.getField(7))) project: [$$39]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$39] <- [$$tenk2.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$36, $$tenk2])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk2.tenk2)  |PARTITIONED|
+                unnest-map [$$35, $$tenk2] <- index-search("tenk2", 0, "Default", "test", "tenk2", true, false, 1, $$44, 1, $$44, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$44)
                     -- STABLE_SORT [$$44(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$36, $$44])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk2.idx_tenk2_1k)  |PARTITIONED|
+                            unnest-map [$$43, $$44] <- index-search("idx_tenk2_1k", 0, "Default", "test", "tenk2", true, true, 1, $$36, 1, $$36, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$36] <- [$$tenk1.getField(7)] project: [$$36]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$tenk1])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.tenk1.tenk1)  |PARTITIONED|
+                                      unnest-map [$$34, $$tenk1] <- index-search("tenk1", 0, "Default", "test", "tenk1", false, false, 0, 1, $$40, true, false, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$40] <- [1]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_ps.plan
index 53c684d..49a942e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_ps.plan
@@ -1,102 +1,198 @@
+distribute result [$$41]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$41] <- [{"tweetid1": $$53, "count1": $$69, "t2info": $$40}] project: [$$41]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$53)
         -- STABLE_SORT [$$53(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$53(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$73
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$70]  |PARTITIONED|
-                            {
+                    group by ([$$53 := $$70]) decor ([$$69]) {
+                              aggregate [$$40] <- [listify({"tweetid2": $$45, "count2": $$46})]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$45)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$70]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$70) (ASC, $$45)
                         -- STABLE_SORT [$$70(ASC), $$45(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$70]  |PARTITIONED|
+                            union ($$66, $$58, $$45) ($$68, $$57, $$46) ($$47, $$47, $$69) ($$44, $$44, $$70)
                             -- UNION_ALL  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (eq($$47, $$68)) retain-untrue ($$66 <- missing) project: [$$66, $$68, $$47, $$44]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$68] <- [$$67.getField(7)] project: [$$44, $$47, $$57, $$58, $$66, $$68]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                      left-outer-unnest-map [$$66, $$67] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$58, 1, $$58, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$44, $$47, $$57, $$58])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              split ($$59)
                                               -- SPLIT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                  left-outer-unnest-map [$$57, $$58, $$59] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$47, 1, $$47, true, true, true)
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    exchange
                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                      assign [$$47] <- [$$t1.getField(6)] project: [$$44, $$47]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                          unnest-map [$$44, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$54, true, false, false)
+                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              assign [$$54] <- [10]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (eq($$47, $$57)) retain-untrue ($$58 <- missing) project: [$$58, $$57, $$47, $$44]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  project ([$$44, $$47, $$57, $$58])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      split ($$59)
                                       -- SPLIT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                          left-outer-unnest-map [$$57, $$58, $$59] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$47, 1, $$47, true, true, true)
+                                          -- BTREE_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              assign [$$47] <- [$$t1.getField(6)] project: [$$44, $$47]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                  unnest-map [$$44, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$54, true, false, false)
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      assign [$$54] <- [10]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$73] <- [agg-range-map($$71, $$72)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$71, $$72] <- [agg-local-sampling($$53), agg-null-writer($$53)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$53])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$70]  |PARTITIONED|
-                                      {
+                              group by ([$$53 := $$70]) decor ([$$69]) {
+                                        aggregate [$$40] <- [listify({"tweetid2": $$45, "count2": $$46})]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$45)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$70]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$70) (ASC, $$45)
                                   -- STABLE_SORT [$$70(ASC), $$45(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$70]  |PARTITIONED|
+                                      union ($$66, $$58, $$45) ($$68, $$57, $$46) ($$47, $$47, $$69) ($$44, $$44, $$70)
                                       -- UNION_ALL  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          select (eq($$47, $$68)) retain-untrue ($$66 <- missing) project: [$$66, $$68, $$47, $$44]
                                           -- STREAM_SELECT  |PARTITIONED|
+                                            assign [$$68] <- [$$67.getField(7)] project: [$$44, $$47, $$57, $$58, $$66, $$68]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                left-outer-unnest-map [$$66, $$67] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$58, 1, $$58, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    project ([$$44, $$47, $$57, $$58])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        split ($$59)
                                                         -- SPLIT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                            left-outer-unnest-map [$$57, $$58, $$59] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$47, 1, $$47, true, true, true)
+                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                              exchange
                                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                assign [$$47] <- [$$t1.getField(6)] project: [$$44, $$47]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                    unnest-map [$$44, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$54, true, false, false)
+                                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        assign [$$54] <- [10]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          select (eq($$47, $$57)) retain-untrue ($$58 <- missing) project: [$$58, $$57, $$47, $$44]
                                           -- STREAM_SELECT  |PARTITIONED|
+                                            project ([$$44, $$47, $$57, $$58])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                split ($$59)
                                                 -- SPLIT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                    left-outer-unnest-map [$$57, $$58, $$59] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$47, 1, $$47, true, true, true)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        assign [$$47] <- [$$t1.getField(6)] project: [$$44, $$47]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                            unnest-map [$$44, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$54, true, false, false)
+                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                assign [$$54] <- [10]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02.plan
index 78dd14c..6e61876 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02.plan
@@ -1,31 +1,59 @@
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"tweetid1": $$58, "count1": $$52, "t2info": $$44}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$58(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
-                {
+        group by ([$$58 := $$48]) decor ([$$52]) {
+                  aggregate [$$44] <- [listify({"tweetid2": $$49, "count2": $$51})]
                   -- AGGREGATE  |LOCAL|
+                    select (not(is-missing($$49)))
                     -- STREAM_SELECT  |LOCAL|
+                      nested tuple source
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$48) (ASC, $$49)
             -- STABLE_SORT [$$48(ASC), $$49(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+                select (and(eq($$52, $$51), neq($$48, $$49))) retain-untrue ($$49 <- missing)
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$51] <- [$$t2.getField(7)] project: [$$52, $$48, $$49, $$51]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$52, $$48, $$49, $$t2])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                        left-outer-unnest-map [$$49, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$63, 1, $$63, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$63)
                             -- STABLE_SORT [$$63(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$52, $$48, $$63])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                    left-outer-unnest-map [$$62, $$63] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$52, 1, $$52, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        assign [$$52] <- [$$t1.getField(6)] project: [$$48, $$52]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                            unnest-map [$$48, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$59, true, false, false)
+                                            -- BTREE_SEARCH  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                assign [$$59] <- [10]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_ps.plan
index 65e8723..cb4a6c9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_ps.plan
@@ -1,72 +1,138 @@
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"tweetid1": $$58, "count1": $$52, "t2info": $$44}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$58)
         -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$58(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$66
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
-                            {
+                    group by ([$$58 := $$48]) decor ([$$52]) {
+                              aggregate [$$44] <- [listify({"tweetid2": $$49, "count2": $$51})]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$49)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$48) (ASC, $$49)
                         -- STABLE_SORT [$$48(ASC), $$49(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+                            select (and(eq($$52, $$51), neq($$48, $$49))) retain-untrue ($$49 <- missing)
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$51] <- [$$t2.getField(7)] project: [$$52, $$48, $$49, $$51]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$52, $$48, $$49, $$t2])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                    left-outer-unnest-map [$$49, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$63, 1, $$63, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$63)
                                         -- STABLE_SORT [$$63(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$52, $$48, $$63])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                left-outer-unnest-map [$$62, $$63] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$52, 1, $$52, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$52] <- [$$t1.getField(6)] project: [$$48, $$52]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                        unnest-map [$$48, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$59, true, false, false)
+                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            assign [$$59] <- [10]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$66] <- [agg-range-map($$64, $$65)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$64, $$65] <- [agg-local-sampling($$58), agg-null-writer($$58)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$58])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
-                                      {
+                              group by ([$$58 := $$48]) decor ([$$52]) {
+                                        aggregate [$$44] <- [listify({"tweetid2": $$49, "count2": $$51})]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$49)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$48) (ASC, $$49)
                                   -- STABLE_SORT [$$48(ASC), $$49(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+                                      select (and(eq($$52, $$51), neq($$48, $$49))) retain-untrue ($$49 <- missing)
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        assign [$$51] <- [$$t2.getField(7)] project: [$$52, $$48, $$49, $$51]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$52, $$48, $$49, $$t2])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                              left-outer-unnest-map [$$49, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$63, 1, $$63, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  order (ASC, $$63)
                                                   -- STABLE_SORT [$$63(ASC)]  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      project ([$$52, $$48, $$63])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                          left-outer-unnest-map [$$62, $$63] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$52, 1, $$52, true, true, true)
+                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                              assign [$$52] <- [$$t1.getField(6)] project: [$$48, $$52]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                  unnest-map [$$48, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$59, true, false, false)
+                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      assign [$$59] <- [10]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_03-index-only.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_03-index-only.plan
index 3ad3f60..dea08b7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_03-index-only.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_03-index-only.plan
@@ -1,44 +1,88 @@
+distribute result [$$37]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$37] <- [{"tweetid1": $$67, "count1": $$68, "tweetid2": $$42, "count2": $$44}] project: [$$37]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$67(ASC), $$42(ASC) ]  |PARTITIONED|
+        order (ASC, $$67) (ASC, $$42)
         -- STABLE_SORT [$$67(ASC), $$42(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select ($$69) project: [$$67, $$68, $$42, $$44]
             -- STREAM_SELECT  |PARTITIONED|
+              window-aggregate [$$69] <- [win-mark-first-missing-impl($$42)] partition [$$67] order (DESC, $$42)
               -- WINDOW_STREAM  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$67) (DESC, $$42)
                   -- STABLE_SORT [$$67(ASC), $$42(DESC)]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$67]  |PARTITIONED|
+                      union ($$64, $$56, $$42) ($$66, $$55, $$44) ($$41, $$41, $$67) ($$43, $$43, $$68)
                       -- UNION_ALL  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          select (eq($$43, $$66)) retain-untrue ($$64 <- missing) project: [$$64, $$66, $$41, $$43]
                           -- STREAM_SELECT  |PARTITIONED|
+                            assign [$$66] <- [$$65.getField(7)] project: [$$41, $$43, $$55, $$56, $$64, $$66]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                left-outer-unnest-map [$$64, $$65] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$56, 1, $$56, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$41, $$43, $$55, $$56])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        split ($$57)
                                         -- SPLIT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                            left-outer-unnest-map [$$55, $$56, $$57] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$43, 1, $$43, true, true, true)
+                                            -- BTREE_SEARCH  |PARTITIONED|
+                                              exchange
                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                assign [$$43] <- [$$t1.getField(6)] project: [$$41, $$43]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                    unnest-map [$$41, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$52, true, false, false)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        assign [$$52] <- [10]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          select (eq($$43, $$55)) retain-untrue ($$56 <- missing) project: [$$56, $$55, $$41, $$43]
                           -- STREAM_SELECT  |PARTITIONED|
+                            project ([$$41, $$43, $$55, $$56])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                split ($$57)
                                 -- SPLIT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                    left-outer-unnest-map [$$55, $$56, $$57] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$43, 1, $$43, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        assign [$$43] <- [$$t1.getField(6)] project: [$$41, $$43]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                            unnest-map [$$41, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$52, true, false, false)
+                                            -- BTREE_SEARCH  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                assign [$$52] <- [10]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_03.plan
index f6df175..8c47cba 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_03.plan
@@ -1,29 +1,58 @@
+distribute result [$$37]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$37] <- [{"tweetid1": $$41, "count1": $$43, "tweetid2": $$42, "count2": $$44}] project: [$$37]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$41(ASC), $$42(ASC) ]  |PARTITIONED|
+        order (ASC, $$41) (ASC, $$42)
         -- STABLE_SORT [$$41(ASC), $$42(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select ($$57) project: [$$41, $$43, $$42, $$44]
             -- STREAM_SELECT  |PARTITIONED|
+              window-aggregate [$$57] <- [win-mark-first-missing-impl($$42)] partition [$$41] order (DESC, $$42)
               -- WINDOW_STREAM  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$41) (DESC, $$42)
                   -- STABLE_SORT [$$41(ASC), $$42(DESC)]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$41]  |PARTITIONED|
+                      select (eq($$43, $$44)) retain-untrue ($$42 <- missing)
                       -- STREAM_SELECT  |PARTITIONED|
+                        assign [$$44] <- [$$t2.getField(7)] project: [$$41, $$43, $$42, $$44]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$41, $$43, $$42, $$t2])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                              left-outer-unnest-map [$$42, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$56, 1, $$56, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$56)
                                   -- STABLE_SORT [$$56(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$41, $$43, $$56])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                          left-outer-unnest-map [$$55, $$56] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$43, 1, $$43, true, true, true)
+                                          -- BTREE_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              assign [$$43] <- [$$t1.getField(6)] project: [$$41, $$43]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                  unnest-map [$$41, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$52, true, false, false)
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      assign [$$52] <- [10]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/primary-between-join_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/primary-between-join_01.plan
index 7d21217..8a9783a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/primary-between-join_01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/primary-between-join_01.plan
@@ -1,13 +1,26 @@
+distribute result [$$x]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$x])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BTREE_SEARCH (test1.DsTwo.DsTwo)  |PARTITIONED|
+        unnest-map [$$33, $$y] <- index-search("DsTwo", 0, "Default", "test1", "DsTwo", true, true, 0, 1, $$31, true, true, false)
+        -- BTREE_SEARCH  |PARTITIONED|
+          exchange
           -- BROADCAST_EXCHANGE  |PARTITIONED|
+            select (le($$31, 10))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$31] <- [$$x.getField(1)]
               -- ASSIGN  |PARTITIONED|
+                project ([$$x])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test1.DsOne)  |PARTITIONED|
+                    data-scan []<-[$$32, $$x] <- test1.DsOne
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/primary-equi-join_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/primary-equi-join_04.plan
index 528f21e..659441b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/primary-equi-join_04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/primary-equi-join_04.plan
@@ -1,15 +1,30 @@
+distribute result [$$29]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"customer": $$c, "order": $$o}] project: [$$29]
     -- ASSIGN  |PARTITIONED|
+      project ([$$o, $$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$31, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", true, true, 1, $$32, 1, $$32, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$32)
               -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
+                  assign [$$32] <- [$$o.getField(1)]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$o])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
+                        data-scan []<-[$$30, $$o] <- test.Orders
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join-multiindex.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join-multiindex.plan
index 8f2091d..076ddfb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join-multiindex.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join-multiindex.plan
@@ -1,20 +1,40 @@
+distribute result [$$38]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$38] <- [{"fbu-ID": $$40, "fbm-auth-ID": $$message.getField(2), "uname": $$44, "message": $$message.getField(6)}] project: [$$38]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$40, $$message.getField(3)))
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$40, $$44, $$message])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.FacebookMessages.FacebookMessages)  |PARTITIONED|
+            unnest-map [$$41, $$message] <- index-search("FacebookMessages", 0, "Default", "test", "FacebookMessages", true, false, 1, $$51, 1, $$51, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$51)
                 -- STABLE_SORT [$$51(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$40, $$44, $$51])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.FacebookMessages.fbmIdxAutId)  |PARTITIONED|
+                        unnest-map [$$50, $$51] <- index-search("fbmIdxAutId", 0, "Default", "test", "FacebookMessages", true, true, 1, $$40, 1, $$40, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$44] <- [$$user.getField(3)] project: [$$40, $$44]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.FacebookUsers.FacebookUsers)  |PARTITIONED|
+                                unnest-map [$$40, $$user] <- index-search("FacebookUsers", 0, "Default", "test", "FacebookUsers", false, false, 1, $$46, 1, $$47, true, true, false)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$46, $$47] <- [11000, 12000]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_02.plan
index 4959113..726b0e9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_02.plan
@@ -1,20 +1,40 @@
+distribute result [$$29]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"arec": $$a, "brec": $$b}] project: [$$29]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$32, $$b.getField(2))) project: [$$a, $$b]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$a, $$32, $$b])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+            unnest-map [$$31, $$b] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$35, 1, $$35, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$35)
                 -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$a, $$32, $$35])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.CSX.title_index)  |PARTITIONED|
+                        unnest-map [$$34, $$35] <- index-search("title_index", 0, "Default", "test", "CSX", true, true, 1, $$32, 1, $$32, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$32] <- [$$a.getField(2)]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$a])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                  data-scan []<-[$$30, $$a] <- test.DBLP
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_03.plan
index bd949cc..50b3056 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_03.plan
@@ -1,20 +1,40 @@
+distribute result [$$29]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"arec": $$a, "brec": $$b}] project: [$$29]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$32, $$b.getField(2))) project: [$$a, $$b]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$a, $$32, $$b])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+            unnest-map [$$31, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$35, 1, $$35, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$35)
                 -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$a, $$32, $$35])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.DBLP.title_index)  |PARTITIONED|
+                        unnest-map [$$34, $$35] <- index-search("title_index", 0, "Default", "test", "DBLP", true, true, 1, $$32, 1, $$32, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$32] <- [$$a.getField(2)]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$a])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                  data-scan []<-[$$30, $$a] <- test.DBLP
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_04.plan
index b75b258..98d370e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_04.plan
@@ -1,31 +1,62 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"a": $$a, "b": $$b, "c": $$c}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$45, $$c.getField(1))) project: [$$a, $$b, $$c]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$a, $$b, $$45, $$c])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.testdst3.testdst3)  |PARTITIONED|
+            unnest-map [$$48, $$c] <- index-search("testdst3", 0, "Default", "test", "testdst3", true, false, 1, $$52, 1, $$52, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$52)
                 -- STABLE_SORT [$$52(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$a, $$b, $$45, $$52])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.testdst3.sec3_Idx)  |PARTITIONED|
+                        unnest-map [$$51, $$52] <- index-search("sec3_Idx", 0, "Default", "test", "testdst3", true, true, 1, $$45, 1, $$45, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            project ([$$a, $$b, $$45])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$49, $$45))
                                 -- HYBRID_HASH_JOIN [$$49][$$45]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$49]  |PARTITIONED|
+                                    assign [$$49] <- [$$a.getField(1)]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$a])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+                                          data-scan []<-[$$46, $$a] <- test.testdst
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$45]  |PARTITIONED|
+                                    assign [$$45] <- [$$b.getField(1)]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$b])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.testdst2)  |PARTITIONED|
+                                          data-scan []<-[$$47, $$b] <- test.testdst2
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_05.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_05.plan
index 66d63f1..253d23b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_05.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_05.plan
@@ -1,17 +1,34 @@
+distribute result [$$28]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$28] <- [{"bar": $$bar, "testdst": $$testdst}] project: [$$28]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$bar, $$testdst.getField(1)))
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$bar, $$testdst])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+            unnest-map [$$29, $$testdst] <- index-search("testdst", 0, "Default", "test", "testdst", true, false, 1, $$33, 1, $$33, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$33)
                 -- STABLE_SORT [$$33(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$bar, $$33])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                        unnest-map [$$32, $$33] <- index-search("sec_Idx", 0, "Default", "test", "testdst", true, true, 1, $$34, 1, $$34, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$34] <- [cast-lax($$bar)]
                             -- ASSIGN  |UNPARTITIONED|
+                              unnest $$bar <- scan-collection(array: [ 1, 2, 3 ])
                               -- UNNEST  |UNPARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_06.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_06.plan
index f2dbe69..994d92a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_06.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-join/secondary-equi-join_06.plan
@@ -1,34 +1,62 @@
+distribute result [$$75]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$75] <- [{"bar": $$68, "testdst2": $$testdst2}] project: [$$75]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$val, $$testdst2.getField(1))) project: [$$68, $$testdst2]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$68, $$val, $$testdst2])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.testdst2.testdst2)  |PARTITIONED|
+            unnest-map [$$78, $$testdst2] <- index-search("testdst2", 0, "Default", "test", "testdst2", true, false, 1, $$85, 1, $$85, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$85)
                 -- STABLE_SORT [$$85(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$68, $$val, $$85])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.testdst2.sec_Idx)  |PARTITIONED|
+                        unnest-map [$$84, $$85] <- index-search("sec_Idx", 0, "Default", "test", "testdst2", true, true, 1, $$val, 1, $$val, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$68] <- [{"val": $$val, "$1": $$81}] project: [$$val, $$68]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- SORT_GROUP_BY[$$83]  |PARTITIONED|
-                                        {
+                                group by ([$$val := $$83]) decor ([]) {
+                                          aggregate [$$81] <- [agg-sql-sum($$82)]
                                           -- AGGREGATE  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- SORT_GROUP_BY[$$83]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$83]  |PARTITIONED|
-                                    -- SORT_GROUP_BY[$$76]  |PARTITIONED|
-                                            {
+                                    group by ([$$83 := $$76]) decor ([]) {
+                                              aggregate [$$82] <- [agg-sql-count(1)]
                                               -- AGGREGATE  |LOCAL|
+                                                nested tuple source
                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                           }
+                                    -- SORT_GROUP_BY[$$76]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$76] <- [$$testdst.getField(1)] project: [$$76]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$testdst])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+                                              data-scan []<-[$$77, $$testdst] <- test.testdst
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/btree-index-composite-key-04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/btree-index-composite-key-04.plan
index f55b79e..466882a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/btree-index-composite-key-04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/btree-index-composite-key-04.plan
@@ -1,29 +1,58 @@
+distribute result [$$19]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"id": $$22, "fname": $$21, "lname": $$25}] project: [$$19]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$22(ASC) ]  |PARTITIONED|
+        order (ASC, $$22)
         -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            union ($$36, $$30, $$22) ($$38, $$28, $$21) ($$39, $$29, $$25)
             -- UNION_ALL  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (eq($$38, "A")) project: [$$36, $$38, $$39]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$39, $$38] <- [$$37.getField(2), $$37.getField(1)] project: [$$36, $$39, $$38]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.employee.employee)  |PARTITIONED|
+                      unnest-map [$$36, $$37] <- index-search("employee", 0, "Default", "test", "employee", false, false, 1, $$30, 1, $$30, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          split ($$31)
                           -- SPLIT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.employee.idx_employee_f_l_name)  |PARTITIONED|
+                              unnest-map [$$28, $$29, $$30, $$31] <- index-search("idx_employee_f_l_name", 0, "Default", "test", "employee", false, false, 1, $$26, 1, $$27, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$26, $$27] <- ["A", "A"]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (eq($$28, "A")) project: [$$30, $$28, $$29]
                 -- STREAM_SELECT  |PARTITIONED|
+                  project ([$$28, $$29, $$30])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      split ($$31)
                       -- SPLIT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.employee.idx_employee_f_l_name)  |PARTITIONED|
+                          unnest-map [$$28, $$29, $$30, $$31] <- index-search("idx_employee_f_l_name", 0, "Default", "test", "employee", false, false, 1, $$26, 1, $$27, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$26, $$27] <- ["A", "A"]
                               -- ASSIGN  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-01.plan
index c7e7795..030ed52 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-01.plan
@@ -1,12 +1,24 @@
+distribute result [$$58]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$58] <- [{"id": $$61, "x": $$72, "y": int64-default-null($$64)}] project: [$$58]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$61(ASC) ]  |PARTITIONED|
+        order (ASC, $$61)
         -- STABLE_SORT [$$61(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (le($$72, 1))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$72, $$64] <- [int64-default-null($$ds1.getField("x")), $$ds1.getField("y")] project: [$$61, $$72, $$64]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds1)  |PARTITIONED|
+                  data-scan []<-[$$61, $$ds1] <- test.ds1
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-02.plan
index cc2475f..476291d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-02.plan
@@ -1,19 +1,38 @@
+distribute result [$$58]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$58] <- [{"id": $$61, "x": $$75, "y": int64-default-null($$64)}] project: [$$58]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$61(ASC) ]  |PARTITIONED|
+        order (ASC, $$61)
         -- STABLE_SORT [$$61(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (le($$75, 1))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$75, $$64] <- [int64-default-null($$ds2.getField("x")), $$ds2.getField("y")] project: [$$61, $$75, $$64]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.ds2.ds2)  |PARTITIONED|
+                  unnest-map [$$61, $$ds2] <- index-search("ds2", 0, "Default", "test", "ds2", false, false, 1, $$74, 1, $$74, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$74)
                       -- STABLE_SORT [$$74(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$74])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.ds2.idx2)  |PARTITIONED|
+                              unnest-map [$$73, $$74] <- index-search("idx2", 0, "Default", "test", "ds2", false, false, 0, 1, $$72, true, true, false)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$72] <- [1]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-03.plan
index efabbca..2faff22 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-03.plan
@@ -1,12 +1,24 @@
+distribute result [$$58]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$58] <- [{"id": $$61, "x": $$72, "y": int64-default-null($$64)}] project: [$$58]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$61(ASC) ]  |PARTITIONED|
+        order (ASC, $$61)
         -- STABLE_SORT [$$61(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (le($$72, "1"))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$72, $$64] <- [string-default-null($$ds3.getField("x")), $$ds3.getField("y")] project: [$$61, $$72, $$64]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds3)  |PARTITIONED|
+                  data-scan []<-[$$61, $$ds3] <- test.ds3
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-04.plan
index 190d315..c7b669e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-04.plan
@@ -1,12 +1,24 @@
+distribute result [$$19]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"id": $$22, "x": $$21, "y": $$25}] project: [$$19]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$22(ASC) ]  |PARTITIONED|
+        order (ASC, $$22)
         -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (le($$21, 1))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25, $$21] <- [$$ds3.getField("y"), $$ds3.getField("x")] project: [$$22, $$25, $$21]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds3)  |PARTITIONED|
+                  data-scan []<-[$$22, $$ds3] <- test.ds3
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-05.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-05.plan
index a0fb880..83fb7d6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-05.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-05.plan
@@ -1,24 +1,48 @@
+distribute result [$$127]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$127] <- [{"v4x": $$128, "v2x": $$129}] project: [$$127]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$128(ASC), $$129(ASC) ]  |PARTITIONED|
+        order (ASC, $$128) (ASC, $$129)
         -- STABLE_SORT [$$128(ASC), $$129(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$128, $$129))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$129] <- [int64-default-null($$ds2.getField("x"))] project: [$$128, $$129]
               -- ASSIGN  |PARTITIONED|
+                project ([$$128, $$ds2])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.ds2.ds2)  |PARTITIONED|
+                    unnest-map [$$131, $$ds2] <- index-search("ds2", 0, "Default", "test", "ds2", true, false, 1, $$145, 1, $$145, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$145)
                         -- STABLE_SORT [$$145(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$128, $$145])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.ds2.idx2)  |PARTITIONED|
+                                unnest-map [$$144, $$145] <- index-search("idx2", 0, "Default", "test", "ds2", true, true, 1, $$128, 1, $$128, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$128] <- [int64-default-null($$ds4.getField("x"))] project: [$$128]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$ds4])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.ds4)  |PARTITIONED|
+                                          data-scan []<-[$$130, $$ds4] <- test.ds4
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-06.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-06.plan
index af975ab..b657914 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-06.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-06.plan
@@ -1,21 +1,42 @@
+distribute result [$$127]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$127] <- [{"v4x": $$128, "v3x": $$129}] project: [$$127]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$128(ASC), $$129(ASC) ]  |PARTITIONED|
+        order (ASC, $$128) (ASC, $$129)
         -- STABLE_SORT [$$128(ASC), $$129(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$128, $$129))
             -- HYBRID_HASH_JOIN [$$128][$$129]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$128]  |PARTITIONED|
+                assign [$$128] <- [int64-default-null($$ds4.getField("x"))] project: [$$128]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$ds4])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.ds4)  |PARTITIONED|
+                      data-scan []<-[$$130, $$ds4] <- test.ds4
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$129]  |PARTITIONED|
+                assign [$$129] <- [string-default-null($$ds3.getField("x"))] project: [$$129]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$ds3])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.ds3)  |PARTITIONED|
+                      data-scan []<-[$$131, $$ds3] <- test.ds3
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-07.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-07.plan
index 340321d..5ac7a49 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-07.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-07.plan
@@ -1,21 +1,42 @@
+distribute result [$$127]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$127] <- [{"v4x": $$128, "v1x": $$129}] project: [$$127]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$128(ASC), $$129(ASC) ]  |PARTITIONED|
+        order (ASC, $$128) (ASC, $$129)
         -- STABLE_SORT [$$128(ASC), $$129(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$128, $$129))
             -- HYBRID_HASH_JOIN [$$128][$$129]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$128]  |PARTITIONED|
+                assign [$$128] <- [int64-default-null($$ds4.getField("x"))] project: [$$128]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$ds4])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.ds4)  |PARTITIONED|
+                      data-scan []<-[$$130, $$ds4] <- test.ds4
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$129]  |PARTITIONED|
+                assign [$$129] <- [int64-default-null($$ds1.getField("x"))] project: [$$129]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$ds1])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.ds1)  |PARTITIONED|
+                      data-scan []<-[$$131, $$ds1] <- test.ds1
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-08.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-08.plan
index 340321d..5ac7a49 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-08.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-08.plan
@@ -1,21 +1,42 @@
+distribute result [$$127]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$127] <- [{"v4x": $$128, "v1x": $$129}] project: [$$127]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$128(ASC), $$129(ASC) ]  |PARTITIONED|
+        order (ASC, $$128) (ASC, $$129)
         -- STABLE_SORT [$$128(ASC), $$129(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$128, $$129))
             -- HYBRID_HASH_JOIN [$$128][$$129]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$128]  |PARTITIONED|
+                assign [$$128] <- [int64-default-null($$ds4.getField("x"))] project: [$$128]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$ds4])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.ds4)  |PARTITIONED|
+                      data-scan []<-[$$130, $$ds4] <- test.ds4
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$129]  |PARTITIONED|
+                assign [$$129] <- [int64-default-null($$ds1.getField("x"))] project: [$$129]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$ds1])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.ds1)  |PARTITIONED|
+                      data-scan []<-[$$131, $$ds1] <- test.ds1
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-09.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-09.plan
index d162de1..8578e6b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-09.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-09.plan
@@ -1,21 +1,42 @@
+distribute result [$$88]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$88] <- [{"v4x": $$89, "ds2x": $$90}] project: [$$88]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$89(ASC), $$90(ASC) ]  |PARTITIONED|
+        order (ASC, $$89) (ASC, $$90)
         -- STABLE_SORT [$$89(ASC), $$90(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$89, $$90))
             -- HYBRID_HASH_JOIN [$$89][$$90]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$89]  |PARTITIONED|
+                assign [$$89] <- [int64-default-null($$ds4.getField("x"))] project: [$$89]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$ds4])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.ds4)  |PARTITIONED|
+                      data-scan []<-[$$91, $$ds4] <- test.ds4
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$90]  |PARTITIONED|
+                assign [$$90] <- [$$ds2.getField("x")] project: [$$90]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$ds2])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.ds2)  |PARTITIONED|
+                      data-scan []<-[$$92, $$ds2] <- test.ds2
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-10.plan
index 588a92a..f6428bb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-10.plan
@@ -1,19 +1,38 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"id": $$50, "f_dt_fmt": $$62}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
+        order (ASC, $$50)
         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$62, datetime: { 2020-12-20T00:00:00.000 }))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$62] <- [datetime-default-null($$ds5.getField("f_dt_fmt"), "MM/DD/YYYY hh:mm:ss.nnna")] project: [$$50, $$62]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.ds5.ds5)  |PARTITIONED|
+                  unnest-map [$$50, $$ds5] <- index-search("ds5", 0, "Default", "test", "ds5", false, false, 1, $$61, 1, $$61, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$61)
                       -- STABLE_SORT [$$61(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$61])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.ds5.idx5_dt_fmt)  |PARTITIONED|
+                              unnest-map [$$60, $$61] <- index-search("idx5_dt_fmt", 0, "Default", "test", "ds5", false, false, 0, 1, $$59, true, false, false)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$59] <- [datetime: { 2020-12-20T00:00:00.000 }]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-11.plan
index 918da4d..2121373 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-11.plan
@@ -1,19 +1,38 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"id": $$50, "f_d_fmt": $$62}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
+        order (ASC, $$50)
         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$62, date: { 2020-12-20 }))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$62] <- [date-default-null($$ds5.getField("f_d_fmt"), "MM/DD/YYYY")] project: [$$50, $$62]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.ds5.ds5)  |PARTITIONED|
+                  unnest-map [$$50, $$ds5] <- index-search("ds5", 0, "Default", "test", "ds5", false, false, 1, $$61, 1, $$61, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$61)
                       -- STABLE_SORT [$$61(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$61])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.ds5.idx5_d_fmt)  |PARTITIONED|
+                              unnest-map [$$60, $$61] <- index-search("idx5_d_fmt", 0, "Default", "test", "ds5", false, false, 0, 1, $$59, true, false, false)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$59] <- [date: { 2020-12-20 }]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-12.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-12.plan
index 372ef30..6fa6254 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-12.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-12.plan
@@ -1,19 +1,38 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"id": $$50, "f_t_fmt": $$62}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
+        order (ASC, $$50)
         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$62, time: { 18:13:03.000 }))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$62] <- [time-default-null($$ds5.getField("f_t_fmt"), "hh:mm:ss.nnna")] project: [$$50, $$62]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.ds5.ds5)  |PARTITIONED|
+                  unnest-map [$$50, $$ds5] <- index-search("ds5", 0, "Default", "test", "ds5", false, false, 1, $$61, 1, $$61, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$61)
                       -- STABLE_SORT [$$61(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$61])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.ds5.idx5_t_fmt)  |PARTITIONED|
+                              unnest-map [$$60, $$61] <- index-search("idx5_t_fmt", 0, "Default", "test", "ds5", false, false, 0, 1, $$59, true, false, false)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$59] <- [time: { 18:13:03.000 }]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-13.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-13.plan
index f03306d..912e020 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-13.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-13.plan
@@ -1,19 +1,38 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"id": $$50, "f_dt": $$62}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
+        order (ASC, $$50)
         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$62, datetime: { 2020-12-20T00:00:00.000 }))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$62] <- [datetime-default-null($$ds6.getField("f_dt"))] project: [$$50, $$62]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.ds6.ds6)  |PARTITIONED|
+                  unnest-map [$$50, $$ds6] <- index-search("ds6", 0, "Default", "test", "ds6", false, false, 1, $$61, 1, $$61, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$61)
                       -- STABLE_SORT [$$61(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$61])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.ds6.idx6_dt)  |PARTITIONED|
+                              unnest-map [$$60, $$61] <- index-search("idx6_dt", 0, "Default", "test", "ds6", false, false, 0, 1, $$59, true, false, false)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$59] <- [datetime: { 2020-12-20T00:00:00.000 }]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-14.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-14.plan
index 40197ad..a9bae93 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-14.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-14.plan
@@ -1,19 +1,38 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"id": $$50, "f_d": $$62}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
+        order (ASC, $$50)
         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$62, date: { 2020-12-20 }))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$62] <- [date-default-null($$ds6.getField("f_d"))] project: [$$50, $$62]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.ds6.ds6)  |PARTITIONED|
+                  unnest-map [$$50, $$ds6] <- index-search("ds6", 0, "Default", "test", "ds6", false, false, 1, $$61, 1, $$61, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$61)
                       -- STABLE_SORT [$$61(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$61])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.ds6.idx6_d)  |PARTITIONED|
+                              unnest-map [$$60, $$61] <- index-search("idx6_d", 0, "Default", "test", "ds6", false, false, 0, 1, $$59, true, false, false)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$59] <- [date: { 2020-12-20 }]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-15.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-15.plan
index 9f5ad1b..499bb49 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-15.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-15.plan
@@ -1,19 +1,38 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"id": $$50, "f_t": $$62}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
+        order (ASC, $$50)
         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$62, time: { 18:13:03.000 }))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$62] <- [time-default-null($$ds6.getField("f_t"))] project: [$$50, $$62]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.ds6.ds6)  |PARTITIONED|
+                  unnest-map [$$50, $$ds6] <- index-search("ds6", 0, "Default", "test", "ds6", false, false, 1, $$61, 1, $$61, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$61)
                       -- STABLE_SORT [$$61(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$61])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.ds6.idx6_t)  |PARTITIONED|
+                              unnest-map [$$60, $$61] <- index-search("idx6_t", 0, "Default", "test", "ds6", false, false, 0, 1, $$59, true, false, false)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$59] <- [time: { 18:13:03.000 }]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-16.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-16.plan
index 9e04d8e..17643ee 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-16.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-16.plan
@@ -1,12 +1,24 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"id": $$50, "f_dt_fmt": $$59}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
+        order (ASC, $$50)
         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$59, datetime: { 2020-12-20T00:00:00.000 }))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$59] <- [datetime-default-null($$ds5.getField("f_dt_fmt"), "MM-DD-YYYY hh:mm:ss.nnna")] project: [$$50, $$59]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds5)  |PARTITIONED|
+                  data-scan []<-[$$50, $$ds5] <- test.ds5
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-17.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-17.plan
index c488edd..b0031eb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-17.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-17.plan
@@ -1,12 +1,24 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"id": $$50, "f_d": $$59}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
+        order (ASC, $$50)
         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$59, date: { 2020-12-20 }))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$59] <- [date-default-null($$ds6.getField("f_d"))] project: [$$50, $$59]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds6)  |PARTITIONED|
+                  data-scan []<-[$$50, $$ds6] <- test.ds6
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-18.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-18.plan
index 9e04d8e..8b5b16b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-18.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-18.plan
@@ -1,12 +1,24 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"id": $$50, "f_t_fmt": $$59}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
+        order (ASC, $$50)
         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$59, time: { 18:13:03.000 }))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$59] <- [time-default-null($$ds5.getField("f_t_fmt"), "hh:mm:ss.nnna")] project: [$$50, $$59]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds5)  |PARTITIONED|
+                  data-scan []<-[$$50, $$ds5] <- test.ds5
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-19.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-19.plan
index 1587d66..6b4ace6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-19.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-19.plan
@@ -1,24 +1,48 @@
+distribute result [$$115]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$115] <- [{"v6f_dt": $$116, "v5f_dt_fmt": $$117}] project: [$$115]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$116(ASC), $$117(ASC) ]  |PARTITIONED|
+        order (ASC, $$116) (ASC, $$117)
         -- STABLE_SORT [$$116(ASC), $$117(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$116, $$117))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$117] <- [datetime-default-null($$ds5.getField("f_dt_fmt"), "MM/DD/YYYY hh:mm:ss.nnna")] project: [$$116, $$117]
               -- ASSIGN  |PARTITIONED|
+                project ([$$116, $$ds5])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.ds5.ds5)  |PARTITIONED|
+                    unnest-map [$$119, $$ds5] <- index-search("ds5", 0, "Default", "test", "ds5", true, false, 1, $$129, 1, $$129, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$129)
                         -- STABLE_SORT [$$129(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$116, $$129])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.ds5.idx5_dt_fmt)  |PARTITIONED|
+                                unnest-map [$$128, $$129] <- index-search("idx5_dt_fmt", 0, "Default", "test", "ds5", true, true, 1, $$116, 1, $$116, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$116] <- [datetime-default-null($$ds6.getField("f_dt"))] project: [$$116]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$ds6])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.ds6)  |PARTITIONED|
+                                          data-scan []<-[$$118, $$ds6] <- test.ds6
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-20.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-20.plan
index 7375151..776b9ad 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-20.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-20.plan
@@ -1,19 +1,38 @@
+distribute result [$$57]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$57] <- [{"id": $$60, "s_f2": $$73}] project: [$$57]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$60(ASC) ]  |PARTITIONED|
+        order (ASC, $$60)
         -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$73, "4"))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$73] <- [string-default-null($$ds7.getField(2))] project: [$$60, $$73]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.ds7.ds7)  |PARTITIONED|
+                  unnest-map [$$60, $$ds7] <- index-search("ds7", 0, "Default", "test", "ds7", false, false, 1, $$72, 1, $$72, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$72)
                       -- STABLE_SORT [$$72(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$72])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.ds7.idx2)  |PARTITIONED|
+                              unnest-map [$$71, $$72] <- index-search("idx2", 0, "Default", "test", "ds7", false, false, 0, 1, $$70, true, false, false)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$70] <- ["4"]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-21.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-21.plan
index 161c4d4..4a370e1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-21.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-21.plan
@@ -1,12 +1,24 @@
+distribute result [$$57]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$57] <- [{"id": $$60, "s_f2": $$70}] project: [$$57]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$60(ASC) ]  |PARTITIONED|
+        order (ASC, $$60)
         -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$70, 4))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$70] <- [string-default-null($$ds7.getField(2))] project: [$$60, $$70]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds7)  |PARTITIONED|
+                  data-scan []<-[$$60, $$ds7] <- test.ds7
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-22.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-22.plan
index 161c4d4..ec3cfbe 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-22.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-22.plan
@@ -1,12 +1,24 @@
+distribute result [$$57]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$57] <- [{"id": $$60, "s_f2": $$70}] project: [$$57]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$60(ASC) ]  |PARTITIONED|
+        order (ASC, $$60)
         -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$70, "4"))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$70] <- [int64-default-null($$ds7.getField(2))] project: [$$60, $$70]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds7)  |PARTITIONED|
+                  data-scan []<-[$$60, $$ds7] <- test.ds7
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-23.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-23.plan
index 1270c47..bf9105e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-23.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-23.plan
@@ -1,19 +1,38 @@
+distribute result [$$57]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$57] <- [{"id": $$60, "s_f2": $$73}] project: [$$57]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$60(ASC) ]  |PARTITIONED|
+        order (ASC, $$60)
         -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$73, 4))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$73] <- [int64-default-null($$ds7.getField(2))] project: [$$60, $$73]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.ds7.ds7)  |PARTITIONED|
+                  unnest-map [$$60, $$ds7] <- index-search("ds7", 0, "Default", "test", "ds7", false, false, 1, $$72, 1, $$72, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$72)
                       -- STABLE_SORT [$$72(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$72])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.ds7.idx3)  |PARTITIONED|
+                              unnest-map [$$71, $$72] <- index-search("idx3", 0, "Default", "test", "ds7", false, false, 0, 1, $$70, true, true, false)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$70] <- [4]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-24.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-24.plan
index fa7d6db..c584af2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-24.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-24.plan
@@ -1,29 +1,58 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$18] <- [{"id": $$21, "s_f2": $$20}] project: [$$18]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            union ($$31, $$26, $$21) ($$33, $$25, $$20)
             -- UNION_ALL  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (lt($$33, "4"))
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$33] <- [$$32.getField(2)] project: [$$31, $$33]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.ds7.ds7)  |PARTITIONED|
+                      unnest-map [$$31, $$32] <- index-search("ds7", 0, "Default", "test", "ds7", false, false, 1, $$26, 1, $$26, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          split ($$27)
                           -- SPLIT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.ds7.idx1)  |PARTITIONED|
+                              unnest-map [$$25, $$26, $$27] <- index-search("idx1", 0, "Default", "test", "ds7", false, false, 0, 1, $$24, true, false, false)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$24] <- ["4"]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (lt($$25, "4")) project: [$$26, $$25]
                 -- STREAM_SELECT  |PARTITIONED|
+                  project ([$$25, $$26])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      split ($$27)
                       -- SPLIT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.ds7.idx1)  |PARTITIONED|
+                          unnest-map [$$25, $$26, $$27] <- index-search("idx1", 0, "Default", "test", "ds7", false, false, 0, 1, $$24, true, false, false)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$24] <- ["4"]
                               -- ASSIGN  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-25.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-25.plan
index 7375151..8866f47 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-25.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/cast-default-null/cast-default-null-25.plan
@@ -1,19 +1,38 @@
+distribute result [$$57]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$57] <- [{"id": $$60, "s_f2": $$62}] project: [$$57]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$60(ASC) ]  |PARTITIONED|
+        order (ASC, $$60)
         -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$62, "4"))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$62] <- [$$ds7.getField(2)] project: [$$60, $$62]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.ds7.ds7)  |PARTITIONED|
+                  unnest-map [$$60, $$ds7] <- index-search("ds7", 0, "Default", "test", "ds7", false, false, 1, $$72, 1, $$72, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$72)
                       -- STABLE_SORT [$$72(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$72])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.ds7.idx2)  |PARTITIONED|
+                              unnest-map [$$71, $$72] <- index-search("idx2", 0, "Default", "test", "ds7", false, false, 0, 1, $$70, true, false, false)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$70] <- ["4"]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-1.plan
index aae34f1..e01516f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-1.plan
@@ -1,10 +1,20 @@
+distribute result [$$x]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$x])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BTREE_SEARCH (test.TestSet.TestSet)  |PARTITIONED|
+        unnest-map [$$21, $$x] <- index-search("TestSet", 0, "Default", "test", "TestSet", true, true, 1, $$22, 1, $$22, true, true, true)
+        -- BTREE_SEARCH  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$21]  |PARTITIONED|
+            order (ASC, $$22)
+            -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+              exchange
+              -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                unnest $$22 <- scan-collection(array: [ "one", "two" ])
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-2.plan
index 642109c..6be8b2b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-2.plan
@@ -1,15 +1,30 @@
+distribute result [$$x]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (eq($$22, $$x.getField(1))) project: [$$x]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$22, $$x])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.TestSet.TestSet)  |PARTITIONED|
+          unnest-map [$$21, $$x] <- index-search("TestSet", 0, "Default", "test", "TestSet", true, false, 1, $$24, 1, $$24, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$24)
               -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$22, $$24])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TestSet.TestSetIndex)  |PARTITIONED|
+                      unnest-map [$$23, $$24] <- index-search("TestSetIndex", 0, "Default", "test", "TestSet", true, true, 1, $$22, 1, $$22, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          unnest $$22 <- scan-collection(array: [ "one", "two" ])
                           -- UNNEST  |UNPARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-3.plan
index 318f7d5..8c71c9d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-3.plan
@@ -1,15 +1,30 @@
+distribute result [$$x]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$x])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        join (eq($$21, $$19))
         -- HYBRID_HASH_JOIN [$$19][$$21]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            assign [$$19] <- [$$x.getField(2)]
             -- ASSIGN  |PARTITIONED|
+              project ([$$x])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.TestSet)  |PARTITIONED|
+                  data-scan []<-[$$20, $$x] <- test.TestSet
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+          exchange
           -- BROADCAST_EXCHANGE  |PARTITIONED|
+            unnest $$21 <- scan-collection(array: [ "one", "two" ])
             -- UNNEST  |UNPARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-4.plan
index 2db6d1a..4ff4a6b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-4.plan
@@ -1,10 +1,20 @@
+distribute result [$$x]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (or(eq($$20, "one"), $$23, $$23)) project: [$$x]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$23] <- [eq($$20, "two")]
       -- ASSIGN  |PARTITIONED|
+        assign [$$20] <- [$$x.getField(1)]
         -- ASSIGN  |PARTITIONED|
+          project ([$$x])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.TestSet)  |PARTITIONED|
+              data-scan []<-[$$21, $$x] <- test.TestSet
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-5.plan
index cfc9617..0962eac 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/disjunctive-predicate/disjunctive-predicate-5.plan
@@ -1,11 +1,22 @@
+distribute result [$$x]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 2
     -- STREAM_LIMIT  |UNPARTITIONED|
+      exchange
       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+        limit 2
         -- STREAM_LIMIT  |PARTITIONED|
+          assign [$$20] <- [$$x.getField(1)] project: [$$x]
           -- ASSIGN  |PARTITIONED|
+            project ([$$x])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.TestSet)  |PARTITIONED|
+                data-scan []<-[$$21, $$x] <- test.TestSet condition (or(eq($$x.getField(1), "one"), eq($$x.getField(1), "two"), eq($$x.getField(1), "two"))) limit 2
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/function-on-pk/function-on-pk-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/function-on-pk/function-on-pk-01.plan
index 9f4d55c..e6fcf6c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/function-on-pk/function-on-pk-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/function-on-pk/function-on-pk-01.plan
@@ -1,8 +1,16 @@
+distribute result [$$19]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"a": $$ds1.getField(1), "b": $$ds1.getField(2)}] project: [$$19]
     -- ASSIGN  |PARTITIONED|
+      select (eq(numeric-add($$20, 1), 3)) project: [$$ds1]
       -- STREAM_SELECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.ds1)  |PARTITIONED|
+          data-scan []<-[$$20, $$ds1] <- test.ds1
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/function-on-pk/function-on-pk-02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/function-on-pk/function-on-pk-02.plan
index 9f4d55c..d06d5ca3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/function-on-pk/function-on-pk-02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/function-on-pk/function-on-pk-02.plan
@@ -1,8 +1,16 @@
+distribute result [$$19]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"a": $$ds1.getField(1), "b": $$ds1.getField(2)}] project: [$$19]
     -- ASSIGN  |PARTITIONED|
+      select (eq(3, numeric-add($$20, 1))) project: [$$ds1]
       -- STREAM_SELECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.ds1)  |PARTITIONED|
+          data-scan []<-[$$20, $$ds1] <- test.ds1
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-10.plan
index cfff6e8..a239131 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-10.plan
@@ -1,18 +1,36 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20)
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$18, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$25, 1, $$25, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$25)
                     -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$25])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                            unnest-map [$$23, $$24, $$25] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 1, $$21, 1, $$22, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$21, $$22] <- [0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-11.plan
index 88609bd..51821ad 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-11.plan
@@ -1,17 +1,34 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        project ([$$24])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$23, $$21))
             -- HYBRID_HASH_JOIN [$$21][$$23]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$24, $$21] <- [$$tenk.getField(0), $$tenk.getField(7)] project: [$$24, $$21]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                      data-scan []<-[$$22, $$tenk] <- test.tenk
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                unnest $$23 <- scan-collection(array: [ 0, 1 ])
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-12.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-12.plan
index 82a6ab3..2ad3f5d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-12.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-12.plan
@@ -1,19 +1,38 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$23, $$tenk.getField(7))) project: [$$24]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$23, $$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$22, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", true, false, 1, $$28, 1, $$28, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$28)
                     -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$23, $$28])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                            unnest-map [$$26, $$27, $$28] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", true, true, 1, $$29, 1, $$29, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$29] <- [cast-lax($$23)]
                                 -- ASSIGN  |UNPARTITIONED|
+                                  unnest $$23 <- scan-collection(array: [ 0, 1 ])
                                   -- UNNEST  |UNPARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-13.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-13.plan
index 1fe8eeb..ee77bbc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-13.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-13.plan
@@ -1,18 +1,36 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20)
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$18, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$24, 1, $$24, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$24)
                     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$24])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k)  |PARTITIONED|
+                            unnest-map [$$23, $$24] <- index-search("idx_1k", 0, "Default", "test", "tenk", false, false, 1, $$21, 1, $$22, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$21, $$22] <- [0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-3.plan
index da99423..da06346 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-3.plan
@@ -1,11 +1,22 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20)
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$18, $$tenk] <- test.tenk
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-4.plan
index cfff6e8..a239131 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-4.plan
@@ -1,18 +1,36 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20)
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$18, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$25, 1, $$25, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$25)
                     -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$25])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                            unnest-map [$$23, $$24, $$25] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 1, $$21, 1, $$22, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$21, $$22] <- [0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-5.plan
index da99423..da06346 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-5.plan
@@ -1,11 +1,22 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20)
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$18, $$tenk] <- test.tenk
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-6.plan
index 106ce2c..7d5d25e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-6.plan
@@ -1,18 +1,36 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$28, 1, $$28, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$28)
                     -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$28])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_2k)  |PARTITIONED|
+                            unnest-map [$$27, $$28] <- index-search("idx_2k", 0, "Default", "test", "tenk", false, false, 1, $$25, 1, $$26, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$25, $$26] <- [0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-7.plan
index a28e2c4..bb04889 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-7.plan
@@ -1,29 +1,58 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$36, 1, $$36, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    intersect [$$36] <- [[$$31], [$$35]]
                     -- INTERSECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$31)
                         -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$31])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                                unnest-map [$$29, $$30, $$31] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 2, $$25, $$26, 2, $$27, $$28, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$25, $$26, $$27, $$28] <- [0, 0, 0, 0]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$35)
                         -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$35])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_2k)  |PARTITIONED|
+                                unnest-map [$$34, $$35] <- index-search("idx_2k", 0, "Default", "test", "tenk", false, false, 1, $$32, 1, $$33, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$32, $$33] <- [0, 0]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-8.plan
index 797e5fa..e0f7d69 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-8.plan
@@ -1,18 +1,36 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$31, 1, $$31, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$31)
                     -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$31])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                            unnest-map [$$29, $$30, $$31] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 2, $$25, $$26, 2, $$27, $$28, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$25, $$26, $$27, $$28] <- [0, 0, 0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-9.plan
index 1fe8eeb..ee77bbc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-9.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-skip-index/hints-skip-index-9.plan
@@ -1,18 +1,36 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20)
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$18, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$24, 1, $$24, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$24)
                     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$24])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k)  |PARTITIONED|
+                            unnest-map [$$23, $$24] <- index-search("idx_1k", 0, "Default", "test", "tenk", false, false, 1, $$21, 1, $$22, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$21, $$22] <- [0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-10.plan
index 1fe8eeb..ee77bbc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-10.plan
@@ -1,18 +1,36 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20)
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$18, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$24, 1, $$24, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$24)
                     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$24])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k)  |PARTITIONED|
+                            unnest-map [$$23, $$24] <- index-search("idx_1k", 0, "Default", "test", "tenk", false, false, 1, $$21, 1, $$22, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$21, $$22] <- [0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-11.plan
index 1fe8eeb..ee77bbc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-11.plan
@@ -1,18 +1,36 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20)
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$18, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$24, 1, $$24, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$24)
                     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$24])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k)  |PARTITIONED|
+                            unnest-map [$$23, $$24] <- index-search("idx_1k", 0, "Default", "test", "tenk", false, false, 1, $$21, 1, $$22, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$21, $$22] <- [0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-12.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-12.plan
index b571087..2f991a3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-12.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-12.plan
@@ -1,35 +1,70 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(9), 0))) project: [$$24]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$33, 1, $$33, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    intersect [$$33] <- [[$$28], [$$32]]
                     -- INTERSECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$28)
                         -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$28])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_1k)  |PARTITIONED|
+                                unnest-map [$$27, $$28] <- index-search("idx_1k", 0, "Default", "test", "tenk", false, false, 1, $$25, 1, $$26, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$25, $$26] <- [$$29, $$30] project: [$$25, $$26]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$29, $$30] <- [0, 0]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$32)
                         -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$32])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_5k)  |PARTITIONED|
+                                unnest-map [$$31, $$32] <- index-search("idx_5k", 0, "Default", "test", "tenk", false, false, 1, $$29, 1, $$30, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$29, $$30] <- [0, 0]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-13.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-13.plan
index 1fe8eeb..ee77bbc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-13.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-13.plan
@@ -1,18 +1,36 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20)
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$18, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$24, 1, $$24, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$24)
                     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$24])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k)  |PARTITIONED|
+                            unnest-map [$$23, $$24] <- index-search("idx_1k", 0, "Default", "test", "tenk", false, false, 1, $$21, 1, $$22, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$21, $$22] <- [0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-14.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-14.plan
index 07438f8..ecd4c81 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-14.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-14.plan
@@ -1,18 +1,36 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20)
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(8), 0)) project: [$$20]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$18, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$24, 1, $$24, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$24)
                     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$24])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_2k)  |PARTITIONED|
+                            unnest-map [$$23, $$24] <- index-search("idx_2k", 0, "Default", "test", "tenk", false, false, 1, $$21, 1, $$22, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$21, $$22] <- [0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-15.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-15.plan
index 106ce2c..7d5d25e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-15.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-15.plan
@@ -1,18 +1,36 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$28, 1, $$28, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$28)
                     -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$28])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_2k)  |PARTITIONED|
+                            unnest-map [$$27, $$28] <- index-search("idx_2k", 0, "Default", "test", "tenk", false, false, 1, $$25, 1, $$26, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$25, $$26] <- [0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-16.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-16.plan
index 9a52414..ca0eb2b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-16.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-16.plan
@@ -1,35 +1,70 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$33, 1, $$33, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    intersect [$$33] <- [[$$28], [$$32]]
                     -- INTERSECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$28)
                         -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$28])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_1k)  |PARTITIONED|
+                                unnest-map [$$27, $$28] <- index-search("idx_1k", 0, "Default", "test", "tenk", false, false, 1, $$25, 1, $$26, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$25, $$26] <- [$$29, $$30] project: [$$25, $$26]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$29, $$30] <- [0, 0]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$32)
                         -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$32])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_2k)  |PARTITIONED|
+                                unnest-map [$$31, $$32] <- index-search("idx_2k", 0, "Default", "test", "tenk", false, false, 1, $$29, 1, $$30, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$29, $$30] <- [0, 0]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-17.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-17.plan
index ad64bb8..0f04f35 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-17.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-17.plan
@@ -1,18 +1,36 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$29, 1, $$29, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$29)
                     -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$29])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                            unnest-map [$$27, $$28, $$29] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 1, $$25, 1, $$26, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$25, $$26] <- [0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-18.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-18.plan
index 1fe8eeb..ee77bbc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-18.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-18.plan
@@ -1,18 +1,36 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20)
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$18, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$24, 1, $$24, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$24)
                     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$24])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k)  |PARTITIONED|
+                            unnest-map [$$23, $$24] <- index-search("idx_1k", 0, "Default", "test", "tenk", false, false, 1, $$21, 1, $$22, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$21, $$22] <- [0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-19.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-19.plan
index 1fe8eeb..ee77bbc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-19.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-19.plan
@@ -1,18 +1,36 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20)
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$18, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$24, 1, $$24, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$24)
                     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$24])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k)  |PARTITIONED|
+                            unnest-map [$$23, $$24] <- index-search("idx_1k", 0, "Default", "test", "tenk", false, false, 1, $$21, 1, $$22, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$21, $$22] <- [0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-20.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-20.plan
index aa0bf62..0ac3f32 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-20.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-20.plan
@@ -1,24 +1,48 @@
+distribute result [$$50]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$50] <- [{"revenue": $$53}] project: [$$50]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$53] <- [agg-sql-sum($$55)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$55] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(ge($$51, "2016-01-01 00:00:00.000000"), lt($$51, "2017-01-01 00:00:00.000000")))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$51] <- [$$ol.getField("ol_delivery_d")] project: [$$51]
               -- ASSIGN  |PARTITIONED|
+                unnest $$ol <- scan-collection($$54) project: [$$ol]
                 -- UNNEST  |PARTITIONED|
+                  assign [$$54] <- [$$o.getField("o_orderline")] project: [$$54]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$o])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.orders.orders)  |PARTITIONED|
+                        unnest-map [$$52, $$o] <- index-search("orders", 0, "Default", "test", "orders", false, false, 1, $$59, 1, $$59, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            distinct ([$$59])
                             -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$59)
                                 -- STABLE_SORT [$$59(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$59])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.orders.orderline_delivery_d)  |PARTITIONED|
+                                        unnest-map [$$58, $$59] <- index-search("orderline_delivery_d", 0, "Default", "test", "orders", false, false, 1, $$56, 1, $$57, true, false, false)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$56, $$57] <- ["2016-01-01 00:00:00.000000", "2017-01-01 00:00:00.000000"]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-21.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-21.plan
index d018905..1b413a3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-21.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-21.plan
@@ -1,24 +1,48 @@
+distribute result [$$50]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$50] <- [{"revenue": $$53}] project: [$$50]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$53] <- [agg-sql-sum($$55)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$55] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(ge($$51, "2016-01-01 00:00:00.000000"), lt($$51, "2017-01-01 00:00:00.000000")))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$51] <- [$$ol.getField("ol_delivery_d")] project: [$$51]
               -- ASSIGN  |PARTITIONED|
+                unnest $$ol <- scan-collection($$54) project: [$$ol]
                 -- UNNEST  |PARTITIONED|
+                  assign [$$54] <- [$$o.getField("o_orderline")] project: [$$54]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$o])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.orders.orders)  |PARTITIONED|
+                        unnest-map [$$52, $$o] <- index-search("orders", 0, "Default", "test", "orders", false, false, 1, $$58, 1, $$58, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            distinct ([$$58])
                             -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$58)
                                 -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$58])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.orders.orderline_delivery_d)  |PARTITIONED|
+                                        unnest-map [$$57, $$58] <- index-search("orderline_delivery_d", 0, "Default", "test", "orders", false, false, 1, $$56, 0, true, true, false)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$56] <- ["2016-01-01 00:00:00.000000"]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-3.plan
index cfff6e8..a239131 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-3.plan
@@ -1,18 +1,36 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20)
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$18, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$25, 1, $$25, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$25)
                     -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$25])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                            unnest-map [$$23, $$24, $$25] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 1, $$21, 1, $$22, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$21, $$22] <- [0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-4.plan
index 9a52414..ca0eb2b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-4.plan
@@ -1,35 +1,70 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$33, 1, $$33, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    intersect [$$33] <- [[$$28], [$$32]]
                     -- INTERSECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$28)
                         -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$28])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_1k)  |PARTITIONED|
+                                unnest-map [$$27, $$28] <- index-search("idx_1k", 0, "Default", "test", "tenk", false, false, 1, $$25, 1, $$26, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$25, $$26] <- [$$29, $$30] project: [$$25, $$26]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$29, $$30] <- [0, 0]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$32)
                         -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$32])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_2k)  |PARTITIONED|
+                                unnest-map [$$31, $$32] <- index-search("idx_2k", 0, "Default", "test", "tenk", false, false, 1, $$29, 1, $$30, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$29, $$30] <- [0, 0]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-5.plan
index 5e57a22..dbd1f60 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-5.plan
@@ -1,35 +1,70 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(9), 0))) project: [$$24]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$35, 1, $$35, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    intersect [$$35] <- [[$$29], [$$34]]
                     -- INTERSECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$29)
                         -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$29])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                                unnest-map [$$27, $$28, $$29] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 1, $$25, 1, $$26, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$25, $$26] <- [$$30, $$31] project: [$$25, $$26]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$30, $$31] <- [0, 0]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$34)
                         -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$34])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_5k_10k)  |PARTITIONED|
+                                unnest-map [$$32, $$33, $$34] <- index-search("idx_5k_10k", 0, "Default", "test", "tenk", false, false, 1, $$30, 1, $$31, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$30, $$31] <- [0, 0]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-6.plan
index 797e5fa..e0f7d69 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-6.plan
@@ -1,18 +1,36 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$31, 1, $$31, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$31)
                     -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$31])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                            unnest-map [$$29, $$30, $$31] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 2, $$25, $$26, 2, $$27, $$28, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$25, $$26, $$27, $$28] <- [0, 0, 0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-7.plan
index 797e5fa..e0f7d69 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-7.plan
@@ -1,18 +1,36 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$31, 1, $$31, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$31)
                     -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$31])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                            unnest-map [$$29, $$30, $$31] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 2, $$25, $$26, 2, $$27, $$28, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$25, $$26, $$27, $$28] <- [0, 0, 0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-8.plan
index e32ac40..3cb5a78 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-8.plan
@@ -1,29 +1,58 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$37, 1, $$37, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    intersect [$$37] <- [[$$31], [$$36]]
                     -- INTERSECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$31)
                         -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$31])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                                unnest-map [$$29, $$30, $$31] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 2, $$25, $$26, 2, $$27, $$28, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$25, $$26, $$27, $$28] <- [0, 0, 0, 0]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$36)
                         -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$36])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_2k_5k)  |PARTITIONED|
+                                unnest-map [$$34, $$35, $$36] <- index-search("idx_2k_5k", 0, "Default", "test", "tenk", false, false, 1, $$32, 1, $$33, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$32, $$33] <- [0, 0]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-9.plan
index e32ac40..3cb5a78 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-9.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/hints-use-index/hints-use-index-9.plan
@@ -1,29 +1,58 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$37, 1, $$37, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    intersect [$$37] <- [[$$31], [$$36]]
                     -- INTERSECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$31)
                         -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$31])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                                unnest-map [$$29, $$30, $$31] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 2, $$25, $$26, 2, $$27, $$28, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$25, $$26, $$27, $$28] <- [0, 0, 0, 0]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$36)
                         -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$36])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_2k_5k)  |PARTITIONED|
+                                unnest-map [$$34, $$35, $$36] <- index-search("idx_2k_5k", 0, "Default", "test", "tenk", false, false, 1, $$32, 1, $$33, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$32, $$33] <- [0, 0]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/intersection-misc/intersection-misc-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/intersection-misc/intersection-misc-01.plan
index 98dcddd..68dcc74 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/intersection-misc/intersection-misc-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/intersection-misc/intersection-misc-01.plan
@@ -1,119 +1,232 @@
+distribute result [$$125]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$125] <- [{"t1": $$95, "t2": $$t2, "t3": $$119}] project: [$$125]
     -- ASSIGN  |PARTITIONED|
+      project ([$$95, $$t2, $$119])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$142(ASC), $$132(ASC), $$144(ASC) ]  |PARTITIONED|
+          order (ASC, $$142) (ASC, $$132) (ASC, $$144)
           -- STABLE_SORT [$$142(ASC), $$132(ASC), $$144(ASC)]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$95, $$t2, $$119, $$142, $$132, $$144])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$137, $$144))
                   -- HYBRID_HASH_JOIN [$$137][$$144]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$137]  |PARTITIONED|
+                      project ([$$95, $$t2, $$142, $$132, $$137])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          join (eq($$142, $$136))
                           -- HYBRID_HASH_JOIN [$$142][$$136]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$142]  |PARTITIONED|
+                              assign [$$95] <- [{"c3": $$142}]
                               -- ASSIGN  |PARTITIONED|
+                                select ($$89) project: [$$142]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  project ([$$89, $$142])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
-                                              {
+                                      group by ([$$149 := $$130]) decor ([$$142]) {
+                                                aggregate [$$89] <- [non-empty-stream()]
                                                 -- AGGREGATE  |LOCAL|
+                                                  select (not(is-missing($$148)))
                                                   -- STREAM_SELECT  |LOCAL|
+                                                    nested tuple source
                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                              }
+                                             }
+                                      -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          order (ASC, $$130)
                                           -- STABLE_SORT [$$130(ASC)]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$130]  |PARTITIONED|
+                                              project ([$$142, $$148, $$130])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  left outer join (eq($$139, $$85))
                                                   -- HYBRID_HASH_JOIN [$$139][$$85]  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$139]  |PARTITIONED|
+                                                      select (eq($$d.getField("c5"), 1)) project: [$$142, $$130, $$139]
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        assign [$$142, $$139] <- [$$d.getField("c3"), $$d.getField("c1")]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- BTREE_SEARCH (test.d.d)  |PARTITIONED|
+                                                            unnest-map [$$130, $$d] <- index-search("d", 0, "Default", "test", "d", false, false, 1, $$155, 1, $$155, true, true, true)
+                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                replicate
                                                                 -- REPLICATE  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    order (ASC, $$155)
                                                                     -- STABLE_SORT [$$155(ASC)]  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        project ([$$155])
                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- BTREE_SEARCH (test.d.idx_c5)  |PARTITIONED|
+                                                                            unnest-map [$$154, $$155] <- index-search("idx_c5", 0, "Default", "test", "d", false, false, 1, $$152, 1, $$153, true, true, true)
+                                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                assign [$$152, $$153] <- [1, 1]
                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                  empty-tuple-source
                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                                                          assign [$$148, $$85] <- [true, $$c.getField("c11")] project: [$$148, $$85]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            project ([$$c])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.c)  |PARTITIONED|
+                                                                data-scan []<-[$$131, $$c] <- test.c
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$136]  |PARTITIONED|
+                              assign [$$137, $$136] <- [$$t2.getField("c4"), $$t2.getField("c2")]
                               -- ASSIGN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.d)  |PARTITIONED|
+                                  data-scan []<-[$$132, $$t2] <- test.d
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$144]  |PARTITIONED|
+                      assign [$$119] <- [{"c4": $$144}]
                       -- ASSIGN  |PARTITIONED|
+                        select ($$108) project: [$$144]
                         -- STREAM_SELECT  |PARTITIONED|
+                          project ([$$108, $$144])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$133]  |PARTITIONED|
-                                      {
+                              group by ([$$151 := $$133]) decor ([$$144]) {
+                                        aggregate [$$108] <- [non-empty-stream()]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$150)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$133]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$133)
                                   -- STABLE_SORT [$$133(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$133]  |PARTITIONED|
+                                      project ([$$144, $$150, $$133])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          left outer join (eq($$140, $$104))
                                           -- HYBRID_HASH_JOIN [$$140][$$104]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$140]  |PARTITIONED|
+                                              select (and(eq($$d.getField("c5"), 1), ge($$129, "2019-01-01"), le($$129, "2019-02-01"))) project: [$$144, $$133, $$140]
                                               -- STREAM_SELECT  |PARTITIONED|
+                                                assign [$$144, $$129, $$140] <- [$$d.getField("c4"), $$d.getField("c6"), $$d.getField("c1")]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (test.d.d)  |PARTITIONED|
+                                                    unnest-map [$$133, $$d] <- index-search("d", 0, "Default", "test", "d", false, false, 1, $$164, 1, $$164, true, true, true)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        intersect [$$164] <- [[$$159], [$$163]]
                                                         -- INTERSECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            assign [$$159] <- [$$155] project: [$$159]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                replicate
                                                                 -- REPLICATE  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    order (ASC, $$155)
                                                                     -- STABLE_SORT [$$155(ASC)]  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        project ([$$155])
                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- BTREE_SEARCH (test.d.idx_c5)  |PARTITIONED|
+                                                                            unnest-map [$$154, $$155] <- index-search("idx_c5", 0, "Default", "test", "d", false, false, 1, $$152, 1, $$153, true, true, true)
+                                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                assign [$$152, $$153] <- [1, 1]
                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                  empty-tuple-source
                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            order (ASC, $$163)
                                                             -- STABLE_SORT [$$163(ASC)]  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                project ([$$163])
                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- BTREE_SEARCH (test.d.idx_c6)  |PARTITIONED|
+                                                                    unnest-map [$$162, $$163] <- index-search("idx_c6", 0, "Default", "test", "d", false, false, 1, $$160, 1, $$161, true, true, false)
+                                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        assign [$$160, $$161] <- ["2019-01-01", "2019-02-01"]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$150, $$104] <- [$$148, $$85] project: [$$150, $$104]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  replicate
                                                   -- REPLICATE  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                                                      assign [$$148, $$85] <- [true, $$c.getField("c11")] project: [$$148, $$85]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$c])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.c)  |PARTITIONED|
+                                                            data-scan []<-[$$131, $$c] <- test.c
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/intersection-misc/intersection-misc-02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/intersection-misc/intersection-misc-02.plan
index a4d6a43..05f1a9e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/intersection-misc/intersection-misc-02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/intersection-misc/intersection-misc-02.plan
@@ -1,107 +1,208 @@
+distribute result [$$125]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$125] <- [{"t1": $$95, "t2": $$t2, "t3": $$119}] project: [$$125]
     -- ASSIGN  |PARTITIONED|
+      project ([$$95, $$t2, $$119])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$142(ASC), $$132(ASC), $$144(ASC) ]  |PARTITIONED|
+          order (ASC, $$142) (ASC, $$132) (ASC, $$144)
           -- STABLE_SORT [$$142(ASC), $$132(ASC), $$144(ASC)]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$95, $$t2, $$119, $$142, $$132, $$144])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$137, $$144))
                   -- HYBRID_HASH_JOIN [$$137][$$144]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$137]  |PARTITIONED|
+                      project ([$$95, $$t2, $$142, $$132, $$137])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          join (eq($$142, $$136))
                           -- HYBRID_HASH_JOIN [$$142][$$136]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$142]  |PARTITIONED|
+                              assign [$$95] <- [{"c3": $$142}]
                               -- ASSIGN  |PARTITIONED|
+                                select ($$89) project: [$$142]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  project ([$$89, $$142])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
-                                              {
+                                      group by ([$$149 := $$130]) decor ([$$142]) {
+                                                aggregate [$$89] <- [non-empty-stream()]
                                                 -- AGGREGATE  |LOCAL|
+                                                  select (not(is-missing($$148)))
                                                   -- STREAM_SELECT  |LOCAL|
+                                                    nested tuple source
                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                              }
+                                             }
+                                      -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          order (ASC, $$130)
                                           -- STABLE_SORT [$$130(ASC)]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$130]  |PARTITIONED|
+                                              project ([$$142, $$148, $$130])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  left outer join (eq($$139, $$85))
                                                   -- HYBRID_HASH_JOIN [$$139][$$85]  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$139]  |PARTITIONED|
+                                                      select (eq($$d.getField("c5"), 1)) project: [$$142, $$130, $$139]
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        assign [$$142, $$139] <- [$$d.getField("c3"), $$d.getField("c1")]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            replicate
                                                             -- REPLICATE  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- BTREE_SEARCH (test.d.d)  |PARTITIONED|
+                                                                unnest-map [$$130, $$d] <- index-search("d", 0, "Default", "test", "d", false, false, 1, $$155, 1, $$155, true, true, true)
+                                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    order (ASC, $$155)
                                                                     -- STABLE_SORT [$$155(ASC)]  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        project ([$$155])
                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- BTREE_SEARCH (test.d.idx_c5)  |PARTITIONED|
+                                                                            unnest-map [$$154, $$155] <- index-search("idx_c5", 0, "Default", "test", "d", false, false, 1, $$152, 1, $$153, true, true, true)
+                                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                assign [$$152, $$153] <- [1, 1]
                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                  empty-tuple-source
                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                                                          assign [$$148, $$85] <- [true, $$c.getField("c11")] project: [$$148, $$85]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            project ([$$c])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.c)  |PARTITIONED|
+                                                                data-scan []<-[$$131, $$c] <- test.c
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$136]  |PARTITIONED|
+                              assign [$$137, $$136] <- [$$t2.getField("c4"), $$t2.getField("c2")]
                               -- ASSIGN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.d)  |PARTITIONED|
+                                  data-scan []<-[$$132, $$t2] <- test.d
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$144]  |PARTITIONED|
+                      assign [$$119] <- [{"c4": $$144}]
                       -- ASSIGN  |PARTITIONED|
+                        select ($$108) project: [$$144]
                         -- STREAM_SELECT  |PARTITIONED|
+                          project ([$$108, $$144])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$133]  |PARTITIONED|
-                                      {
+                              group by ([$$151 := $$133]) decor ([$$144]) {
+                                        aggregate [$$108] <- [non-empty-stream()]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$150)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$133]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$133)
                                   -- STABLE_SORT [$$133(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$133]  |PARTITIONED|
+                                      project ([$$144, $$150, $$133])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          left outer join (eq($$140, $$104))
                                           -- HYBRID_HASH_JOIN [$$140][$$104]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$140]  |PARTITIONED|
+                                              select (and(eq($$d.getField("c5"), 1), ge($$129, "2019-01-01"), le($$129, "2019-02-01"))) project: [$$144, $$133, $$140]
                                               -- STREAM_SELECT  |PARTITIONED|
+                                                assign [$$144, $$129, $$140] <- [$$d.getField("c4"), $$d.getField("c6"), $$d.getField("c1")]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  assign [$$133, $$d] <- [$$130, $$d] project: [$$133, $$d]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- BTREE_SEARCH (test.d.d)  |PARTITIONED|
+                                                          unnest-map [$$130, $$d] <- index-search("d", 0, "Default", "test", "d", false, false, 1, $$155, 1, $$155, true, true, true)
+                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              order (ASC, $$155)
                                                               -- STABLE_SORT [$$155(ASC)]  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  project ([$$155])
                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- BTREE_SEARCH (test.d.idx_c5)  |PARTITIONED|
+                                                                      unnest-map [$$154, $$155] <- index-search("idx_c5", 0, "Default", "test", "d", false, false, 1, $$152, 1, $$153, true, true, true)
+                                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          assign [$$152, $$153] <- [1, 1]
                                                                           -- ASSIGN  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$150, $$104] <- [$$148, $$85] project: [$$150, $$104]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  replicate
                                                   -- REPLICATE  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                                                      assign [$$148, $$85] <- [true, $$c.getField("c11")] project: [$$148, $$85]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$c])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.c)  |PARTITIONED|
+                                                            data-scan []<-[$$131, $$c] <- test.c
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/intersection-misc/intersection-misc-03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/intersection-misc/intersection-misc-03.plan
index fb235a5..45cb450 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/intersection-misc/intersection-misc-03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/intersection-misc/intersection-misc-03.plan
@@ -1,102 +1,198 @@
+distribute result [$$125]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$125] <- [{"t1": $$95, "t2": $$t2, "t3": $$119}] project: [$$125]
     -- ASSIGN  |PARTITIONED|
+      project ([$$95, $$t2, $$119])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$142(ASC), $$132(ASC), $$144(ASC) ]  |PARTITIONED|
+          order (ASC, $$142) (ASC, $$132) (ASC, $$144)
           -- STABLE_SORT [$$142(ASC), $$132(ASC), $$144(ASC)]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$95, $$t2, $$119, $$142, $$132, $$144])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$137, $$144))
                   -- HYBRID_HASH_JOIN [$$137][$$144]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$137]  |PARTITIONED|
+                      project ([$$95, $$t2, $$142, $$132, $$137])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          join (eq($$142, $$136))
                           -- HYBRID_HASH_JOIN [$$142][$$136]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$142]  |PARTITIONED|
+                              assign [$$95] <- [{"c3": $$142}]
                               -- ASSIGN  |PARTITIONED|
+                                select ($$89) project: [$$142]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  project ([$$89, $$142])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
-                                              {
+                                      group by ([$$149 := $$130]) decor ([$$142]) {
+                                                aggregate [$$89] <- [non-empty-stream()]
                                                 -- AGGREGATE  |LOCAL|
+                                                  select (not(is-missing($$148)))
                                                   -- STREAM_SELECT  |LOCAL|
+                                                    nested tuple source
                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                              }
+                                             }
+                                      -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          order (ASC, $$130)
                                           -- STABLE_SORT [$$130(ASC)]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$130]  |PARTITIONED|
+                                              project ([$$142, $$148, $$130])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  left outer join (eq($$139, $$85))
                                                   -- HYBRID_HASH_JOIN [$$139][$$85]  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$139]  |PARTITIONED|
+                                                      select (eq($$d.getField("c5"), 1)) project: [$$142, $$130, $$139]
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        assign [$$142, $$139] <- [$$d.getField("c3"), $$d.getField("c1")]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- BTREE_SEARCH (test.d.d)  |PARTITIONED|
+                                                            unnest-map [$$130, $$d] <- index-search("d", 0, "Default", "test", "d", false, false, 1, $$155, 1, $$155, true, true, true)
+                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                order (ASC, $$155)
                                                                 -- STABLE_SORT [$$155(ASC)]  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    project ([$$155])
                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- BTREE_SEARCH (test.d.idx_c5)  |PARTITIONED|
+                                                                        unnest-map [$$154, $$155] <- index-search("idx_c5", 0, "Default", "test", "d", false, false, 1, $$152, 1, $$153, true, true, true)
+                                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            assign [$$152, $$153] <- [1, 1]
                                                                             -- ASSIGN  |PARTITIONED|
+                                                                              empty-tuple-source
                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                                                          assign [$$148, $$85] <- [true, $$c.getField("c11")] project: [$$148, $$85]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            project ([$$c])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.c)  |PARTITIONED|
+                                                                data-scan []<-[$$131, $$c] <- test.c
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$136]  |PARTITIONED|
+                              assign [$$137, $$136] <- [$$t2.getField("c4"), $$t2.getField("c2")]
                               -- ASSIGN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.d)  |PARTITIONED|
+                                  data-scan []<-[$$132, $$t2] <- test.d
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$144]  |PARTITIONED|
+                      assign [$$119] <- [{"c4": $$144}]
                       -- ASSIGN  |PARTITIONED|
+                        select ($$108) project: [$$144]
                         -- STREAM_SELECT  |PARTITIONED|
+                          project ([$$108, $$144])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$133]  |PARTITIONED|
-                                      {
+                              group by ([$$151 := $$133]) decor ([$$144]) {
+                                        aggregate [$$108] <- [non-empty-stream()]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$150)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$133]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$133)
                                   -- STABLE_SORT [$$133(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$133]  |PARTITIONED|
+                                      project ([$$144, $$150, $$133])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          left outer join (eq($$140, $$104))
                                           -- HYBRID_HASH_JOIN [$$140][$$104]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$140]  |PARTITIONED|
+                                              select (and(eq($$d.getField("c5"), 1), ge($$129, "2019-01-01"), le($$129, "2019-02-01"))) project: [$$144, $$133, $$140]
                                               -- STREAM_SELECT  |PARTITIONED|
+                                                assign [$$144, $$129, $$140] <- [$$d.getField("c4"), $$d.getField("c6"), $$d.getField("c1")]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (test.d.d)  |PARTITIONED|
+                                                    unnest-map [$$133, $$d] <- index-search("d", 0, "Default", "test", "d", false, false, 1, $$159, 1, $$159, true, true, true)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        order (ASC, $$159)
                                                         -- STABLE_SORT [$$159(ASC)]  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            project ([$$159])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- BTREE_SEARCH (test.d.idx_c6)  |PARTITIONED|
+                                                                unnest-map [$$158, $$159] <- index-search("idx_c6", 0, "Default", "test", "d", false, false, 1, $$156, 1, $$157, true, true, false)
+                                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    assign [$$156, $$157] <- ["2019-01-01", "2019-02-01"]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$150, $$104] <- [$$148, $$85] project: [$$150, $$104]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  replicate
                                                   -- REPLICATE  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                                                      assign [$$148, $$85] <- [true, $$c.getField("c11")] project: [$$148, $$85]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$c])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.c)  |PARTITIONED|
+                                                            data-scan []<-[$$131, $$c] <- test.c
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/intersection-misc/intersection-misc-04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/intersection-misc/intersection-misc-04.plan
index 33ccc2e..a2a803d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/intersection-misc/intersection-misc-04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index-selection/intersection-misc/intersection-misc-04.plan
@@ -1,96 +1,186 @@
+distribute result [$$125]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$125] <- [{"t1": $$95, "t2": $$t2, "t3": $$119}] project: [$$125]
     -- ASSIGN  |PARTITIONED|
+      project ([$$95, $$t2, $$119])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$142(ASC), $$132(ASC), $$144(ASC) ]  |PARTITIONED|
+          order (ASC, $$142) (ASC, $$132) (ASC, $$144)
           -- STABLE_SORT [$$142(ASC), $$132(ASC), $$144(ASC)]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$95, $$t2, $$119, $$142, $$132, $$144])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$137, $$144))
                   -- HYBRID_HASH_JOIN [$$137][$$144]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$137]  |PARTITIONED|
+                      project ([$$95, $$t2, $$142, $$132, $$137])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          join (eq($$142, $$136))
                           -- HYBRID_HASH_JOIN [$$142][$$136]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$142]  |PARTITIONED|
+                              assign [$$95] <- [{"c3": $$142}]
                               -- ASSIGN  |PARTITIONED|
+                                select ($$89) project: [$$142]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  project ([$$89, $$142])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
-                                              {
+                                      group by ([$$149 := $$130]) decor ([$$142]) {
+                                                aggregate [$$89] <- [non-empty-stream()]
                                                 -- AGGREGATE  |LOCAL|
+                                                  select (not(is-missing($$148)))
                                                   -- STREAM_SELECT  |LOCAL|
+                                                    nested tuple source
                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                              }
+                                             }
+                                      -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          order (ASC, $$130)
                                           -- STABLE_SORT [$$130(ASC)]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$130]  |PARTITIONED|
+                                              project ([$$142, $$148, $$130])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  left outer join (eq($$139, $$85))
                                                   -- HYBRID_HASH_JOIN [$$139][$$85]  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$139]  |PARTITIONED|
+                                                      select (eq($$d.getField("c5"), 1)) project: [$$142, $$130, $$139]
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        assign [$$142, $$139] <- [$$d.getField("c3"), $$d.getField("c1")]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            replicate
                                                             -- REPLICATE  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.d)  |PARTITIONED|
+                                                                data-scan []<-[$$130, $$d] <- test.d
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                                                          assign [$$148, $$85] <- [true, $$c.getField("c11")] project: [$$148, $$85]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            project ([$$c])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.c)  |PARTITIONED|
+                                                                data-scan []<-[$$131, $$c] <- test.c
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$136]  |PARTITIONED|
+                              assign [$$137, $$136] <- [$$t2.getField("c4"), $$t2.getField("c2")]
                               -- ASSIGN  |PARTITIONED|
+                                assign [$$132, $$t2] <- [$$130, $$d] project: [$$132, $$t2]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.d)  |PARTITIONED|
+                                        data-scan []<-[$$130, $$d] <- test.d
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$144]  |PARTITIONED|
+                      assign [$$119] <- [{"c4": $$144}]
                       -- ASSIGN  |PARTITIONED|
+                        select ($$108) project: [$$144]
                         -- STREAM_SELECT  |PARTITIONED|
+                          project ([$$108, $$144])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$133]  |PARTITIONED|
-                                      {
+                              group by ([$$151 := $$133]) decor ([$$144]) {
+                                        aggregate [$$108] <- [non-empty-stream()]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$150)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$133]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$133)
                                   -- STABLE_SORT [$$133(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$133]  |PARTITIONED|
+                                      project ([$$144, $$150, $$133])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          left outer join (eq($$140, $$104))
                                           -- HYBRID_HASH_JOIN [$$140][$$104]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$140]  |PARTITIONED|
+                                              select (and(eq($$d.getField("c5"), 1), ge($$129, "2019-01-01"), le($$129, "2019-02-01"))) project: [$$144, $$133, $$140]
                                               -- STREAM_SELECT  |PARTITIONED|
+                                                assign [$$144, $$129, $$140] <- [$$d.getField("c4"), $$d.getField("c6"), $$d.getField("c1")]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  assign [$$133, $$d] <- [$$130, $$d] project: [$$133, $$d]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.d)  |PARTITIONED|
+                                                          data-scan []<-[$$130, $$d] <- test.d
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$150, $$104] <- [$$148, $$85] project: [$$150, $$104]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  replicate
                                                   -- REPLICATE  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                                                      assign [$$148, $$85] <- [true, $$c.getField("c11")] project: [$$148, $$85]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$c])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.c)  |PARTITIONED|
+                                                            data-scan []<-[$$131, $$c] <- test.c
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-composite-key-03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-composite-key-03.plan
index 0f21ecf..5a2c811 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-composite-key-03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-composite-key-03.plan
@@ -1,15 +1,30 @@
+distribute result [$$l]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(eq($$l.getField(1), "Julio"), eq($$l.getField(2), "Isa")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$l])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.employee.employee)  |PARTITIONED|
+          unnest-map [$$18, $$l] <- index-search("employee", 0, "Default", "test", "employee", false, false, 1, $$26, 1, $$26, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+              order (ASC, $$26)
+              -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$26])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.employee.idx_employee_fal)  |PARTITIONED|
+                      unnest-map [$$23, $$24, $$25, $$26] <- index-search("idx_employee_fal", 0, "Default", "test", "employee", false, false, 1, $$21, 1, $$22, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$21, $$22] <- ["Julio", "Julio"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-33.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-33.plan
index 49dab53..17a3b93 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-33.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-33.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (gt($$emp.getField(1), "Roger"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$15, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+              order (ASC, $$20)
+              -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$20])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$18, $$19, $$20] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 1, $$17, 0, false, true, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$17] <- ["Roger"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-34.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-34.plan
index 49dab53..3541c9b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-34.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-34.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (ge($$emp.getField(1), "Susan"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$15, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+              order (ASC, $$20)
+              -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$20])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$18, $$19, $$20] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 1, $$17, 0, true, true, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$17] <- ["Susan"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-35.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-35.plan
index 49dab53..43a557c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-35.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-35.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (lt($$emp.getField(1), "Isa"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$15, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+              order (ASC, $$20)
+              -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$20])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$18, $$19, $$20] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 0, 1, $$17, true, false, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$17] <- ["Isa"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-36.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-36.plan
index 49dab53..9b0ca24 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-36.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-36.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (le($$emp.getField(1), "Vanpatten"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$15, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+              order (ASC, $$20)
+              -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$20])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$18, $$19, $$20] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 0, 1, $$17, true, true, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$17] <- ["Vanpatten"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-40.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-40.plan
index 90f0e84..2215cda 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-40.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-40.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(eq($$emp.getField(1), "Young Seok"), eq($$emp.getField(2), "Kim")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$27, 1, $$27, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+              order (ASC, $$27)
+              -- STABLE_SORT [$$27(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$27])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$25, $$26, $$27] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 2, $$21, $$22, 2, $$23, $$24, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$21, $$22, $$23, $$24] <- ["Young Seok", "Kim", "Young Seok", "Kim"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-42.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-42.plan
index e7a5c31..41b6928 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-42.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-42.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(gt($$emp.getField(1), "Alex"), lt($$emp.getField(2), "Zach")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$24, 1, $$24, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$23(ASC)]  |PARTITIONED|
+              order (ASC, $$24)
+              -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$24])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$22, $$23, $$24] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 1, $$21, 0, true, true, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$21] <- ["Alex"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-43.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-43.plan
index e7a5c31..d3fdb8f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-43.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-43.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(gt($$emp.getField(1), "Allan"), lt($$emp.getField(2), "Zubi")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$24, 1, $$24, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$23(ASC)]  |PARTITIONED|
+              order (ASC, $$24)
+              -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$24])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$22, $$23, $$24] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 1, $$21, 0, true, true, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$21] <- ["Allan"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-44.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-44.plan
index e7a5c31..1da8796 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-44.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-44.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(gt($$emp.getField(1), "Allan"), eq($$emp.getField(2), "Xu")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$24, 1, $$24, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$23(ASC)]  |PARTITIONED|
+              order (ASC, $$24)
+              -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$24])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$22, $$23, $$24] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 1, $$21, 0, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$21] <- ["Allan"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-45.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-45.plan
index 0746bd8..783199d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-45.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-45.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(eq($$emp.getField(1), "Julio"), lt($$emp.getField(2), "Xu")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$25, 1, $$25, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+              order (ASC, $$25)
+              -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$25])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$23, $$24, $$25] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 1, $$21, 1, $$22, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$21, $$22] <- ["Julio", "Julio"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-46.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-46.plan
index e7a5c31..c883107 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-46.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-46.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(ge($$emp.getField(1), "Michael"), le($$emp.getField(2), "Xu")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$24, 1, $$24, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$23(ASC)]  |PARTITIONED|
+              order (ASC, $$24)
+              -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$24])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$22, $$23, $$24] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 1, $$21, 0, true, true, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$21] <- ["Michael"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-47.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-47.plan
index 95526b9..9fc83df 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-47.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-47.plan
@@ -1,16 +1,32 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(lt($$22, "Tomes"), gt($$22, "Kevin"), gt($$23, "Craig"), lt($$23, "Mary"))) project: [$$emp]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$23, $$22] <- [$$emp.getField(1), $$emp.getField(2)]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+            unnest-map [$$24, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$31, 1, $$31, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$31)
                 -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$31])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                        unnest-map [$$29, $$30, $$31] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 2, $$25, $$26, 2, $$27, $$28, true, true, false)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$25, $$26, $$27, $$28] <- ["Craig", "Kevin", "Mary", "Tomes"]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-48.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-48.plan
index 95526b9..da63a69 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-48.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-48.plan
@@ -1,16 +1,32 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(le($$22, "Tomes"), ge($$22, "Kevin"), ge($$23, "Craig"), le($$23, "Mary"))) project: [$$emp]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$23, $$22] <- [$$emp.getField(1), $$emp.getField(2)]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+            unnest-map [$$24, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$31, 1, $$31, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$31)
                 -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$31])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                        unnest-map [$$29, $$30, $$31] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 2, $$25, $$26, 2, $$27, $$28, true, true, false)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$25, $$26, $$27, $$28] <- ["Craig", "Kevin", "Mary", "Tomes"]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-49.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-49.plan
index e7a5c31..fed3c29 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-49.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-49.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(le($$emp.getField(1), "Craig"), gt($$emp.getField(2), "Kevin")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$24, 1, $$24, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$23(ASC)]  |PARTITIONED|
+              order (ASC, $$24)
+              -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$24])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$22, $$23, $$24] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 0, 1, $$21, true, true, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$21] <- ["Craig"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-51.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-51.plan
index 95526b9..979bcb0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-51.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-51.plan
@@ -1,16 +1,32 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(le($$22, "Tomes"), gt($$22, "Kevin"), gt($$23, "Craig"), le($$23, "Mary"))) project: [$$emp]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$23, $$22] <- [$$emp.getField(1), $$emp.getField(2)]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+            unnest-map [$$24, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$31, 1, $$31, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$31)
                 -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$31])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                        unnest-map [$$29, $$30, $$31] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 2, $$25, $$26, 2, $$27, $$28, true, true, false)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$25, $$26, $$27, $$28] <- ["Craig", "Kevin", "Mary", "Tomes"]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-52.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-52.plan
index 95526b9..a5197f0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-52.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-52.plan
@@ -1,16 +1,32 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(lt($$22, "Tomes"), ge($$22, "Kevin"), ge($$23, "Craig"), lt($$23, "Mary"))) project: [$$emp]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$23, $$22] <- [$$emp.getField(1), $$emp.getField(2)]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+            unnest-map [$$24, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$31, 1, $$31, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$31)
                 -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$31])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                        unnest-map [$$29, $$30, $$31] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 2, $$25, $$26, 2, $$27, $$28, true, true, false)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$25, $$26, $$27, $$28] <- ["Craig", "Kevin", "Mary", "Tomes"]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-53.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-53.plan
index 95526b9..aa6ca11 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-53.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-53.plan
@@ -1,16 +1,32 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(ge($$22, "Tomes"), le($$22, "Kevin"), ge($$23, "Craig"), le($$23, "Mary"))) project: [$$emp]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$23, $$22] <- [$$emp.getField(1), $$emp.getField(2)]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+            unnest-map [$$24, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$31, 1, $$31, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$31)
                 -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$31])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                        unnest-map [$$29, $$30, $$31] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 2, $$25, $$26, 2, $$27, $$28, true, true, false)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$25, $$26, $$27, $$28] <- ["Craig", "Tomes", "Mary", "Kevin"]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-54.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-54.plan
index 0b28fcd..755c402 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-54.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-54.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (gt($$emp.getField(1), "Max"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$15, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$19, 1, $$19, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+              order (ASC, $$19)
+              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$19])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$18, $$19] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 1, $$17, 0, false, true, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$17] <- ["Max"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-55.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-55.plan
index 0b28fcd..0453b7b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-55.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-55.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (ge($$emp.getField(1), "Sofia"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$15, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$19, 1, $$19, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+              order (ASC, $$19)
+              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$19])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$18, $$19] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 1, $$17, 0, true, true, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$17] <- ["Sofia"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-56.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-56.plan
index 0b28fcd..8f8c386 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-56.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-56.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (lt($$emp.getField(1), "Chen"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$15, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$19, 1, $$19, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+              order (ASC, $$19)
+              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$19])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$18, $$19] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 0, 1, $$17, true, false, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$17] <- ["Chen"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-57.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-57.plan
index 0b28fcd..1e39e2e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-57.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-57.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (le($$emp.getField(1), "Julio"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$15, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$19, 1, $$19, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+              order (ASC, $$19)
+              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$19])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$18, $$19] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 0, 1, $$17, true, true, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$17] <- ["Julio"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-58.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-58.plan
index 218a98c..3c70ceb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-58.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-58.plan
@@ -1,16 +1,32 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(gt($$18, "Neil"), lt($$18, "Roger"))) project: [$$emp]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$18] <- [$$emp.getField(1)]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+            unnest-map [$$19, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$23, 1, $$23, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$23)
                 -- STABLE_SORT [$$23(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$23])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                        unnest-map [$$22, $$23] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 1, $$20, 1, $$21, false, false, false)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$20, $$21] <- ["Neil", "Roger"]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-59.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-59.plan
index 218a98c..abe816f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-59.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-59.plan
@@ -1,16 +1,32 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(ge($$18, "Max"), le($$18, "Roger"))) project: [$$emp]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$18] <- [$$emp.getField(1)]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+            unnest-map [$$19, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$23, 1, $$23, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$23)
                 -- STABLE_SORT [$$23(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$23])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                        unnest-map [$$22, $$23] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 1, $$20, 1, $$21, true, true, false)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$20, $$21] <- ["Max", "Roger"]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-60.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-60.plan
index 49dab53..cf5b4de 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-60.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-60.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (eq($$emp.getField(1), "Max"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$15, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+              order (ASC, $$20)
+              -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$20])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$19, $$20] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 1, $$17, 1, $$18, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$17, $$18] <- ["Max", "Max"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-61.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-61.plan
index 95526b9..20c76f1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-61.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-61.plan
@@ -1,16 +1,32 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(lt($$22, "Tomes"), gt($$22, "Kevin"), gt($$23, "Craig"), le($$23, "Mary"))) project: [$$emp]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$23, $$22] <- [$$emp.getField(1), $$emp.getField(2)]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+            unnest-map [$$24, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$31, 1, $$31, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$31)
                 -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$31])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                        unnest-map [$$29, $$30, $$31] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 2, $$25, $$26, 2, $$27, $$28, true, true, false)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$25, $$26, $$27, $$28] <- ["Craig", "Kevin", "Mary", "Tomes"]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-62.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-62.plan
index 0746bd8..c000e55 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-62.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-62.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(eq($$emp.getField(1), "Julio"), gt($$emp.getField(2), "Xu")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$25, 1, $$25, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+              order (ASC, $$25)
+              -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$25])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$23, $$24, $$25] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 1, $$21, 1, $$22, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$21, $$22] <- ["Julio", "Julio"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-63.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-63.plan
index e7a5c31..d632c0b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-63.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-63.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(lt($$emp.getField(1), "Julio"), eq($$emp.getField(2), "Xu")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$24, 1, $$24, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$23(ASC)]  |PARTITIONED|
+              order (ASC, $$24)
+              -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$24])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$22, $$23, $$24] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 0, 1, $$21, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$21] <- ["Julio"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-68.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-68.plan
index 25f3a1f..68c69a7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-68.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-68.plan
@@ -1,30 +1,60 @@
+distribute result [$$25]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$25] <- [{"o_custkey": $$28, "o_orderkey": $$29, "o_orderstatus": $$34}] project: [$$25]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$28(ASC), $$29(ASC) ]  |PARTITIONED|
+        order (ASC, $$28) (ASC, $$29)
         -- STABLE_SORT [$$28(ASC), $$29(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(eq($$Orders.getField(5), "1-URGENT"), le($$28, 43), ge($$28, 40))) project: [$$28, $$29, $$34]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$34, $$28] <- [$$Orders.getField(2), $$Orders.getField(1)]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (tpch.Orders.Orders)  |PARTITIONED|
+                  unnest-map [$$29, $$Orders] <- index-search("Orders", 0, "Default", "tpch", "Orders", false, false, 1, $$43, 1, $$43, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      intersect [$$43] <- [[$$38], [$$42]]
                       -- INTERSECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$38)
                           -- STABLE_SORT [$$38(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$38])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (tpch.Orders.idx_custkey)  |PARTITIONED|
+                                  unnest-map [$$37, $$38] <- index-search("idx_custkey", 0, "Default", "tpch", "Orders", false, false, 1, $$35, 1, $$36, true, true, false)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$35, $$36] <- [40, 43]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$42)
                           -- STABLE_SORT [$$42(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$42])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (tpch.Orders.idx_orderpriority)  |PARTITIONED|
+                                  unnest-map [$$41, $$42] <- index-search("idx_orderpriority", 0, "Default", "tpch", "Orders", false, false, 1, $$39, 1, $$40, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$39, $$40] <- ["1-URGENT", "1-URGENT"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-68_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-68_ps.plan
index d9ccf43..efa09d2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-68_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-68_ps.plan
@@ -1,66 +1,132 @@
+distribute result [$$25]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$25] <- [{"o_custkey": $$28, "o_orderkey": $$29, "o_orderstatus": $$34}] project: [$$25]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$28) (ASC, $$29)
         -- STABLE_SORT [$$28(ASC), $$29(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$28(ASC), $$29(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$47
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (and(eq($$Orders.getField(5), "1-URGENT"), le($$28, 43), ge($$28, 40))) project: [$$28, $$29, $$34]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$34, $$28] <- [$$Orders.getField(2), $$Orders.getField(1)]
                       -- ASSIGN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (tpch.Orders.Orders)  |PARTITIONED|
+                          unnest-map [$$29, $$Orders] <- index-search("Orders", 0, "Default", "tpch", "Orders", false, false, 1, $$43, 1, $$43, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              intersect [$$43] <- [[$$38], [$$42]]
                               -- INTERSECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$38)
                                   -- STABLE_SORT [$$38(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$38])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH (tpch.Orders.idx_custkey)  |PARTITIONED|
+                                          unnest-map [$$37, $$38] <- index-search("idx_custkey", 0, "Default", "tpch", "Orders", false, false, 1, $$35, 1, $$36, true, true, false)
+                                          -- BTREE_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$35, $$36] <- [40, 43]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$42)
                                   -- STABLE_SORT [$$42(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$42])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH (tpch.Orders.idx_orderpriority)  |PARTITIONED|
+                                          unnest-map [$$41, $$42] <- index-search("idx_orderpriority", 0, "Default", "tpch", "Orders", false, false, 1, $$39, 1, $$40, true, true, true)
+                                          -- BTREE_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$39, $$40] <- ["1-URGENT", "1-URGENT"]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$47] <- [agg-range-map($$44, $$45, $$46)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$44, $$45, $$46] <- [agg-local-sampling($$28, $$29), agg-null-writer($$28), agg-null-writer($$29)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$28, $$29])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (and(eq($$Orders.getField(5), "1-URGENT"), le($$28, 43), ge($$28, 40))) project: [$$28, $$29, $$34]
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$34, $$28] <- [$$Orders.getField(2), $$Orders.getField(1)]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (tpch.Orders.Orders)  |PARTITIONED|
+                                    unnest-map [$$29, $$Orders] <- index-search("Orders", 0, "Default", "tpch", "Orders", false, false, 1, $$43, 1, $$43, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        intersect [$$43] <- [[$$38], [$$42]]
                                         -- INTERSECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$38)
                                             -- STABLE_SORT [$$38(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$38])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (tpch.Orders.idx_custkey)  |PARTITIONED|
+                                                    unnest-map [$$37, $$38] <- index-search("idx_custkey", 0, "Default", "tpch", "Orders", false, false, 1, $$35, 1, $$36, true, true, false)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        assign [$$35, $$36] <- [40, 43]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$42)
                                             -- STABLE_SORT [$$42(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$42])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (tpch.Orders.idx_orderpriority)  |PARTITIONED|
+                                                    unnest-map [$$41, $$42] <- index-search("idx_orderpriority", 0, "Default", "tpch", "Orders", false, false, 1, $$39, 1, $$40, true, true, true)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        assign [$$39, $$40] <- ["1-URGENT", "1-URGENT"]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-01-disable-idxonly.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-01-disable-idxonly.plan
index f70a511..aa7bb57 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-01-disable-idxonly.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-01-disable-idxonly.plan
@@ -1,19 +1,38 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$18] <- [{"pk": $$21, "sk": $$20}] project: [$$18]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$20, 3))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$20] <- [$$o.getField(1)] project: [$$21, $$20]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.MyData.MyData)  |PARTITIONED|
+                  unnest-map [$$21, $$o] <- index-search("MyData", 0, "Default", "test", "MyData", false, false, 1, $$26, 1, $$26, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$26)
                       -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$26])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.MyData.btree_index_docid)  |PARTITIONED|
+                              unnest-map [$$25, $$26] <- index-search("btree_index_docid", 0, "Default", "test", "MyData", false, false, 0, 1, $$24, true, false, false)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$24] <- [3]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-01-disable-idxonly_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-01-disable-idxonly_ps.plan
index 7852236..c558730 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-01-disable-idxonly_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-01-disable-idxonly_ps.plan
@@ -1,44 +1,88 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$18] <- [{"pk": $$21, "sk": $$20}] project: [$$18]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$29
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (lt($$20, 3))
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$20] <- [$$o.getField(1)] project: [$$21, $$20]
                       -- ASSIGN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.MyData.MyData)  |PARTITIONED|
+                          unnest-map [$$21, $$o] <- index-search("MyData", 0, "Default", "test", "MyData", false, false, 1, $$26, 1, $$26, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$26)
                               -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$26])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.MyData.btree_index_docid)  |PARTITIONED|
+                                      unnest-map [$$25, $$26] <- index-search("btree_index_docid", 0, "Default", "test", "MyData", false, false, 0, 1, $$24, true, false, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$24] <- [3]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$29] <- [agg-range-map($$27, $$28)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$27, $$28] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$21])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (lt($$20, 3))
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$20] <- [$$o.getField(1)] project: [$$21, $$20]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.MyData.MyData)  |PARTITIONED|
+                                    unnest-map [$$21, $$o] <- index-search("MyData", 0, "Default", "test", "MyData", false, false, 1, $$26, 1, $$26, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$26)
                                         -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$26])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.MyData.btree_index_docid)  |PARTITIONED|
+                                                unnest-map [$$25, $$26] <- index-search("btree_index_docid", 0, "Default", "test", "MyData", false, false, 0, 1, $$24, true, false, false)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$24] <- [3]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-01.plan
index 82888fd..4b1047a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-01.plan
@@ -1,29 +1,58 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$18] <- [{"pk": $$21, "sk": $$20}] project: [$$18]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            union ($$31, $$26, $$21) ($$33, $$25, $$20)
             -- UNION_ALL  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (lt($$33, 3))
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$33] <- [$$32.getField(1)] project: [$$31, $$33]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.MyData.MyData)  |PARTITIONED|
+                      unnest-map [$$31, $$32] <- index-search("MyData", 0, "Default", "test", "MyData", false, false, 1, $$26, 1, $$26, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          split ($$27)
                           -- SPLIT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.MyData.btree_index_docid)  |PARTITIONED|
+                              unnest-map [$$25, $$26, $$27] <- index-search("btree_index_docid", 0, "Default", "test", "MyData", false, false, 0, 1, $$24, true, false, false)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$24] <- [3]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (lt($$25, 3)) project: [$$26, $$25]
                 -- STREAM_SELECT  |PARTITIONED|
+                  project ([$$25, $$26])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      split ($$27)
                       -- SPLIT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.MyData.btree_index_docid)  |PARTITIONED|
+                          unnest-map [$$25, $$26, $$27] <- index-search("btree_index_docid", 0, "Default", "test", "MyData", false, false, 0, 1, $$24, true, false, false)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$24] <- [3]
                               -- ASSIGN  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-01_ps.plan
index 5e00152..c4b1f53 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-01_ps.plan
@@ -1,64 +1,128 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$18] <- [{"pk": $$21, "sk": $$20}] project: [$$18]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$36
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    union ($$31, $$26, $$21) ($$33, $$25, $$20)
                     -- UNION_ALL  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        select (lt($$33, 3))
                         -- STREAM_SELECT  |PARTITIONED|
+                          assign [$$33] <- [$$32.getField(1)] project: [$$31, $$33]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.MyData.MyData)  |PARTITIONED|
+                              unnest-map [$$31, $$32] <- index-search("MyData", 0, "Default", "test", "MyData", false, false, 1, $$26, 1, $$26, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  split ($$27)
                                   -- SPLIT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.MyData.btree_index_docid)  |PARTITIONED|
+                                      unnest-map [$$25, $$26, $$27] <- index-search("btree_index_docid", 0, "Default", "test", "MyData", false, false, 0, 1, $$24, true, false, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$24] <- [3]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        select (lt($$25, 3)) project: [$$26, $$25]
                         -- STREAM_SELECT  |PARTITIONED|
+                          project ([$$25, $$26])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              split ($$27)
                               -- SPLIT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.MyData.btree_index_docid)  |PARTITIONED|
+                                  unnest-map [$$25, $$26, $$27] <- index-search("btree_index_docid", 0, "Default", "test", "MyData", false, false, 0, 1, $$24, true, false, false)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$24] <- [3]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$36] <- [agg-range-map($$34, $$35)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$34, $$35] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$21])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              union ($$31, $$26, $$21) ($$33, $$25, $$20)
                               -- UNION_ALL  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  select (lt($$33, 3))
                                   -- STREAM_SELECT  |PARTITIONED|
+                                    assign [$$33] <- [$$32.getField(1)] project: [$$31, $$33]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.MyData.MyData)  |PARTITIONED|
+                                        unnest-map [$$31, $$32] <- index-search("MyData", 0, "Default", "test", "MyData", false, false, 1, $$26, 1, $$26, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            split ($$27)
                                             -- SPLIT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.MyData.btree_index_docid)  |PARTITIONED|
+                                                unnest-map [$$25, $$26, $$27] <- index-search("btree_index_docid", 0, "Default", "test", "MyData", false, false, 0, 1, $$24, true, false, false)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$24] <- [3]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  select (lt($$25, 3)) project: [$$26, $$25]
                                   -- STREAM_SELECT  |PARTITIONED|
+                                    project ([$$25, $$26])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        split ($$27)
                                         -- SPLIT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- BTREE_SEARCH (test.MyData.btree_index_docid)  |PARTITIONED|
+                                            unnest-map [$$25, $$26, $$27] <- index-search("btree_index_docid", 0, "Default", "test", "MyData", false, false, 0, 1, $$24, true, false, false)
+                                            -- BTREE_SEARCH  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                assign [$$24] <- [3]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-10.plan
index 794a51d..9b9881a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-sidx-idxonly-10.plan
@@ -1,31 +1,62 @@
+distribute result [$$73]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    aggregate [$$73] <- [agg-sql-sum($$80)]
     -- AGGREGATE  |UNPARTITIONED|
+      exchange
       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+        aggregate [$$80] <- [agg-sql-count(1)]
         -- AGGREGATE  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            union
             -- UNION_ALL  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (and(ge($$95, 0), lt($$95, 1000000), lt($$96, date: { 2002-11-09 }), ge($$96, date: { 1997-05-19 }))) project: []
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$95, $$96] <- [$$72.getField(10), $$72.getField(6)] project: [$$95, $$96]
                   -- ASSIGN  |PARTITIONED|
+                    assign [$$72] <- [$$94.getField(12)] project: [$$72]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$94])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (twitter.ds_tweet.ds_tweet)  |PARTITIONED|
+                          unnest-map [$$93, $$94] <- index-search("ds_tweet", 0, "Default", "twitter", "ds_tweet", false, false, 1, $$87, 1, $$87, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              split ($$88)
                               -- SPLIT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (twitter.ds_tweet.create_at_status_count_idx)  |PARTITIONED|
+                                  unnest-map [$$85, $$86, $$87, $$88] <- index-search("create_at_status_count_idx", 0, "Default", "twitter", "ds_tweet", false, false, 2, $$81, $$82, 2, $$83, $$84, true, true, false)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$81, $$82, $$83, $$84] <- [date: { 1997-05-19 }, 0, date: { 2002-11-09 }, 1000000]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (and(ge($$86, 0), lt($$86, 1000000), lt($$85, date: { 2002-11-09 }), ge($$85, date: { 1997-05-19 }))) project: []
                 -- STREAM_SELECT  |PARTITIONED|
+                  project ([$$85, $$86])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      split ($$88)
                       -- SPLIT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (twitter.ds_tweet.create_at_status_count_idx)  |PARTITIONED|
+                          unnest-map [$$85, $$86, $$87, $$88] <- index-search("create_at_status_count_idx", 0, "Default", "twitter", "ds_tweet", false, false, 2, $$81, $$82, 2, $$83, $$84, true, true, false)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$81, $$82, $$83, $$84] <- [date: { 1997-05-19 }, 0, date: { 2002-11-09 }, 1000000]
                               -- ASSIGN  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-ternary-inlj/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-ternary-inlj/query1.plan
index 82658f0..84f7d6e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-ternary-inlj/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-ternary-inlj/query1.plan
@@ -1,33 +1,66 @@
+distribute result [$$65]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$65] <- [{"$1": $$71}] project: [$$65]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$71] <- [agg-sql-sum($$73)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$73] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (eq($$67, $$B.getField("k")))
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$67, $$B])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.IndexDatasetB.IndexDatasetB)  |PARTITIONED|
+                  unnest-map [$$69, $$B] <- index-search("IndexDatasetB", 0, "Default", "TestDataverse", "IndexDatasetB", true, false, 1, $$77, 1, $$77, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$77)
                       -- STABLE_SORT [$$77(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$67, $$77])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (TestDataverse.IndexDatasetB.indexB)  |PARTITIONED|
+                              unnest-map [$$76, $$77] <- index-search("indexB", 0, "Default", "TestDataverse", "IndexDatasetB", true, true, 1, $$67, 1, $$67, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  select (eq($$67, $$A.getField("k"))) project: [$$67]
                                   -- STREAM_SELECT  |PARTITIONED|
+                                    project ([$$67, $$A])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (TestDataverse.IndexDatasetA.IndexDatasetA)  |PARTITIONED|
+                                        unnest-map [$$68, $$A] <- index-search("IndexDatasetA", 0, "Default", "TestDataverse", "IndexDatasetA", true, false, 1, $$75, 1, $$75, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$75)
                                             -- STABLE_SORT [$$75(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$67, $$75])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (TestDataverse.IndexDatasetA.indexA)  |PARTITIONED|
+                                                    unnest-map [$$74, $$75] <- index-search("indexA", 0, "Default", "TestDataverse", "IndexDatasetA", true, true, 1, $$67, 1, $$67, true, true, true)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        project ([$$67])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (TestDataverse.ProbeDataset)  |PARTITIONED|
+                                                            data-scan []<-[$$67, $$P] <- TestDataverse.ProbeDataset
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-ternary-inlj/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-ternary-inlj/query2.plan
index 42c4f34..03ebcdc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-ternary-inlj/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-ternary-inlj/query2.plan
@@ -1,34 +1,68 @@
+distribute result [$$65]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$65] <- [{"$1": $$71}] project: [$$65]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$71] <- [agg-sql-sum($$73)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$73] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (eq($$66, $$B.getField("k")))
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$66, $$B])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.IndexDatasetB.IndexDatasetB)  |PARTITIONED|
+                  unnest-map [$$69, $$B] <- index-search("IndexDatasetB", 0, "Default", "TestDataverse", "IndexDatasetB", true, false, 1, $$77, 1, $$77, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$77)
                       -- STABLE_SORT [$$77(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$66, $$77])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (TestDataverse.IndexDatasetB.indexB)  |PARTITIONED|
+                              unnest-map [$$76, $$77] <- index-search("indexB", 0, "Default", "TestDataverse", "IndexDatasetB", true, true, 1, $$66, 1, $$66, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  select (eq($$66, $$A.getField("k"))) project: [$$66]
                                   -- STREAM_SELECT  |PARTITIONED|
+                                    project ([$$66, $$A])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (TestDataverse.IndexDatasetA.IndexDatasetA)  |PARTITIONED|
+                                        unnest-map [$$68, $$A] <- index-search("IndexDatasetA", 0, "Default", "TestDataverse", "IndexDatasetA", true, false, 1, $$75, 1, $$75, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$75)
                                             -- STABLE_SORT [$$75(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$66, $$75])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (TestDataverse.IndexDatasetA.indexA)  |PARTITIONED|
+                                                    unnest-map [$$74, $$75] <- index-search("indexA", 0, "Default", "TestDataverse", "IndexDatasetA", true, true, 1, $$66, 1, $$66, true, true, true)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        assign [$$66] <- [$$P.getField(1)] project: [$$66]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          project ([$$P])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN (TestDataverse.ProbeDataset)  |PARTITIONED|
+                                                              data-scan []<-[$$67, $$P] <- TestDataverse.ProbeDataset
+                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-ternary-inlj/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-ternary-inlj/query3.plan
index 1bb7cee..a761acb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-ternary-inlj/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-ternary-inlj/query3.plan
@@ -1,45 +1,90 @@
+distribute result [$$80]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$80] <- [{"$1": $$87}] project: [$$80]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$87] <- [agg-sql-sum($$90)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$90] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (eq($$81, $$C.getField("k")))
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$81, $$C])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.IndexDatasetC.IndexDatasetC)  |PARTITIONED|
+                  unnest-map [$$85, $$C] <- index-search("IndexDatasetC", 0, "Default", "TestDataverse", "IndexDatasetC", true, false, 1, $$96, 1, $$96, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$96)
                       -- STABLE_SORT [$$96(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$81, $$96])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (TestDataverse.IndexDatasetC.indexC)  |PARTITIONED|
+                              unnest-map [$$95, $$96] <- index-search("indexC", 0, "Default", "TestDataverse", "IndexDatasetC", true, true, 1, $$81, 1, $$81, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  select (eq($$81, $$B.getField("k"))) project: [$$81]
                                   -- STREAM_SELECT  |PARTITIONED|
+                                    project ([$$81, $$B])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (TestDataverse.IndexDatasetB.IndexDatasetB)  |PARTITIONED|
+                                        unnest-map [$$84, $$B] <- index-search("IndexDatasetB", 0, "Default", "TestDataverse", "IndexDatasetB", true, false, 1, $$94, 1, $$94, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$94)
                                             -- STABLE_SORT [$$94(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$81, $$94])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (TestDataverse.IndexDatasetB.indexB)  |PARTITIONED|
+                                                    unnest-map [$$93, $$94] <- index-search("indexB", 0, "Default", "TestDataverse", "IndexDatasetB", true, true, 1, $$81, 1, $$81, true, true, true)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        select (eq($$81, $$A.getField("k"))) project: [$$81]
                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                          project ([$$81, $$A])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (TestDataverse.IndexDatasetA.IndexDatasetA)  |PARTITIONED|
+                                                              unnest-map [$$83, $$A] <- index-search("IndexDatasetA", 0, "Default", "TestDataverse", "IndexDatasetA", true, false, 1, $$92, 1, $$92, true, true, true)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  order (ASC, $$92)
                                                                   -- STABLE_SORT [$$92(ASC)]  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      project ([$$81, $$92])
                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                          -- BTREE_SEARCH (TestDataverse.IndexDatasetA.indexA)  |PARTITIONED|
+                                                                          unnest-map [$$91, $$92] <- index-search("indexA", 0, "Default", "TestDataverse", "IndexDatasetA", true, true, 1, $$81, 1, $$81, true, true, true)
+                                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                                            exchange
                                                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                              assign [$$81] <- [$$P.getField(1)] project: [$$81]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                project ([$$P])
                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                    -- DATASOURCE_SCAN (TestDataverse.ProbeDataset)  |PARTITIONED|
+                                                                                    data-scan []<-[$$82, $$P] <- TestDataverse.ProbeDataset
+                                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        empty-tuple-source
                                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-ternary-inlj/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-ternary-inlj/query4.plan
index 2018224..bb3af35 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-ternary-inlj/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-ternary-inlj/query4.plan
@@ -1,30 +1,60 @@
+distribute result [$$70]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$70] <- [{"$1": $$75}] project: [$$70]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$75] <- [agg-sql-sum($$80)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$80] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$74, $$61))
               -- HYBRID_HASH_JOIN [$$61][$$74]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$61])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (tpcds.customer_address.customer_address)  |PARTITIONED|
+                      unnest-map [$$73, $$ca] <- index-search("customer_address", 0, "Default", "tpcds", "customer_address", true, true, 1, $$78, 1, $$78, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$78)
                           -- STABLE_SORT [$$78(ASC)]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$78]  |PARTITIONED|
+                              project ([$$78, $$61])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (tpcds.customer_demographics.customer_demographics)  |PARTITIONED|
+                                  unnest-map [$$72, $$cd2] <- index-search("customer_demographics", 0, "Default", "tpcds", "customer_demographics", true, true, 1, $$76, 1, $$76, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$76)
                                       -- STABLE_SORT [$$76(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$76]  |PARTITIONED|
+                                          assign [$$78, $$61, $$76] <- [$$c.getField(4), $$c.getField(12), $$c.getField(2)] project: [$$78, $$61, $$76]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$c])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpcds.customer)  |PARTITIONED|
+                                                data-scan []<-[$$71, $$c] <- tpcds.customer
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  unnest $$74 <- scan-collection(array: [ 4, 5 ])
                   -- UNNEST  |UNPARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q1.plan
index 8fe17e7..3f3bf58 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q1.plan
@@ -1,25 +1,44 @@
+distribute result [$$95]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$95] <- [{"ol_number": $$ol_number, "sum_qty": $$99, "sum_amount": $$100, "avg_qty": $$101, "avg_amount": $$102, "COUNT_order": $$103}] project: [$$95]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$ol_number(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$111]  |PARTITIONED|
-                {
+        group by ([$$ol_number := $$111]) decor ([]) {
+                  aggregate [$$99, $$100, $$101, $$102, $$103] <- [agg-global-sql-sum($$106), agg-global-sql-sum($$107), agg-global-sql-avg($$108), agg-global-sql-avg($$109), agg-sql-sum($$110)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$111]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$111]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$96]  |PARTITIONED|
-                    {
+            group by ([$$111 := $$96]) decor ([]) {
+                      aggregate [$$106, $$107, $$108, $$109, $$110] <- [agg-local-sql-sum($$75), agg-local-sql-sum($$80), agg-local-sql-avg($$75), agg-local-sql-avg($$80), agg-sql-count(1)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$96]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (gt($$ol.getField("ol_delivery_d"), "2014-07-01 00:00:00")) project: [$$75, $$80, $$96]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$80, $$75, $$96] <- [$$ol.getField("ol_amount"), $$ol.getField("ol_quantity"), $$ol.getField("ol_number")]
                   -- ASSIGN  |PARTITIONED|
+                    unnest $$ol <- scan-collection($$104) project: [$$ol]
                     -- UNNEST  |PARTITIONED|
+                      assign [$$104] <- [$$o.getField("o_orderline")] project: [$$104]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$o])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                            data-scan []<-[$$98, $$o] <- test.orders
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q10.plan
index df289e3..f224090 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q10.plan
@@ -1,52 +1,98 @@
+distribute result [$$159]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 20
     -- STREAM_LIMIT  |UNPARTITIONED|
+      assign [$$159] <- [{"c_id": $$c_id, "c_last": $$c_last, "revenue": $$175, "c_city": $$c_city, "c_phone": $$c_phone, "n_name": $$n_name}] project: [$$159]
       -- ASSIGN  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$175(DESC) ]  |PARTITIONED|
+          limit 20
           -- STREAM_LIMIT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (topK: 20) (DESC, $$175)
               -- STABLE_SORT [topK: 20] [$$175(DESC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- SORT_GROUP_BY[$$182, $$183, $$184, $$185, $$186]  |PARTITIONED|
-                          {
+                  group by ([$$c_id := $$182; $$c_last := $$183; $$c_city := $$184; $$c_phone := $$185; $$n_name := $$186]) decor ([]) {
+                            aggregate [$$175] <- [agg-global-sql-sum($$181)]
                             -- AGGREGATE  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                          }
+                         }
+                  -- SORT_GROUP_BY[$$182, $$183, $$184, $$185, $$186]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$182, $$183, $$184, $$185, $$186]  |PARTITIONED|
-                      -- SORT_GROUP_BY[$$166, $$161, $$162, $$163, $$164]  |PARTITIONED|
-                              {
+                      group by ([$$182 := $$166; $$183 := $$161; $$184 := $$162; $$185 := $$163; $$186 := $$164]) decor ([]) {
+                                aggregate [$$181] <- [agg-local-sql-sum($$156)]
                                 -- AGGREGATE  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- SORT_GROUP_BY[$$166, $$161, $$162, $$163, $$164]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$156, $$166, $$161, $$162, $$163, $$164])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              join (and(eq($$166, $$170), eq($$171, $$172), eq($$173, $$174)))
                               -- HYBRID_HASH_JOIN [$$166, $$171, $$173][$$170, $$172, $$174]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$166, $$171, $$173]  |PARTITIONED|
+                                  project ([$$166, $$161, $$162, $$163, $$164, $$171, $$173])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      join (eq($$176, $$177))
                                       -- HYBRID_HASH_JOIN [$$176][$$177]  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$176]  |PARTITIONED|
+                                          assign [$$164, $$176] <- [$$n.getField("n_name"), $$n.getField("n_nationkey")] project: [$$164, $$176]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$n])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                data-scan []<-[$$167, $$n] <- test.nation
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$177]  |PARTITIONED|
+                                          assign [$$177, $$163, $$162, $$161, $$173, $$171, $$166] <- [get-item(string-to-codepoint($$c.getField("c_state")), 0), $$c.getField("c_phone"), $$c.getField("c_city"), $$c.getField("c_last"), $$c.getField("c_w_id"), $$c.getField("c_d_id"), $$c.getField("c_id")] project: [$$166, $$161, $$162, $$163, $$171, $$173, $$177]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$c])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.customer)  |PARTITIONED|
+                                                data-scan []<-[$$168, $$c] <- test.customer
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$170, $$172, $$174]  |PARTITIONED|
+                                  assign [$$156] <- [$$ol.getField("ol_amount")] project: [$$156, $$170, $$172, $$174]
                                   -- ASSIGN  |PARTITIONED|
+                                    unnest $$ol <- scan-collection($$179) project: [$$174, $$172, $$170, $$ol]
                                     -- UNNEST  |PARTITIONED|
+                                      select (and(lt($$165, "2016-01-01 00:00:00.000000"), ge($$165, "2015-10-01 00:00:00.000000"))) project: [$$174, $$172, $$170, $$179]
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        assign [$$174, $$172, $$170, $$165, $$179] <- [$$o.getField("o_w_id"), $$o.getField("o_d_id"), $$o.getField("o_c_id"), $$o.getField("o_entry_d"), $$o.getField("o_orderline")] project: [$$174, $$172, $$170, $$165, $$179]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$o])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                              data-scan []<-[$$169, $$o] <- test.orders
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q11.plan
index 4ef2cfe..0ff988c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q11.plan
@@ -1,107 +1,208 @@
+distribute result [$$176]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$176] <- [{"s_i_id": $$s_i_id, "ordercount": $$188}] project: [$$176]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$188(DESC) ]  |PARTITIONED|
+        order (DESC, $$188)
         -- STABLE_SORT [$$188(DESC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$s_i_id, $$188])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (gt($$187, $$199))
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$214]  |PARTITIONED|
-                            {
+                    group by ([$$s_i_id := $$214]) decor ([]) {
+                              aggregate [$$187, $$188] <- [agg-global-sql-sum($$212), agg-global-sql-sum($$213)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$214]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$214]  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$178]  |PARTITIONED|
-                                {
+                        group by ([$$214 := $$178]) decor ([]) {
+                                  aggregate [$$212, $$213] <- [agg-local-sql-sum($$142), agg-local-sql-sum($$142)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$178]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$142, $$178])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$185, $$186))
                                 -- HYBRID_HASH_JOIN [$$186][$$185]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$186]  |PARTITIONED|
+                                    project ([$$186])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        join (eq($$197, $$198))
                                         -- HYBRID_HASH_JOIN [$$198][$$197]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$198] <- [$$203] project: [$$198]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$203]  |PARTITIONED|
+                                                    select (eq($$191.getField("n_name"), "Germany")) project: [$$203]
                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                      assign [$$203] <- [$$191.getField("n_nationkey")]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$191])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                            data-scan []<-[$$196, $$191] <- test.nation
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$186, $$197] <- [$$201, $$202] project: [$$186, $$197]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$202]  |PARTITIONED|
+                                                    assign [$$201, $$202] <- [$$192.getField("su_suppkey"), $$192.getField("su_nationkey")] project: [$$201, $$202]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$192])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                                          data-scan []<-[$$195, $$192] <- test.supplier
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$185]  |PARTITIONED|
+                                    assign [$$185] <- [numeric-mod(numeric-multiply($$s.getField("s_w_id"), $$178), 10000)] project: [$$142, $$178, $$185]
                                     -- ASSIGN  |PARTITIONED|
+                                      assign [$$178, $$142] <- [$$s.getField("s_i_id"), $$s.getField("s_order_cnt")]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$s])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                  data-scan []<-[$$181, $$s] <- test.stock
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    assign [$$199] <- [get-item($$167, 0)] project: [$$199]
                     -- ASSIGN  |UNPARTITIONED|
+                      aggregate [$$167] <- [listify($$166)]
                       -- AGGREGATE  |UNPARTITIONED|
+                        assign [$$166] <- [numeric-multiply($$211, 5.0E-5)] project: [$$166]
                         -- ASSIGN  |UNPARTITIONED|
+                          aggregate [$$211] <- [agg-global-sql-sum($$215)]
                           -- AGGREGATE  |UNPARTITIONED|
+                            exchange
                             -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                              aggregate [$$215] <- [agg-local-sql-sum($$163)]
                               -- AGGREGATE  |PARTITIONED|
+                                project ([$$163])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (eq($$200, $$201))
                                     -- HYBRID_HASH_JOIN [$$201][$$200]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$201]  |PARTITIONED|
+                                        project ([$$201])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            join (eq($$202, $$203))
                                             -- HYBRID_HASH_JOIN [$$203][$$202]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$203]  |PARTITIONED|
+                                                    select (eq($$191.getField("n_name"), "Germany")) project: [$$203]
                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                      assign [$$203] <- [$$191.getField("n_nationkey")]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$191])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                            data-scan []<-[$$196, $$191] <- test.nation
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$202]  |PARTITIONED|
+                                                    assign [$$201, $$202] <- [$$192.getField("su_suppkey"), $$192.getField("su_nationkey")] project: [$$201, $$202]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$192])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                                          data-scan []<-[$$195, $$192] <- test.supplier
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$200]  |PARTITIONED|
+                                        assign [$$200, $$163] <- [numeric-mod(numeric-multiply($$193.getField("s_w_id"), $$193.getField("s_i_id")), 10000), $$193.getField("s_order_cnt")] project: [$$163, $$200]
                                         -- ASSIGN  |PARTITIONED|
+                                          assign [$$193] <- [$$s] project: [$$193]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              replicate
                                               -- REPLICATE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  project ([$$s])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                      data-scan []<-[$$181, $$s] <- test.stock
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q12.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q12.plan
index dfb7cbc..514729f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q12.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q12.plan
@@ -1,25 +1,44 @@
+distribute result [$$88]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$88] <- [{"o_ol_cnt": $$o_ol_cnt, "high_line_COUNT": $$93, "low_line_COUNT": $$94}] project: [$$88]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$o_ol_cnt(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$100]  |PARTITIONED|
-                {
+        group by ([$$o_ol_cnt := $$100]) decor ([]) {
+                  aggregate [$$93, $$94] <- [agg-global-sql-sum($$98), agg-global-sql-sum($$99)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$100]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$100]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$89]  |PARTITIONED|
-                    {
+            group by ([$$100 := $$89]) decor ([]) {
+                      aggregate [$$98, $$99] <- [agg-local-sql-sum(switch-case(true, or(eq($$92, 1), eq($$92, 2)), 1, 0)), agg-local-sql-sum(switch-case(true, and(neq($$92, 1), neq($$92, 2)), 1, 0))]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$89]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (and(le($$o.getField("o_entry_d"), $$90), ge($$90, "2016-01-01 00:00:00.000000"), lt($$90, "2017-01-01 00:00:00.000000"))) project: [$$92, $$89]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$90] <- [$$ol.getField("ol_delivery_d")] project: [$$o, $$89, $$92, $$90]
                   -- ASSIGN  |PARTITIONED|
+                    unnest $$ol <- scan-collection($$95) project: [$$o, $$89, $$92, $$ol]
                     -- UNNEST  |PARTITIONED|
+                      assign [$$89, $$95, $$92] <- [$$o.getField("o_ol_cnt"), $$o.getField("o_orderline"), $$o.getField("o_carrier_id")]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$o])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                            data-scan []<-[$$91, $$o] <- test.orders
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q13.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q13.plan
index 7588ece..e390d92 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q13.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q13.plan
@@ -1,50 +1,88 @@
+distribute result [$$127]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$127] <- [{"c_count": $$c_count, "custdist": $$133}] project: [$$127]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$133(DESC), $$c_count(DESC) ]  |PARTITIONED|
+        order (DESC, $$133) (DESC, $$c_count)
         -- STABLE_SORT [$$133(DESC), $$c_count(DESC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- SORT_GROUP_BY[$$147]  |PARTITIONED|
-                    {
+            group by ([$$c_count := $$147]) decor ([]) {
+                      aggregate [$$133] <- [agg-sql-sum($$146)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$147]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$147]  |PARTITIONED|
-                -- SORT_GROUP_BY[$$132]  |PARTITIONED|
-                        {
+                group by ([$$147 := $$132]) decor ([]) {
+                          aggregate [$$146] <- [agg-sql-count(1)]
                           -- AGGREGATE  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SORT_GROUP_BY[$$132]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$132])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$145]  |PARTITIONED|
-                                {
+                        group by ([$$c_id := $$145]) decor ([]) {
+                                  aggregate [$$132] <- [agg-sql-sum($$144)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$145]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$145]  |PARTITIONED|
-                            -- SORT_GROUP_BY[$$134]  |PARTITIONED|
-                                    {
+                            group by ([$$145 := $$134]) decor ([]) {
+                                      aggregate [$$144] <- [agg-sql-count($$116)]
                                       -- AGGREGATE  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- SORT_GROUP_BY[$$134]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$116, $$134])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    left outer join (and(eq($$134, $$135), eq($$136, $$137), eq($$138, $$139)))
                                     -- HYBRID_HASH_JOIN [$$134, $$136, $$138][$$135, $$137, $$139]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$134, $$136, $$138]  |PARTITIONED|
+                                        assign [$$138, $$134, $$136] <- [$$c.getField("c_d_id"), $$c.getField("c_id"), $$c.getField("c_w_id")] project: [$$134, $$136, $$138]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$c])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.customer)  |PARTITIONED|
+                                              data-scan []<-[$$130, $$c] <- test.customer
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$135, $$137, $$139]  |PARTITIONED|
+                                        select (gt($$o.getField("o_carrier_id"), 8)) project: [$$116, $$135, $$137, $$139]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$139, $$137, $$135, $$116] <- [$$o.getField("o_d_id"), $$o.getField("o_w_id"), $$o.getField("o_c_id"), $$o.getField("o_id")]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$o])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                data-scan []<-[$$131, $$o] <- test.orders
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q14.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q14.plan
index 102418b..d696cc3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q14.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q14.plan
@@ -1,27 +1,54 @@
+distribute result [$$86]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$86] <- [{"promo_revenue": numeric-divide(numeric-multiply(100.0, $$94), numeric-add(1, $$95))}] project: [$$86]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$94, $$95] <- [agg-global-sql-sum($$99), agg-global-sql-sum($$100)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$99, $$100] <- [agg-local-sql-sum($$77), agg-local-sql-sum($$91)]
           -- AGGREGATE  |PARTITIONED|
+            assign [$$77] <- [switch-case(true, and(ge($$90, "pr"), lt($$90, "ps")), $$91, 0)] project: [$$77, $$91]
             -- ASSIGN  |PARTITIONED|
+              project ([$$90, $$91])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$92, $$93))
                   -- HYBRID_HASH_JOIN [$$93][$$92]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$93]  |PARTITIONED|
+                      assign [$$90, $$93] <- [$$i.getField("i_data"), $$i.getField("i_id")] project: [$$90, $$93]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$i])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.item)  |PARTITIONED|
+                            data-scan []<-[$$88, $$i] <- test.item
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$92]  |PARTITIONED|
+                      select (and(ge($$87, "2017-09-01 00:00:00.000000"), lt($$87, "2017-10-01 00:00:00.000000"))) project: [$$91, $$92]
                       -- STREAM_SELECT  |PARTITIONED|
+                        assign [$$91, $$92, $$87] <- [$$ol.getField("ol_amount"), $$ol.getField("ol_i_id"), $$ol.getField("ol_delivery_d")] project: [$$91, $$92, $$87]
                         -- ASSIGN  |PARTITIONED|
+                          unnest $$ol <- scan-collection($$96) project: [$$ol]
                           -- UNNEST  |PARTITIONED|
+                            assign [$$96] <- [$$o.getField("o_orderline")] project: [$$96]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$o])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                  data-scan []<-[$$89, $$o] <- test.orders
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q15.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q15.plan
index 78616bd..1b1cdb7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q15.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q15.plan
@@ -1,110 +1,208 @@
+distribute result [$$223]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$223] <- [{"su_suppkey": $$230, "su_name": $$272, "su_address": $$273, "su_phone": $$274, "total_revenue": $$231}] project: [$$223]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$230(ASC) ]  |PARTITIONED|
+        order (ASC, $$230)
         -- STABLE_SORT [$$230(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$230, $$272, $$273, $$274, $$231])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (eq($$230, $#1))
                 -- HYBRID_HASH_JOIN [$#1][$$230]  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                    project ([$$231, $#1])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$231, $$268))
                         -- HYBRID_HASH_JOIN [$$231][$$268]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$231]  |PARTITIONED|
+                            assign [$$231] <- [{"supplier_no": $#1, "total_rev": $$240}.getField("total_revenue")] project: [$$231, $#1]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- SORT_GROUP_BY[$$280]  |PARTITIONED|
-                                        {
+                                group by ([$#1 := $$280]) decor ([]) {
+                                          aggregate [$$240] <- [agg-global-sql-sum($$279)]
                                           -- AGGREGATE  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- SORT_GROUP_BY[$$280]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$280]  |PARTITIONED|
-                                    -- SORT_GROUP_BY[$$225]  |PARTITIONED|
-                                            {
+                                    group by ([$$280 := $$225]) decor ([]) {
+                                              aggregate [$$279] <- [agg-local-sql-sum($$169)]
                                               -- AGGREGATE  |LOCAL|
+                                                nested tuple source
                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                           }
+                                    -- SORT_GROUP_BY[$$225]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$225] <- [numeric-mod(numeric-multiply($$228, $$229), 10000)] project: [$$169, $$225]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$228, $$229, $$169])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              join (and(eq($$262, $$229), eq($$263, $$228)))
                                               -- HYBRID_HASH_JOIN [$$229, $$228][$$262, $$263]  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  assign [$$228, $$229] <- [$$250, $$251] project: [$$228, $$229]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- HASH_PARTITION_EXCHANGE [$$251, $$250]  |PARTITIONED|
+                                                          assign [$$251, $$250] <- [$$253.getField("s_i_id"), $$253.getField("s_w_id")] project: [$$250, $$251]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            project ([$$253])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                                data-scan []<-[$$258, $$253] <- test.stock
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                exchange
                                                 -- HASH_PARTITION_EXCHANGE [$$262, $$263]  |PARTITIONED|
+                                                  select (and(ge($$227, "2018-01-01 00:00:00.000000"), lt($$227, "2018-04-01 00:00:00.000000"))) project: [$$169, $$262, $$263]
                                                   -- STREAM_SELECT  |PARTITIONED|
+                                                    assign [$$169, $$263, $$262, $$227] <- [$$259, $$267, $$266, $$256] project: [$$169, $$263, $$262, $$227]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        replicate
                                                         -- REPLICATE  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            assign [$$259, $$267, $$266, $$256] <- [$$255.getField("ol_amount"), $$255.getField("ol_supply_w_id"), $$255.getField("ol_i_id"), $$255.getField("ol_delivery_d")] project: [$$259, $$267, $$266, $$256]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              unnest $$255 <- scan-collection($$270) project: [$$255]
                                                               -- UNNEST  |PARTITIONED|
+                                                                assign [$$270] <- [$$254.getField("o_orderline")] project: [$$270]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  project ([$$254])
                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                                      data-scan []<-[$$257, $$254] <- test.orders
+                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$268]  |PARTITIONED|
+                            assign [$$268] <- [get-item($$213, 0)] project: [$$268]
                             -- ASSIGN  |UNPARTITIONED|
+                              aggregate [$$213] <- [listify($$278)]
                               -- AGGREGATE  |UNPARTITIONED|
+                                aggregate [$$278] <- [agg-global-sql-max($$281)]
                                 -- AGGREGATE  |UNPARTITIONED|
+                                  exchange
                                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                    aggregate [$$281] <- [agg-local-sql-max($$210)]
                                     -- AGGREGATE  |PARTITIONED|
+                                      assign [$$210] <- [{"supplier_no": $$247, "total_rev": $$265}.getField("total_revenue")] project: [$$210]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- SORT_GROUP_BY[$$283]  |PARTITIONED|
-                                                  {
+                                          group by ([$$247 := $$283]) decor ([]) {
+                                                    aggregate [$$265] <- [agg-global-sql-sum($$282)]
                                                     -- AGGREGATE  |LOCAL|
+                                                      nested tuple source
                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                  }
+                                                 }
+                                          -- SORT_GROUP_BY[$$283]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$283]  |PARTITIONED|
-                                              -- SORT_GROUP_BY[$$249]  |PARTITIONED|
-                                                      {
+                                              group by ([$$283 := $$249]) decor ([]) {
+                                                        aggregate [$$282] <- [agg-local-sql-sum($$259)]
                                                         -- AGGREGATE  |LOCAL|
+                                                          nested tuple source
                                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                      }
+                                                     }
+                                              -- SORT_GROUP_BY[$$249]  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  assign [$$249] <- [numeric-mod(numeric-multiply($$250, $$251), 10000)] project: [$$259, $$249]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    project ([$$250, $$251, $$259])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        join (and(eq($$266, $$251), eq($$267, $$250)))
                                                         -- HYBRID_HASH_JOIN [$$251, $$250][$$266, $$267]  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            replicate
                                                             -- REPLICATE  |PARTITIONED|
+                                                              exchange
                                                               -- HASH_PARTITION_EXCHANGE [$$251, $$250]  |PARTITIONED|
+                                                                assign [$$251, $$250] <- [$$253.getField("s_i_id"), $$253.getField("s_w_id")] project: [$$250, $$251]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  project ([$$253])
                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                                      data-scan []<-[$$258, $$253] <- test.stock
+                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                          exchange
                                                           -- HASH_PARTITION_EXCHANGE [$$266, $$267]  |PARTITIONED|
+                                                            select (and(lt($$256, "2018-04-01 00:00:00.000000"), ge($$256, "2018-01-01 00:00:00.000000"))) project: [$$259, $$266, $$267]
                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                replicate
                                                                 -- REPLICATE  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    assign [$$259, $$267, $$266, $$256] <- [$$255.getField("ol_amount"), $$255.getField("ol_supply_w_id"), $$255.getField("ol_i_id"), $$255.getField("ol_delivery_d")] project: [$$259, $$267, $$266, $$256]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      unnest $$255 <- scan-collection($$270) project: [$$255]
                                                                       -- UNNEST  |PARTITIONED|
+                                                                        assign [$$270] <- [$$254.getField("o_orderline")] project: [$$270]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          project ([$$254])
                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                              -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                                              data-scan []<-[$$257, $$254] <- test.orders
+                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  empty-tuple-source
                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$230]  |PARTITIONED|
+                    assign [$$274, $$273, $$272, $$230] <- [$$su.getField("su_phone"), $$su.getField("su_address"), $$su.getField("su_name"), $$su.getField("su_suppkey")] project: [$$230, $$272, $$273, $$274]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$su])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                          data-scan []<-[$$234, $$su] <- test.supplier
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q16.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q16.plan
index e2aa179..9899664 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q16.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q16.plan
@@ -1,59 +1,112 @@
+distribute result [$$128]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$128] <- [{"i_name": $$i_name, "brand": $#1, "i_price": $$i_price, "supplier_cnt": $$139}] project: [$$128]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$139(DESC) ]  |PARTITIONED|
+        order (DESC, $$139)
         -- STABLE_SORT [$$139(DESC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- PRE_CLUSTERED_GROUP_BY[$$129, $$130, $$131]  |PARTITIONED|
-                    {
+            group by ([$$i_name := $$129; $#1 := $$130; $$i_price := $$131]) decor ([]) {
+                      aggregate [$$139] <- [agg-sql-count($$150)]
                       -- AGGREGATE  |LOCAL|
+                        distinct ([$$150])
                         -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                          order (ASC, $$150)
                           -- MICRO_STABLE_SORT [$$150(ASC)]  |LOCAL|
+                            assign [$$150] <- [numeric-mod(numeric-multiply($$143, $$144), 10000)]
                             -- ASSIGN  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- PRE_CLUSTERED_GROUP_BY[$$129, $$130, $$131]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$129) (ASC, $$130) (ASC, $$131)
                 -- STABLE_SORT [$$129(ASC), $$130(ASC), $$131(ASC)]  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$129, $$130, $$131]  |PARTITIONED|
+                    assign [$$130] <- [substring1($$132, 1, 3)] project: [$$143, $$144, $$129, $$130, $$131]
                     -- ASSIGN  |PARTITIONED|
+                      select ($$111) project: [$$129, $$131, $$132, $$144, $$143]
                       -- STREAM_SELECT  |PARTITIONED|
+                        project ([$$111, $$129, $$131, $$132, $$144, $$143])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- PRE_CLUSTERED_GROUP_BY[$$133, $$134]  |PARTITIONED|
-                                    {
+                            group by ([$$146 := $$133; $$147 := $$134]) decor ([$$129; $$131; $$132; $$144 := $$138; $$143 := $$141]) {
+                                      aggregate [$$111] <- [empty-stream()]
                                       -- AGGREGATE  |LOCAL|
+                                        select (not(is-missing($$145)))
                                         -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- PRE_CLUSTERED_GROUP_BY[$$133, $$134]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$133) (ASC, $$134)
                                 -- STABLE_SORT [$$133(ASC), $$134(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$133, $$134]  |PARTITIONED|
+                                    project ([$$129, $$131, $$132, $$145, $$133, $$134, $$138, $$141])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        left outer join (not(if-missing-or-null(neq(numeric-mod(numeric-multiply($$141, $$138), 10000), $$105), false)))
                                         -- NESTED_LOOP  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$129, $$131, $$132, $$133, $$134, $$138, $$141])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                join (eq($$137, $$138))
                                                 -- HYBRID_HASH_JOIN [$$138][$$137]  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$138]  |PARTITIONED|
+                                                    assign [$$138, $$141] <- [$$s.getField("s_i_id"), $$s.getField("s_w_id")] project: [$$133, $$138, $$141]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                        data-scan []<-[$$133, $$s] <- test.stock
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$137]  |PARTITIONED|
+                                                    select (not(like($$132, "zz%")))
                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                      assign [$$131, $$129, $$132, $$137] <- [$$i.getField("i_price"), $$i.getField("i_name"), $$i.getField("i_data"), $$i.getField("i_id")] project: [$$134, $$131, $$129, $$132, $$137]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.item)  |PARTITIONED|
+                                                          data-scan []<-[$$134, $$i] <- test.item
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            assign [$$145] <- [true]
                                             -- ASSIGN  |PARTITIONED|
+                                              select (like($$su.getField("su_comment"), "%Customer%Complaints%")) project: [$$105]
                                               -- STREAM_SELECT  |PARTITIONED|
+                                                assign [$$105] <- [$$su.getField("su_suppkey")]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  project ([$$su])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                                      data-scan []<-[$$135, $$su] <- test.supplier
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q17.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q17.plan
index 6c7c721..1df6122 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q17.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q17.plan
@@ -1,59 +1,112 @@
+distribute result [$$144]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$144] <- [{"AVG_yearly": numeric-divide($$155, 2.0)}] project: [$$144]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$155] <- [agg-global-sql-sum($$164)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$164] <- [agg-local-sql-sum($$141)]
           -- AGGREGATE  |PARTITIONED|
+            select (lt($$150, $$154)) project: [$$141]
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$154, $$141, $$150])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$152, $$i_id))
                   -- HYBRID_HASH_JOIN [$$i_id][$$152]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- PRE_CLUSTERED_GROUP_BY[$$163]  |PARTITIONED|
-                              {
+                      group by ([$$i_id := $$163]) decor ([]) {
+                                aggregate [$$154] <- [agg-global-sql-avg($$162)]
                                 -- AGGREGATE  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- PRE_CLUSTERED_GROUP_BY[$$163]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- SORT_GROUP_BY[$$146]  |PARTITIONED|
-                                  {
+                          group by ([$$163 := $$146]) decor ([]) {
+                                    aggregate [$$162] <- [agg-local-sql-avg($$122)]
                                     -- AGGREGATE  |LOCAL|
+                                      nested tuple source
                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
+                                 }
+                          -- SORT_GROUP_BY[$$146]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$122, $$146])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  join (eq($$156, $$146))
                                   -- HYBRID_HASH_JOIN [$$146][$$156]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$146]  |PARTITIONED|
+                                      select (like($$i.getField("i_data"), "%b")) project: [$$146]
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        assign [$$146] <- [$$i.getField("i_id")]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$i])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.item)  |PARTITIONED|
+                                              data-scan []<-[$$147, $$i] <- test.item
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$156]  |PARTITIONED|
+                                      assign [$$122, $$156] <- [$$ol1.getField("ol_quantity"), $$ol1.getField("ol_i_id")] project: [$$122, $$156]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              unnest $$ol1 <- scan-collection($$158) project: [$$ol1]
                                               -- UNNEST  |PARTITIONED|
+                                                assign [$$158] <- [$$o1.getField("o_orderline")] project: [$$158]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  project ([$$o1])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                      data-scan []<-[$$148, $$o1] <- test.orders
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$152]  |PARTITIONED|
+                      assign [$$141, $$152, $$150] <- [$$ol.getField("ol_amount"), $$ol.getField("ol_i_id"), $$ol.getField("ol_quantity")] project: [$$141, $$150, $$152]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$ol] <- [$$ol1] project: [$$ol]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                unnest $$ol1 <- scan-collection($$158) project: [$$ol1]
                                 -- UNNEST  |PARTITIONED|
+                                  assign [$$158] <- [$$o1.getField("o_orderline")] project: [$$158]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$o1])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                        data-scan []<-[$$148, $$o1] <- test.orders
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q18.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q18.plan
index 18d34b2..df7805b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q18.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q18.plan
@@ -1,44 +1,82 @@
+distribute result [$$169]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 100
     -- STREAM_LIMIT  |UNPARTITIONED|
+      assign [$$169] <- [{"c_last": $$c_last, "o_id": $$c_id, "o_entry_d": $$o_entry_d, "o_ol_cnt": $$o_ol_cnt, "$1": $$192}] project: [$$169]
       -- ASSIGN  |PARTITIONED|
+        project ([$$c_last, $$c_id, $$o_entry_d, $$o_ol_cnt, $$192])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- SORT_MERGE_EXCHANGE [$$193(DESC), $$o_entry_d(ASC) ]  |PARTITIONED|
+            limit 100
             -- STREAM_LIMIT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (topK: 100) (DESC, $$193) (ASC, $$o_entry_d)
                 -- STABLE_SORT [topK: 100] [$$193(DESC), $$o_entry_d(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (gt($$191, 200)) project: [$$c_last, $$c_id, $$o_entry_d, $$o_ol_cnt, $$192, $$193]
                     -- STREAM_SELECT  |PARTITIONED|
+                      project ([$$191, $$192, $$193, $$c_id, $$c_last, $$o_entry_d, $$o_ol_cnt])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- SORT_GROUP_BY[$$199, $$200, $$201, $$202, $$203, $$204, $$205]  |PARTITIONED|
-                                  {
+                          group by ([$$o_id := $$199; $$o_w_id := $$200; $$o_d_id := $$201; $$c_id := $$202; $$c_last := $$203; $$o_entry_d := $$204; $$o_ol_cnt := $$205]) decor ([]) {
+                                    aggregate [$$191, $$192, $$193] <- [agg-global-sql-sum($$196), agg-global-sql-sum($$197), agg-global-sql-sum($$198)]
                                     -- AGGREGATE  |LOCAL|
+                                      nested tuple source
                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
+                                 }
+                          -- SORT_GROUP_BY[$$199, $$200, $$201, $$202, $$203, $$204, $$205]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$199, $$200, $$201, $$202, $$203, $$204, $$205]  |PARTITIONED|
-                              -- SORT_GROUP_BY[$$175, $$183, $$184, $$185, $$179, $$180, $$181]  |PARTITIONED|
-                                      {
+                              group by ([$$199 := $$175; $$200 := $$183; $$201 := $$184; $$202 := $$185; $$203 := $$179; $$204 := $$180; $$205 := $$181]) decor ([]) {
+                                        aggregate [$$196, $$197, $$198] <- [agg-local-sql-sum($$160), agg-local-sql-sum($$160), agg-local-sql-sum($$160)]
                                         -- AGGREGATE  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- SORT_GROUP_BY[$$175, $$183, $$184, $$185, $$179, $$180, $$181]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$160, $$175, $$183, $$184, $$185, $$179, $$180, $$181])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      join (and(eq($$185, $$188), eq($$189, $$183), eq($$190, $$184)))
                                       -- HYBRID_HASH_JOIN [$$188, $$183, $$184][$$185, $$189, $$190]  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$188, $$183, $$184]  |PARTITIONED|
+                                          assign [$$160] <- [$$ol.getField("ol_amount")] project: [$$160, $$175, $$183, $$184, $$180, $$181, $$188]
                                           -- ASSIGN  |PARTITIONED|
+                                            unnest $$ol <- scan-collection($$194) project: [$$181, $$180, $$175, $$188, $$183, $$184, $$ol]
                                             -- UNNEST  |PARTITIONED|
+                                              assign [$$181, $$180, $$175, $$188, $$183, $$184, $$194] <- [$$o.getField("o_ol_cnt"), $$o.getField("o_entry_d"), $$o.getField("o_id"), $$o.getField("o_c_id"), $$o.getField("o_w_id"), $$o.getField("o_d_id"), $$o.getField("o_orderline")] project: [$$181, $$180, $$175, $$188, $$183, $$184, $$194]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$o])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                    data-scan []<-[$$186, $$o] <- test.orders
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$185, $$189, $$190]  |PARTITIONED|
+                                          assign [$$179, $$190, $$189, $$185] <- [$$c.getField("c_last"), $$c.getField("c_d_id"), $$c.getField("c_w_id"), $$c.getField("c_id")] project: [$$185, $$179, $$189, $$190]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$c])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.customer)  |PARTITIONED|
+                                                data-scan []<-[$$187, $$c] <- test.customer
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q19.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q19.plan
index 75be180..d12f3d6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q19.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q19.plan
@@ -1,28 +1,56 @@
+distribute result [$$120]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$120] <- [{"revenue": $$128}] project: [$$120]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$128] <- [agg-global-sql-sum($$133)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$133] <- [agg-local-sql-sum($$118)]
           -- AGGREGATE  |PARTITIONED|
+            select (or(and(like($$123, "%h"), ge($$122, 7), le($$122, 17), and($$134, le($$121, 5)), or(eq($$69, 37), eq($$69, 29), eq($$69, 70))), and(like($$123, "%t"), ge($$122, 16), le($$122, 26), and($$134, le($$121, 10)), or(eq($$69, 78), eq($$69, 17), eq($$69, 6))), and(like($$123, "%m"), ge($$122, 24), le($$122, 34), and($$134, $$135), or(eq($$69, 91), eq($$69, 95), eq($$69, 15))))) project: [$$118]
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$118, $$122, $$69, $$123, $$121, $$135, $$134])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$126, $$127))
                   -- HYBRID_HASH_JOIN [$$126][$$127]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$126]  |PARTITIONED|
+                      assign [$$118, $$122, $$126] <- [$$ol.getField("ol_amount"), $$ol.getField("ol_quantity"), $$ol.getField("ol_i_id")] project: [$$118, $$122, $$69, $$126]
                       -- ASSIGN  |PARTITIONED|
+                        unnest $$ol <- scan-collection($$129) project: [$$69, $$ol]
                         -- UNNEST  |PARTITIONED|
+                          assign [$$69, $$129] <- [$$o.getField("o_w_id"), $$o.getField("o_orderline")] project: [$$69, $$129]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$o])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                data-scan []<-[$$124, $$o] <- test.orders
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$127]  |PARTITIONED|
+                      select (and($$134, $$135))
                       -- STREAM_SELECT  |PARTITIONED|
+                        assign [$$135, $$134] <- [le($$121, 15), ge($$121, 1)]
                         -- ASSIGN  |PARTITIONED|
+                          assign [$$123, $$121, $$127] <- [$$i.getField("i_data"), $$i.getField("i_price"), $$i.getField("i_id")] project: [$$123, $$121, $$127]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$i])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.item)  |PARTITIONED|
+                                data-scan []<-[$$125, $$i] <- test.item
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q2.plan
index 1dd9319..3c1dbe6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q2.plan
@@ -1,147 +1,288 @@
+distribute result [$$240]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 100
     -- STREAM_LIMIT  |UNPARTITIONED|
+      assign [$$240] <- [{"su_suppkey": $$249, "su_name": $$281, "n_name": $$280, "i_id": $$247, "i_name": $$285, "su_address": $$286, "su_phone": $$287, "su_comment": $$288}] project: [$$240]
       -- ASSIGN  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$280(ASC), $$281(ASC), $$247(ASC) ]  |PARTITIONED|
+          limit 100
           -- STREAM_LIMIT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (topK: 100) (ASC, $$280) (ASC, $$281) (ASC, $$247)
               -- STABLE_SORT [topK: 100] [$$280(ASC), $$281(ASC), $$247(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$249, $$281, $$280, $$247, $$285, $$286, $$287, $$288])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (eq($$260, $$261))
                       -- HYBRID_HASH_JOIN [$$260][$$261]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$260]  |PARTITIONED|
+                          project ([$$249, $$281, $$280, $$247, $$285, $$286, $$287, $$288, $$260])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              join (eq($$267, $$268))
                               -- HYBRID_HASH_JOIN [$$267][$$268]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$267]  |PARTITIONED|
+                                  project ([$$249, $$281, $$247, $$285, $$286, $$287, $$288, $$267])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      join (eq($$273, $$249))
                                       -- HYBRID_HASH_JOIN [$$273][$$249]  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$273]  |PARTITIONED|
+                                          assign [$$273] <- [numeric-mod(numeric-multiply($$279, $$248), 10000)] project: [$$247, $$285, $$273]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$247, $$285, $$279, $$248])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                join (and(eq($$247, $$248), eq($$271, $$262)))
                                                 -- HYBRID_HASH_JOIN [$$247, $$262][$$248, $$271]  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$247, $$262]  |PARTITIONED|
+                                                    project ([$$247, $$285, $$262])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        join (eq($$247, $$s_i_id))
                                                         -- HYBRID_HASH_JOIN [$$s_i_id][$$247]  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- SORT_GROUP_BY[$$291]  |PARTITIONED|
-                                                                    {
+                                                            group by ([$$s_i_id := $$291]) decor ([]) {
+                                                                      aggregate [$$262] <- [agg-global-sql-min($$290)]
                                                                       -- AGGREGATE  |LOCAL|
+                                                                        nested tuple source
                                                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                    }
+                                                                   }
+                                                            -- SORT_GROUP_BY[$$291]  |PARTITIONED|
+                                                              exchange
                                                               -- HASH_PARTITION_EXCHANGE [$$291]  |PARTITIONED|
-                                                                -- SORT_GROUP_BY[$$245]  |PARTITIONED|
-                                                                        {
+                                                                group by ([$$291 := $$245]) decor ([]) {
+                                                                          aggregate [$$290] <- [agg-local-sql-min($$194)]
                                                                           -- AGGREGATE  |LOCAL|
+                                                                            nested tuple source
                                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                        }
+                                                                       }
+                                                                -- SORT_GROUP_BY[$$245]  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    project ([$$194, $$245])
                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        join (eq($$269, $$277))
                                                                         -- HYBRID_HASH_JOIN [$$269][$$277]  |PARTITIONED|
+                                                                          exchange
                                                                           -- HASH_PARTITION_EXCHANGE [$$269]  |PARTITIONED|
+                                                                            assign [$$269] <- [numeric-mod(numeric-multiply($$s1.getField("s_w_id"), $$245), 10000)] project: [$$194, $$245, $$269]
                                                                             -- ASSIGN  |PARTITIONED|
+                                                                              assign [$$245, $$194] <- [$$s1.getField("s_i_id"), $$s1.getField("s_quantity")]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  replicate
                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      project ([$$s1])
                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                          -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                                                          data-scan []<-[$$250, $$s1] <- test.stock
+                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              empty-tuple-source
                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                          exchange
                                                                           -- HASH_PARTITION_EXCHANGE [$$277]  |PARTITIONED|
+                                                                            project ([$$277])
                                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                join (eq($$265, $$276))
                                                                                 -- HYBRID_HASH_JOIN [$$265][$$276]  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- HASH_PARTITION_EXCHANGE [$$265]  |PARTITIONED|
+                                                                                    assign [$$277, $$265] <- [$$su1.getField("su_suppkey"), $$su1.getField("su_nationkey")] project: [$$277, $$265]
                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        replicate
                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            project ([$$su1])
                                                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                                                                                data-scan []<-[$$251, $$su1] <- test.supplier
+                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    empty-tuple-source
                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- HASH_PARTITION_EXCHANGE [$$276]  |PARTITIONED|
+                                                                                    project ([$$276])
                                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        join (eq($$263, $$264))
                                                                                         -- HYBRID_HASH_JOIN [$$263][$$264]  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- HASH_PARTITION_EXCHANGE [$$263]  |PARTITIONED|
+                                                                                            assign [$$276, $$263] <- [$$n1.getField("n_nationkey"), $$n1.getField("n_regionkey")] project: [$$276, $$263]
                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                replicate
                                                                                                 -- REPLICATE  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    project ([$$n1])
                                                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                        -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                                                                        data-scan []<-[$$252, $$n1] <- test.nation
+                                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                          exchange
                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                            empty-tuple-source
                                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            replicate
                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- HASH_PARTITION_EXCHANGE [$$264]  |PARTITIONED|
+                                                                                                select (and(ge($$259, "Europ"), lt($$259, "Euroq"))) project: [$$264]
                                                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                                                  assign [$$264, $$259] <- [$$r1.getField("r_regionkey"), $$r1.getField("r_name")] project: [$$264, $$259]
                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                    project ([$$r1])
                                                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                        -- DATASOURCE_SCAN (test.region)  |PARTITIONED|
+                                                                                                        data-scan []<-[$$253, $$r1] <- test.region
+                                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                          exchange
                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                            empty-tuple-source
                                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                          exchange
                                                           -- HASH_PARTITION_EXCHANGE [$$247]  |PARTITIONED|
+                                                            select (like($$i.getField("i_data"), "%b")) project: [$$247, $$285]
                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                              assign [$$285, $$247] <- [$$i.getField("i_name"), $$i.getField("i_id")]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                project ([$$i])
                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- DATASOURCE_SCAN (test.item)  |PARTITIONED|
+                                                                    data-scan []<-[$$254, $$i] <- test.item
+                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$248, $$271]  |PARTITIONED|
+                                                    assign [$$279, $$271, $$248] <- [$$s.getField("s_w_id"), $$s.getField("s_quantity"), $$s.getField("s_i_id")] project: [$$279, $$248, $$271]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      assign [$$s] <- [$$s1] project: [$$s]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          replicate
                                                           -- REPLICATE  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              project ([$$s1])
                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                                  data-scan []<-[$$250, $$s1] <- test.stock
+                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$249]  |PARTITIONED|
+                                          assign [$$288, $$287, $$286, $$281, $$267, $$249] <- [$$su.getField("su_comment"), $$su.getField("su_phone"), $$su.getField("su_address"), $$su.getField("su_name"), $$su.getField("su_nationkey"), $$su.getField("su_suppkey")] project: [$$249, $$281, $$286, $$287, $$288, $$267]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$su] <- [$$su1] project: [$$su]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    project ([$$su1])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                                        data-scan []<-[$$251, $$su1] <- test.supplier
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$268]  |PARTITIONED|
+                                  assign [$$280, $$260, $$268] <- [$$n.getField("n_name"), $$n.getField("n_regionkey"), $$n.getField("n_nationkey")] project: [$$280, $$260, $$268]
                                   -- ASSIGN  |PARTITIONED|
+                                    assign [$$n] <- [$$n1] project: [$$n]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$n1])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                data-scan []<-[$$252, $$n1] <- test.nation
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$261] <- [$$264] project: [$$261]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$264]  |PARTITIONED|
+                                  select (and(ge($$259, "Europ"), lt($$259, "Euroq"))) project: [$$264]
                                   -- STREAM_SELECT  |PARTITIONED|
+                                    assign [$$264, $$259] <- [$$r1.getField("r_regionkey"), $$r1.getField("r_name")] project: [$$264, $$259]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$r1])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.region)  |PARTITIONED|
+                                          data-scan []<-[$$253, $$r1] <- test.region
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q20.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q20.plan
index e451167..3eba9df 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q20.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q20.plan
@@ -1,99 +1,186 @@
+distribute result [$$170]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$170] <- [{"su_name": $$191, "su_address": $$193}] project: [$$170]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$191(ASC) ]  |PARTITIONED|
+        order (ASC, $$191)
         -- STABLE_SORT [$$191(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$191, $$193])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (eq($$186, $$187))
                 -- HYBRID_HASH_JOIN [$$186][$$187]  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$186]  |PARTITIONED|
+                    select ($$160) project: [$$191, $$193, $$186]
                     -- STREAM_SELECT  |PARTITIONED|
+                      project ([$$160, $$193, $$186, $$191])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- PRE_CLUSTERED_GROUP_BY[$$177]  |PARTITIONED|
-                                  {
+                          group by ([$$198 := $$177]) decor ([$$193; $$186; $$191]) {
+                                    aggregate [$$160] <- [non-empty-stream()]
                                     -- AGGREGATE  |LOCAL|
+                                      select (not(is-missing($$197)))
                                       -- STREAM_SELECT  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
+                                 }
+                          -- PRE_CLUSTERED_GROUP_BY[$$177]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$177)
                               -- STABLE_SORT [$$177(ASC)]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$177]  |PARTITIONED|
+                                  project ([$$191, $$193, $$186, $$197, $$177])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      left outer join (eq($$185, $$156))
                                       -- HYBRID_HASH_JOIN [$$185][$$156]  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$185]  |PARTITIONED|
+                                          assign [$$193, $$191, $$186, $$185] <- [$$su.getField("su_address"), $$su.getField("su_name"), $$su.getField("su_nationkey"), $$su.getField("su_suppkey")] project: [$$191, $$193, $$186, $$177, $$185]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                              data-scan []<-[$$177, $$su] <- test.supplier
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$156]  |PARTITIONED|
+                                          assign [$$197, $$156] <- [true, numeric-mod(numeric-multiply($$s_i_id, $$s_w_id), 10000)] project: [$$197, $$156]
                                           -- ASSIGN  |PARTITIONED|
+                                            select (gt(numeric-multiply(20, $$s_quantity), $$183)) project: [$$s_i_id, $$s_w_id]
                                             -- STREAM_SELECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- SORT_GROUP_BY[$$200, $$201, $$202]  |PARTITIONED|
-                                                        {
+                                                group by ([$$s_i_id := $$200; $$s_w_id := $$201; $$s_quantity := $$202]) decor ([]) {
+                                                          aggregate [$$183] <- [agg-global-sql-sum($$199)]
                                                           -- AGGREGATE  |LOCAL|
+                                                            nested tuple source
                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                        }
+                                                       }
+                                                -- SORT_GROUP_BY[$$200, $$201, $$202]  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$200, $$201, $$202]  |PARTITIONED|
-                                                    -- SORT_GROUP_BY[$$184, $$173, $$174]  |PARTITIONED|
-                                                            {
+                                                    group by ([$$200 := $$184; $$201 := $$173; $$202 := $$174]) decor ([]) {
+                                                              aggregate [$$199] <- [agg-local-sql-sum($$152)]
                                                               -- AGGREGATE  |LOCAL|
+                                                                nested tuple source
                                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                            }
+                                                           }
+                                                    -- SORT_GROUP_BY[$$184, $$173, $$174]  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        project ([$$152, $$184, $$173, $$174])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            join (eq($$188, $$184))
                                                             -- HYBRID_HASH_JOIN [$$184][$$188]  |PARTITIONED|
+                                                              exchange
                                                               -- HASH_PARTITION_EXCHANGE [$$184]  |PARTITIONED|
+                                                                select ($$134) project: [$$184, $$173, $$174]
                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                  project ([$$134, $$184, $$173, $$174])
                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- PRE_CLUSTERED_GROUP_BY[$$179]  |PARTITIONED|
-                                                                              {
+                                                                      group by ([$$196 := $$179]) decor ([$$184; $$173; $$174]) {
+                                                                                aggregate [$$134] <- [non-empty-stream()]
                                                                                 -- AGGREGATE  |LOCAL|
+                                                                                  select (not(is-missing($$195)))
                                                                                   -- STREAM_SELECT  |LOCAL|
+                                                                                    nested tuple source
                                                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                              }
+                                                                             }
+                                                                      -- PRE_CLUSTERED_GROUP_BY[$$179]  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          order (ASC, $$179)
                                                                           -- STABLE_SORT [$$179(ASC)]  |PARTITIONED|
+                                                                            exchange
                                                                             -- HASH_PARTITION_EXCHANGE [$$179]  |PARTITIONED|
+                                                                              project ([$$184, $$173, $$174, $$195, $$179])
                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  left outer join (eq($$184, $$130))
                                                                                   -- HYBRID_HASH_JOIN [$$184][$$130]  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- HASH_PARTITION_EXCHANGE [$$184]  |PARTITIONED|
+                                                                                      assign [$$174, $$173, $$184] <- [$$s.getField("s_quantity"), $$s.getField("s_w_id"), $$s.getField("s_i_id")] project: [$$184, $$173, $$174, $$179]
                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                          -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                                                          data-scan []<-[$$179, $$s] <- test.stock
+                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              empty-tuple-source
                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- HASH_PARTITION_EXCHANGE [$$130]  |PARTITIONED|
+                                                                                      assign [$$195] <- [true]
                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                        select (and(ge($$182, "co"), lt($$182, "cp"))) project: [$$130]
                                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                                          assign [$$130, $$182] <- [$$i.getField("i_id"), $$i.getField("i_data")] project: [$$130, $$182]
                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                            project ([$$i])
                                                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                -- DATASOURCE_SCAN (test.item)  |PARTITIONED|
+                                                                                                data-scan []<-[$$181, $$i] <- test.item
+                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    empty-tuple-source
                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                              exchange
                                                               -- HASH_PARTITION_EXCHANGE [$$188]  |PARTITIONED|
+                                                                select (and(ge($$175, "2016-01-01 12:00:00"), lt($$175, "2017-01-01 12:00:00"))) project: [$$152, $$188]
                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                  assign [$$152, $$188, $$175] <- [$$ol.getField("ol_quantity"), $$ol.getField("ol_i_id"), $$ol.getField("ol_delivery_d")] project: [$$152, $$188, $$175]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    unnest $$ol <- scan-collection($$189) project: [$$ol]
                                                                     -- UNNEST  |PARTITIONED|
+                                                                      assign [$$189] <- [$$o.getField("o_orderline")] project: [$$189]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        project ([$$o])
                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                                            data-scan []<-[$$180, $$o] <- test.orders
+                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                empty-tuple-source
                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$187]  |PARTITIONED|
+                    select (eq($$n.getField("n_name"), "Germany")) project: [$$187]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$187] <- [$$n.getField("n_nationkey")]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$n])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                            data-scan []<-[$$178, $$n] <- test.nation
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q21.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q21.plan
index 3ed88a3..bea8419 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q21.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q21.plan
@@ -1,102 +1,192 @@
+distribute result [$$339]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 100
     -- STREAM_LIMIT  |UNPARTITIONED|
+      project ([$$339])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$su_name(ASC) ]  |PARTITIONED|
+          assign [$$339] <- [{"su_name": $$su_name, "numwait": $$364}] project: [$$su_name, $$339]
           -- ASSIGN  |PARTITIONED|
+            limit 100
             -- STREAM_LIMIT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- SORT_GROUP_BY[$$399]  |PARTITIONED|
-                        {
+                group by ([$$su_name := $$399]) decor ([]) {
+                          aggregate [$$364] <- [agg-sql-sum($$398)]
                           -- AGGREGATE  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SORT_GROUP_BY[$$399]  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$399]  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$su_name]  |PARTITIONED|
-                            {
+                    group by ([$$399 := $$su_name]) decor ([]) {
+                              aggregate [$$398] <- [agg-sql-count(1)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$su_name]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        select (eq($$363, 0)) project: [$$su_name]
                         -- STREAM_SELECT  |PARTITIONED|
+                          project ([$$363, $$su_name])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- SORT_GROUP_BY[$$390, $$391, $$392, $$393, $$394, $$395, $$396, $$397]  |PARTITIONED|
-                                      {
+                              group by ([$$o_w_id := $$390; $$o_d_id := $$391; $$o_id := $$392; $$n_nationkey := $$393; $$su_suppkey := $$394; $$s_w_id := $$395; $$s_i_id := $$396; $$su_name := $$397]) decor ([]) {
+                                        aggregate [$$363] <- [agg-sql-sum($$389)]
                                         -- AGGREGATE  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- SORT_GROUP_BY[$$390, $$391, $$392, $$393, $$394, $$395, $$396, $$397]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$390, $$391, $$392, $$393, $$394, $$395, $$396, $$397]  |PARTITIONED|
-                                  -- SORT_GROUP_BY[$$352, $$378, $$377, $$354, $$355, $$351, $$350, $$379]  |PARTITIONED|
-                                          {
+                                  group by ([$$390 := $$352; $$391 := $$378; $$392 := $$377; $$393 := $$354; $$394 := $$355; $$395 := $$351; $$396 := $$350; $$397 := $$379]) decor ([]) {
+                                            aggregate [$$389] <- [agg-sql-count($$326)]
                                             -- AGGREGATE  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                          }
+                                         }
+                                  -- SORT_GROUP_BY[$$352, $$378, $$377, $$354, $$355, $$351, $$350, $$379]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$326, $$352, $$378, $$377, $$354, $$355, $$351, $$350, $$379])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          left outer join (and(eq($$383, $$378), gt($$384, $$353), eq($$381, $$377), eq($$382, $$352)))
                                           -- NESTED_LOOP  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$352, $$378, $$377, $$354, $$355, $$351, $$350, $$379, $$353])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  join (and(eq($$352, $$351), eq($$362, $$350)))
                                                   -- HYBRID_HASH_JOIN [$$351, $$350][$$352, $$362]  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$351, $$350]  |PARTITIONED|
+                                                      project ([$$354, $$355, $$351, $$350, $$379])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          join (eq($$366, $$355))
                                                           -- HYBRID_HASH_JOIN [$$355][$$366]  |PARTITIONED|
+                                                            exchange
                                                             -- HASH_PARTITION_EXCHANGE [$$355]  |PARTITIONED|
+                                                              project ([$$354, $$355, $$379])
                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  join (eq($$365, $$354))
                                                                   -- HYBRID_HASH_JOIN [$$354][$$365]  |PARTITIONED|
+                                                                    exchange
                                                                     -- HASH_PARTITION_EXCHANGE [$$354]  |PARTITIONED|
+                                                                      select (eq($$n.getField("n_name"), "Peru")) project: [$$354]
                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                        assign [$$354] <- [$$n.getField("n_nationkey")]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          project ([$$n])
                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                              -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                                              data-scan []<-[$$357, $$n] <- test.nation
+                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  empty-tuple-source
                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                    exchange
                                                                     -- HASH_PARTITION_EXCHANGE [$$365]  |PARTITIONED|
+                                                                      assign [$$379, $$355, $$365] <- [$$su.getField("su_name"), $$su.getField("su_suppkey"), $$su.getField("su_nationkey")] project: [$$355, $$379, $$365]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        project ([$$su])
                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                                                            data-scan []<-[$$358, $$su] <- test.supplier
+                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                empty-tuple-source
                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                            exchange
                                                             -- HASH_PARTITION_EXCHANGE [$$366]  |PARTITIONED|
+                                                              assign [$$366] <- [numeric-mod(numeric-multiply($$351, $$350), 10000)]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                assign [$$351, $$350] <- [$$s.getField("s_w_id"), $$s.getField("s_i_id")] project: [$$351, $$350]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  project ([$$s])
                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                                      data-scan []<-[$$359, $$s] <- test.stock
+                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$352, $$362]  |PARTITIONED|
+                                                      select (gt($$353, string(numeric-add(date($$349), duration: {P150D })))) project: [$$352, $$378, $$377, $$353, $$362]
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        assign [$$362, $$353] <- [$$ol1.getField("ol_i_id"), $$ol1.getField("ol_delivery_d")] project: [$$378, $$377, $$352, $$349, $$362, $$353]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          unnest $$ol1 <- scan-collection($$376) project: [$$378, $$377, $$352, $$349, $$ol1]
                                                           -- UNNEST  |PARTITIONED|
+                                                            select (and(le($$349, "2017-12-31 00:00:00"), ge($$349, "2017-12-01 00:00:00")))
                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                              assign [$$378, $$377, $$352, $$349, $$376] <- [$$o1.getField("o_d_id"), $$o1.getField("o_id"), $$o1.getField("o_w_id"), $$o1.getField("o_entry_d"), $$o1.getField("o_orderline")] project: [$$378, $$377, $$352, $$349, $$376]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  replicate
                                                                   -- REPLICATE  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      project ([$$o1])
                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                          -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                                          data-scan []<-[$$360, $$o1] <- test.orders
+                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              empty-tuple-source
                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              assign [$$326] <- [{"o_id": $$381, "o_w_id": $$382, "o_d_id": $$383, "ol_delivery_d": $$384}.getField("o_id")]
                                               -- ASSIGN  |PARTITIONED|
+                                                assign [$$384] <- [$$ol2.getField("ol_delivery_d")] project: [$$383, $$382, $$381, $$384]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  unnest $$ol2 <- scan-collection($$380) project: [$$383, $$382, $$381, $$ol2]
                                                   -- UNNEST  |PARTITIONED|
+                                                    select (and(le($$356, "2017-12-31 00:00:00"), ge($$356, "2017-12-01 00:00:00"))) project: [$$383, $$382, $$381, $$380]
                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                      assign [$$383, $$382, $$381, $$356, $$380] <- [$$o2.getField("o_d_id"), $$o2.getField("o_w_id"), $$o2.getField("o_id"), $$o2.getField("o_entry_d"), $$o2.getField("o_orderline")] project: [$$383, $$382, $$381, $$356, $$380]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        assign [$$o2] <- [$$o1] project: [$$o2]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            replicate
                                                             -- REPLICATE  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                project ([$$o1])
                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                                    data-scan []<-[$$360, $$o1] <- test.orders
+                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q22.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q22.plan
index baf25f4..c340af1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q22.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q22.plan
@@ -1,100 +1,188 @@
+distribute result [$$141]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$141] <- [{"country": $#1, "numcust": $$150, "totacctbal": $$151}] project: [$$141]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$#1(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$174]  |PARTITIONED|
-                {
+        group by ([$#1 := $$174]) decor ([]) {
+                  aggregate [$$150, $$151] <- [agg-sql-sum($$172), agg-global-sql-sum($$173)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$174]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$174]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$142]  |PARTITIONED|
-                    {
+            group by ([$$174 := $$142]) decor ([]) {
+                      aggregate [$$172, $$173] <- [agg-sql-count(1), agg-local-sql-sum($$152)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$142]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$142] <- [substring1($$163, 1, 1)] project: [$$152, $$142]
                 -- ASSIGN  |PARTITIONED|
+                  select (not(neq($$149, 0))) project: [$$163, $$152]
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$149, $$163, $$152])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$171]  |PARTITIONED|
-                                {
+                        group by ([$$168 := $$171]) decor ([$$163; $$152]) {
+                                  aggregate [$$149] <- [agg-sum($$170)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$171]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$171]  |PARTITIONED|
-                            -- PRE_CLUSTERED_GROUP_BY[$$166]  |PARTITIONED|
-                                    {
+                            group by ([$$171 := $$166]) decor ([$$163; $$152]) {
+                                      aggregate [$$170] <- [agg-count(1)]
                                       -- AGGREGATE  |LOCAL|
+                                        select (not(is-missing($$167)))
                                         -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- PRE_CLUSTERED_GROUP_BY[$$166]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$166)
                                 -- STABLE_SORT [$$166(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$152, $$163, $$167, $$166])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        left outer join (and(eq($$154, $$155), eq($$156, $$157), eq($$158, $$159)))
                                         -- HYBRID_HASH_JOIN [$$155, $$157, $$159][$$154, $$156, $$158]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$155, $$157, $$159]  |PARTITIONED|
+                                            running-aggregate [$$166] <- [create-query-uid()]
                                             -- RUNNING_AGGREGATE  |PARTITIONED|
+                                              project ([$$152, $$163, $$155, $$157, $$159])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  join (gt($$152, $$153))
                                                   -- NESTED_LOOP  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      project ([$$152, $$163, $$155, $$157, $$159])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          join (eq($$147, $$85))
                                                           -- HYBRID_HASH_JOIN [$$85][$$147]  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              assign [$$85, $$163, $$159, $$157, $$155, $$152] <- [substring1($$c.getField("c_phone"), 1, 1), $$c.getField("c_state"), $$c.getField("c_w_id"), $$c.getField("c_id"), $$c.getField("c_d_id"), $$c.getField("c_balance")] project: [$$152, $$163, $$155, $$157, $$159, $$85]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                assign [$$c] <- [$$c1] project: [$$c]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    replicate
                                                                     -- REPLICATE  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        project ([$$c1])
                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- DATASOURCE_SCAN (test.customer)  |PARTITIONED|
+                                                                            data-scan []<-[$$145, $$c1] <- test.customer
+                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                empty-tuple-source
                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              assign [$$147] <- [$$148] project: [$$147]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  replicate
                                                                   -- REPLICATE  |PARTITIONED|
+                                                                    exchange
                                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                      unnest $$148 <- scan-collection(array: [ "1", "2", "3", "4", "5", "6", "7" ])
                                                                       -- UNNEST  |UNPARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                    exchange
                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                      assign [$$153] <- [get-item($$104, 0)] project: [$$153]
                                                       -- ASSIGN  |UNPARTITIONED|
+                                                        aggregate [$$104] <- [listify($$169)]
                                                         -- AGGREGATE  |UNPARTITIONED|
+                                                          aggregate [$$169] <- [agg-global-sql-avg($$175)]
                                                           -- AGGREGATE  |UNPARTITIONED|
+                                                            exchange
                                                             -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                              aggregate [$$175] <- [agg-local-sql-avg($$161)]
                                                               -- AGGREGATE  |PARTITIONED|
+                                                                project ([$$161])
                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    join (eq($$148, $$93))
                                                                     -- HYBRID_HASH_JOIN [$$93][$$148]  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        assign [$$93] <- [substring1($$c1.getField("c_phone"), 1, 1)] project: [$$161, $$93]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          select (gt($$161, 0.0))
                                                                           -- STREAM_SELECT  |PARTITIONED|
+                                                                            assign [$$161] <- [$$c1.getField("c_balance")]
                                                                             -- ASSIGN  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                replicate
                                                                                 -- REPLICATE  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    project ([$$c1])
                                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                        -- DATASOURCE_SCAN (test.customer)  |PARTITIONED|
+                                                                                        data-scan []<-[$$145, $$c1] <- test.customer
+                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            empty-tuple-source
                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        replicate
                                                                         -- REPLICATE  |PARTITIONED|
+                                                                          exchange
                                                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                            unnest $$148 <- scan-collection(array: [ "1", "2", "3", "4", "5", "6", "7" ])
                                                                             -- UNNEST  |UNPARTITIONED|
+                                                                              empty-tuple-source
                                                                               -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$154, $$156, $$158]  |PARTITIONED|
+                                            assign [$$167] <- [true]
                                             -- ASSIGN  |PARTITIONED|
+                                              select (and(ge($$143, "2013-12-01 00:00:00"), le($$143, "2013-12-31 00:00:00"))) project: [$$158, $$156, $$154]
                                               -- STREAM_SELECT  |PARTITIONED|
+                                                assign [$$158, $$156, $$154, $$143] <- [$$o.getField("o_w_id"), $$o.getField("o_c_id"), $$o.getField("o_d_id"), $$o.getField("o_entry_d")] project: [$$158, $$156, $$154, $$143]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  project ([$$o])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                      data-scan []<-[$$146, $$o] <- test.orders
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q3.plan
index ce1376c..3291e30 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q3.plan
@@ -1,50 +1,94 @@
+distribute result [$$198]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$198] <- [{"o_id": $$o_id, "o_w_id": $$o_w_id, "o_d_id": $$o_d_id, "revenue": $$220, "o_entry_d": $$o_entry_d}] project: [$$198]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$220(DESC), $$o_entry_d(ASC) ]  |PARTITIONED|
+        order (DESC, $$220) (ASC, $$o_entry_d)
         -- STABLE_SORT [$$220(DESC), $$o_entry_d(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- SORT_GROUP_BY[$$226, $$227, $$228, $$229]  |PARTITIONED|
-                    {
+            group by ([$$o_id := $$226; $$o_w_id := $$227; $$o_d_id := $$228; $$o_entry_d := $$229]) decor ([]) {
+                      aggregate [$$220] <- [agg-global-sql-sum($$225)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$226, $$227, $$228, $$229]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$226, $$227, $$228, $$229]  |PARTITIONED|
-                -- SORT_GROUP_BY[$$221, $$204, $$205, $$206]  |PARTITIONED|
-                        {
+                group by ([$$226 := $$221; $$227 := $$204; $$228 := $$205; $$229 := $$206]) decor ([]) {
+                          aggregate [$$225] <- [agg-local-sql-sum($$195)]
                           -- AGGREGATE  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SORT_GROUP_BY[$$221, $$204, $$205, $$206]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$195, $$221, $$204, $$205, $$206])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (and(eq($$217, $$204), eq($$218, $$205), eq($$219, $$221)))
                         -- HYBRID_HASH_JOIN [$$204, $$205, $$221][$$217, $$218, $$219]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$204, $$205, $$221]  |PARTITIONED|
+                            assign [$$195] <- [$$ol.getField("ol_amount")] project: [$$195, $$221, $$204, $$205, $$206]
                             -- ASSIGN  |PARTITIONED|
+                              unnest $$ol <- scan-collection($$222) project: [$$221, $$206, $$205, $$204, $$ol]
                               -- UNNEST  |PARTITIONED|
+                                project ([$$222, $$221, $$206, $$205, $$204])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (and(eq($$213, $$214), eq($$215, $$204), eq($$216, $$205)))
                                     -- HYBRID_HASH_JOIN [$$214, $$204, $$205][$$213, $$215, $$216]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$214, $$204, $$205]  |PARTITIONED|
+                                        select (lt($$206, "2017-03-15 00:00:00.000000"))
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$222, $$221, $$214, $$206, $$205, $$204] <- [$$o.getField("o_orderline"), $$o.getField("o_id"), $$o.getField("o_c_id"), $$o.getField("o_entry_d"), $$o.getField("o_d_id"), $$o.getField("o_w_id")] project: [$$222, $$221, $$214, $$206, $$205, $$204]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$o])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                data-scan []<-[$$210, $$o] <- test.orders
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$213, $$215, $$216]  |PARTITIONED|
+                                        select (and(lt($$203, "B"), ge($$203, "A"))) project: [$$213, $$215, $$216]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$216, $$215, $$213, $$203] <- [$$c.getField("c_d_id"), $$c.getField("c_w_id"), $$c.getField("c_id"), $$c.getField("c_state")] project: [$$216, $$215, $$213, $$203]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$c])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.customer)  |PARTITIONED|
+                                                data-scan []<-[$$211, $$c] <- test.customer
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$217, $$218, $$219]  |PARTITIONED|
+                            assign [$$219, $$218, $$217] <- [$$no.getField("no_o_id"), $$no.getField("no_d_id"), $$no.getField("no_w_id")] project: [$$217, $$218, $$219]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$no])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.neworder)  |PARTITIONED|
+                                  data-scan []<-[$$212, $$no] <- test.neworder
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q4.plan
index f4c7d0d..352f6c4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q4.plan
@@ -1,33 +1,57 @@
+distribute result [$$72]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$72] <- [{"o_ol_cnt": $$o_ol_cnt, "order_COUNT": $$77}] project: [$$72]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$o_ol_cnt(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$82]  |PARTITIONED|
-                {
+        group by ([$$o_ol_cnt := $$82]) decor ([]) {
+                  aggregate [$$77] <- [agg-sql-sum($$81)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$82]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$82]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$73]  |PARTITIONED|
-                    {
+            group by ([$$82 := $$73]) decor ([]) {
+                      aggregate [$$81] <- [agg-sql-count(1)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$73]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (neq($$76, 0)) project: [$$73]
                 -- STREAM_SELECT  |PARTITIONED|
+                  project ([$$73, $$76])
                   -- STREAM_PROJECT  |PARTITIONED|
-                    -- SUBPLAN  |PARTITIONED|
-                            {
+                    subplan {
+                              aggregate [$$76] <- [agg-count(1)]
                               -- AGGREGATE  |LOCAL|
+                                select (ge($$79, string(numeric-add(date($$80), duration: {P7D }))))
                                 -- STREAM_SELECT  |LOCAL|
+                                  assign [$$79] <- [$$ol.getField("ol_delivery_d")]
                                   -- ASSIGN  |LOCAL|
+                                    unnest $$ol <- scan-collection($$78)
                                     -- UNNEST  |LOCAL|
+                                      nested tuple source
                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SUBPLAN  |PARTITIONED|
+                      select (and(lt($$80, "2015-10-01 00:00:00.000000"), ge($$80, "2015-07-01 00:00:00.000000")))
                       -- STREAM_SELECT  |PARTITIONED|
+                        assign [$$73, $$80, $$78] <- [$$o.getField("o_ol_cnt"), $$o.getField("o_entry_d"), $$o.getField("o_orderline")] project: [$$73, $$80, $$78]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$o])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                              data-scan []<-[$$75, $$o] <- test.orders
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q5.plan
index bf45fd7..4515add 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q5.plan
@@ -1,86 +1,166 @@
+distribute result [$$243]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$243] <- [{"n_name": $$n_name, "revenue": $#2}] project: [$$243]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$#2(DESC) ]  |PARTITIONED|
+        order (DESC, $#2)
         -- STABLE_SORT [$#2(DESC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            assign [$#2] <- [round($$270, 2)] project: [$$n_name, $#2]
             -- ASSIGN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- SORT_GROUP_BY[$$291]  |PARTITIONED|
-                        {
+                group by ([$$n_name := $$291]) decor ([]) {
+                          aggregate [$$270] <- [agg-global-sql-sum($$290)]
                           -- AGGREGATE  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SORT_GROUP_BY[$$291]  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$291]  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$275]  |PARTITIONED|
-                            {
+                    group by ([$$291 := $$275]) decor ([]) {
+                              aggregate [$$290] <- [agg-local-sql-sum($$280)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$275]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$280, $$275])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (and(eq($$266, $$274), eq($$268, $$269)))
                             -- HYBRID_HASH_JOIN [$$274, $$268][$$266, $$269]  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$274, $$268]  |PARTITIONED|
+                                assign [$$268] <- [numeric-mod(numeric-multiply($$245, $$246), 10000)] project: [$$280, $$275, $$274, $$268]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$245, $$246, $$280, $$275, $$274])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      join (and(eq($$254, $$245), eq($$281, $$246)))
                                       -- HYBRID_HASH_JOIN [$$245, $$246][$$254, $$281]  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$245, $$246]  |PARTITIONED|
+                                          assign [$$246, $$245] <- [$$s.getField("s_i_id"), $$s.getField("s_w_id")] project: [$$245, $$246]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$s])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                data-scan []<-[$$247, $$s] <- test.stock
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$254, $$281]  |PARTITIONED|
+                                          project ([$$280, $$275, $$274, $$254, $$281])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              join (and(eq($$276, $$260), eq($$277, $$254), eq($$278, $$263)))
                                               -- HYBRID_HASH_JOIN [$$260, $$254, $$263][$$276, $$277, $$278]  |PARTITIONED|
+                                                exchange
                                                 -- HASH_PARTITION_EXCHANGE [$$260, $$254, $$263]  |PARTITIONED|
+                                                  assign [$$281, $$280] <- [$$ol.getField("ol_i_id"), $$ol.getField("ol_amount")] project: [$$280, $$254, $$281, $$260, $$263]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    unnest $$ol <- scan-collection($$271) project: [$$263, $$260, $$254, $$ol]
                                                     -- UNNEST  |PARTITIONED|
+                                                      select (and(ge($$253, "2016-01-01 00:00:00.000000"), lt($$253, "2017-01-01 00:00:00.000000"))) project: [$$263, $$260, $$254, $$271]
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        assign [$$263, $$260, $$254, $$253, $$271] <- [$$o.getField("o_d_id"), $$o.getField("o_c_id"), $$o.getField("o_w_id"), $$o.getField("o_entry_d"), $$o.getField("o_orderline")] project: [$$263, $$260, $$254, $$253, $$271]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          project ([$$o])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                              data-scan []<-[$$248, $$o] <- test.orders
+                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                exchange
                                                 -- HASH_PARTITION_EXCHANGE [$$276, $$277, $$278]  |PARTITIONED|
+                                                  project ([$$275, $$274, $$276, $$277, $$278])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      join (eq($$258, $$274))
                                                       -- HYBRID_HASH_JOIN [$$258][$$274]  |PARTITIONED|
+                                                        exchange
                                                         -- HASH_PARTITION_EXCHANGE [$$258]  |PARTITIONED|
+                                                          assign [$$258, $$278, $$277, $$276] <- [get-item(string-to-codepoint($$c.getField("c_state")), 0), $$c.getField("c_d_id"), $$c.getField("c_w_id"), $$c.getField("c_id")] project: [$$276, $$277, $$278, $$258]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            project ([$$c])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.customer)  |PARTITIONED|
+                                                                data-scan []<-[$$249, $$c] <- test.customer
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                        exchange
                                                         -- HASH_PARTITION_EXCHANGE [$$274]  |PARTITIONED|
+                                                          project ([$$275, $$274])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              join (eq($$256, $$257))
                                                               -- HYBRID_HASH_JOIN [$$256][$$257]  |PARTITIONED|
+                                                                exchange
                                                                 -- HASH_PARTITION_EXCHANGE [$$256]  |PARTITIONED|
+                                                                  assign [$$275, $$274, $$256] <- [$$n.getField("n_name"), $$n.getField("n_nationkey"), $$n.getField("n_regionkey")] project: [$$275, $$274, $$256]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    project ([$$n])
                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                                        data-scan []<-[$$250, $$n] <- test.nation
+                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                exchange
                                                                 -- HASH_PARTITION_EXCHANGE [$$257]  |PARTITIONED|
+                                                                  select (eq($$r.getField("r_name"), "Asia")) project: [$$257]
                                                                   -- STREAM_SELECT  |PARTITIONED|
+                                                                    assign [$$257] <- [$$r.getField("r_regionkey")]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      project ([$$r])
                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                          -- DATASOURCE_SCAN (test.region)  |PARTITIONED|
+                                                                          data-scan []<-[$$251, $$r] <- test.region
+                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              empty-tuple-source
                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$266, $$269]  |PARTITIONED|
+                                assign [$$269, $$266] <- [$$su.getField("su_suppkey"), $$su.getField("su_nationkey")] project: [$$266, $$269]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$su])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                      data-scan []<-[$$252, $$su] <- test.supplier
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q6.plan
index e8e1b49..3a2f704 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q6.plan
@@ -1,15 +1,30 @@
+distribute result [$$54]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$54] <- [{"revenue": $$57}] project: [$$54]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$57] <- [agg-global-sql-sum($$61)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$61] <- [agg-local-sql-sum($$59)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$59, 600), lt($$55, "2017-01-01 00:00:00.000000"), ge($$55, "2016-01-01 00:00:00.000000"))) project: [$$59]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$55, $$59] <- [$$ol.getField("ol_delivery_d"), $$ol.getField("ol_amount")] project: [$$55, $$59]
               -- ASSIGN  |PARTITIONED|
+                unnest $$ol <- scan-collection($$58) project: [$$ol]
                 -- UNNEST  |PARTITIONED|
+                  assign [$$58] <- [$$o.getField("o_orderline")] project: [$$58]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$o])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                        data-scan []<-[$$56, $$o] <- test.orders
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q7.plan
index 5949891..044395e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q7.plan
@@ -1,89 +1,172 @@
+distribute result [$$271]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$271] <- [{"supp_nation": $$su_nationkey, "cust_nation": $#1, "l_year": $#2, "revenue": round($$301, 2)}] project: [$$271]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$su_nationkey(ASC), $#1(ASC), $#2(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$325, $$326, $$327]  |PARTITIONED|
-                {
+        group by ([$$su_nationkey := $$325; $#1 := $$326; $#2 := $$327]) decor ([]) {
+                  aggregate [$$301] <- [agg-global-sql-sum($$324)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$325, $$326, $$327]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$325, $$326, $$327]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$277, $$273, $$274]  |PARTITIONED|
-                    {
+            group by ([$$325 := $$277; $$326 := $$273; $$327 := $$274]) decor ([]) {
+                      aggregate [$$324] <- [agg-local-sql-sum($$313)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$277, $$273, $$274]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$274, $$273] <- [get-year(date($$309)), substring1($$285, 1, 1)] project: [$$313, $$277, $$273, $$274]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$313, $$309, $$285, $$277])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (and(eq($$277, $$303), eq($$299, $$300)))
                       -- HYBRID_HASH_JOIN [$$303, $$299][$$277, $$300]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$303, $$299]  |PARTITIONED|
+                          assign [$$299] <- [numeric-mod(numeric-multiply($$275, $$276), 10000)] project: [$$313, $$309, $$285, $$303, $$299]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$275, $$276, $$313, $$309, $$285, $$303])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (and(eq($$310, $$275), eq($$311, $$276)))
                                 -- HYBRID_HASH_JOIN [$$275, $$276][$$310, $$311]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$275, $$276]  |PARTITIONED|
+                                    assign [$$276, $$275] <- [$$s.getField("s_i_id"), $$s.getField("s_w_id")] project: [$$275, $$276]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$s])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                          data-scan []<-[$$278, $$s] <- test.stock
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$310, $$311]  |PARTITIONED|
+                                    project ([$$313, $$309, $$285, $$303, $$310, $$311])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        join (and(eq($$305, $$291), eq($$306, $$293), eq($$307, $$295)))
                                         -- HYBRID_HASH_JOIN [$$291, $$293, $$295][$$305, $$306, $$307]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$291, $$293, $$295]  |PARTITIONED|
+                                            select (and(ge($$284, "2017-01-01 00:00:00.000000"), le($$284, "2018-12-31 00:00:00.000000"))) project: [$$313, $$309, $$310, $$311, $$291, $$293, $$295]
                                             -- STREAM_SELECT  |PARTITIONED|
+                                              assign [$$313, $$311, $$310, $$284] <- [$$ol.getField("ol_amount"), $$ol.getField("ol_i_id"), $$ol.getField("ol_supply_w_id"), $$ol.getField("ol_delivery_d")] project: [$$309, $$295, $$293, $$291, $$313, $$311, $$310, $$284]
                                               -- ASSIGN  |PARTITIONED|
+                                                unnest $$ol <- scan-collection($$302) project: [$$309, $$295, $$293, $$291, $$ol]
                                                 -- UNNEST  |PARTITIONED|
+                                                  assign [$$309, $$295, $$293, $$291, $$302] <- [$$o.getField("o_entry_d"), $$o.getField("o_d_id"), $$o.getField("o_w_id"), $$o.getField("o_c_id"), $$o.getField("o_orderline")] project: [$$309, $$295, $$293, $$291, $$302]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    project ([$$o])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                        data-scan []<-[$$279, $$o] <- test.orders
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$305, $$306, $$307]  |PARTITIONED|
+                                            project ([$$285, $$303, $$305, $$306, $$307])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                join (eq($$288, $$304))
                                                 -- HYBRID_HASH_JOIN [$$288][$$304]  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$288]  |PARTITIONED|
+                                                    assign [$$288] <- [get-item(string-to-codepoint($$285), 0)]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      assign [$$307, $$306, $$305, $$285] <- [$$c.getField("c_d_id"), $$c.getField("c_w_id"), $$c.getField("c_id"), $$c.getField("c_state")] project: [$$307, $$306, $$305, $$285]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$c])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.customer)  |PARTITIONED|
+                                                            data-scan []<-[$$280, $$c] <- test.customer
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$304]  |PARTITIONED|
+                                                    project ([$$303, $$304])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        join (or(and(eq($$286, "Germany"), eq($$287, "Cambodia")), and(eq($$286, "Cambodia"), eq($$287, "Germany"))))
                                                         -- NESTED_LOOP  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            assign [$$303, $$286] <- [$$304, $$287] project: [$$303, $$286]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                replicate
                                                                 -- REPLICATE  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    assign [$$304, $$287] <- [$$n2.getField("n_nationkey"), $$n2.getField("n_name")] project: [$$304, $$287]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      project ([$$n2])
                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                          -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                                          data-scan []<-[$$282, $$n2] <- test.nation
+                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              empty-tuple-source
                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                          exchange
                                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                            replicate
                                                             -- REPLICATE  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                assign [$$304, $$287] <- [$$n2.getField("n_nationkey"), $$n2.getField("n_name")] project: [$$304, $$287]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  project ([$$n2])
                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                                      data-scan []<-[$$282, $$n2] <- test.nation
+                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$277, $$300]  |PARTITIONED|
+                          assign [$$300, $$277] <- [$$su.getField("su_suppkey"), $$su.getField("su_nationkey")] project: [$$277, $$300]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$su])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                data-scan []<-[$$283, $$su] <- test.supplier
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q8.plan
index 0087b4b..a1fa8ef 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q8.plan
@@ -1,114 +1,222 @@
+distribute result [$$293]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$293] <- [{"l_year": $#1, "mkt_share": round(numeric-divide($$322, $$323), 2)}] project: [$$293]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$#1(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$349]  |PARTITIONED|
-                {
+        group by ([$#1 := $$349]) decor ([]) {
+                  aggregate [$$322, $$323] <- [agg-global-sql-sum($$347), agg-global-sql-sum($$348)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$349]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$349]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$294]  |PARTITIONED|
-                    {
+            group by ([$$349 := $$294]) decor ([]) {
+                      aggregate [$$347, $$348] <- [agg-local-sql-sum(switch-case(true, eq($$342, "Germany"), $$335, 0)), agg-local-sql-sum($$335)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$294]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$294] <- [get-year(date($$305))] project: [$$342, $$335, $$294]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$335, $$305, $$342])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (eq($$320, $$341))
                       -- HYBRID_HASH_JOIN [$$320][$$341]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$320]  |PARTITIONED|
+                          assign [$$320] <- [numeric-mod(numeric-multiply($$295, $$296), 10000)] project: [$$335, $$305, $$320]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$295, $$296, $$335, $$305])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (and(eq($$306, $$296), eq($$336, $$295)))
                                 -- HYBRID_HASH_JOIN [$$296, $$295][$$306, $$336]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$296, $$295]  |PARTITIONED|
+                                    assign [$$296, $$295] <- [$$s.getField("s_i_id"), $$s.getField("s_w_id")] project: [$$295, $$296]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$s])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                          data-scan []<-[$$297, $$s] <- test.stock
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$306, $$336]  |PARTITIONED|
+                                    project ([$$335, $$305, $$306, $$336])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        join (and(eq($$333, $$313), eq($$334, $$315), eq($$332, $$317)))
                                         -- HYBRID_HASH_JOIN [$$313, $$315, $$317][$$333, $$334, $$332]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$313, $$315, $$317]  |PARTITIONED|
+                                            project ([$$335, $$305, $$306, $$336, $$313, $$315, $$317])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                join (eq($$324, $$306))
                                                 -- HYBRID_HASH_JOIN [$$306][$$324]  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$306]  |PARTITIONED|
+                                                    select (lt($$306, 1000))
                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                      assign [$$336, $$335, $$306] <- [$$ol.getField("ol_supply_w_id"), $$ol.getField("ol_amount"), $$ol.getField("ol_i_id")] project: [$$317, $$315, $$313, $$305, $$336, $$335, $$306]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        unnest $$ol <- scan-collection($$327) project: [$$317, $$315, $$313, $$305, $$ol]
                                                         -- UNNEST  |PARTITIONED|
+                                                          select (and(le($$305, "2018-12-31 00:00:00.000000"), ge($$305, "2017-01-01 00:00:00.000000")))
                                                           -- STREAM_SELECT  |PARTITIONED|
+                                                            assign [$$317, $$315, $$313, $$305, $$327] <- [$$o.getField("o_c_id"), $$o.getField("o_d_id"), $$o.getField("o_w_id"), $$o.getField("o_entry_d"), $$o.getField("o_orderline")] project: [$$317, $$315, $$313, $$305, $$327]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              project ([$$o])
                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                                  data-scan []<-[$$298, $$o] <- test.orders
+                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$324]  |PARTITIONED|
+                                                    select (like($$i.getField("i_data"), "%b")) project: [$$324]
                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                      assign [$$324] <- [$$i.getField("i_id")]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$i])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.item)  |PARTITIONED|
+                                                            data-scan []<-[$$299, $$i] <- test.item
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$333, $$334, $$332]  |PARTITIONED|
+                                            project ([$$333, $$334, $$332])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                join (eq($$331, $$311))
                                                 -- HYBRID_HASH_JOIN [$$311][$$331]  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$311]  |PARTITIONED|
+                                                    assign [$$311, $$334, $$333, $$332] <- [get-item(string-to-codepoint($$c.getField("c_state")), 0), $$c.getField("c_d_id"), $$c.getField("c_w_id"), $$c.getField("c_id")] project: [$$333, $$334, $$332, $$311]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$c])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.customer)  |PARTITIONED|
+                                                          data-scan []<-[$$300, $$c] <- test.customer
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$331]  |PARTITIONED|
+                                                    project ([$$331])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        join (eq($$308, $$309))
                                                         -- HYBRID_HASH_JOIN [$$308][$$309]  |PARTITIONED|
+                                                          exchange
                                                           -- HASH_PARTITION_EXCHANGE [$$308]  |PARTITIONED|
+                                                            assign [$$331, $$308] <- [$$n1.getField("n_nationkey"), $$n1.getField("n_regionkey")] project: [$$331, $$308]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                replicate
                                                                 -- REPLICATE  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    project ([$$n1])
                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                                        data-scan []<-[$$301, $$n1] <- test.nation
+                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                          exchange
                                                           -- HASH_PARTITION_EXCHANGE [$$309]  |PARTITIONED|
+                                                            select (eq($$r.getField("r_name"), "Europe")) project: [$$309]
                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                              assign [$$309] <- [$$r.getField("r_regionkey")]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                project ([$$r])
                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- DATASOURCE_SCAN (test.region)  |PARTITIONED|
+                                                                    data-scan []<-[$$302, $$r] <- test.region
+                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$341]  |PARTITIONED|
+                          project ([$$342, $$341])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              join (eq($$325, $$326))
                               -- HYBRID_HASH_JOIN [$$325][$$326]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$325]  |PARTITIONED|
+                                  assign [$$341, $$325] <- [$$su.getField("su_suppkey"), $$su.getField("su_nationkey")] project: [$$341, $$325]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$su])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                        data-scan []<-[$$303, $$su] <- test.supplier
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$326]  |PARTITIONED|
+                                  assign [$$342, $$326] <- [$$n2.getField("n_name"), $$n2.getField("n_nationkey")] project: [$$342, $$326]
                                   -- ASSIGN  |PARTITIONED|
+                                    assign [$$n2] <- [$$n1] project: [$$n2]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$n1])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                data-scan []<-[$$301, $$n1] <- test.nation
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q9.plan
index 5fd9860..cbc4728 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q9.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/ch2/ch2_q9.plan
@@ -1,71 +1,136 @@
+distribute result [$$196]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$196] <- [{"n_name": $$n_name, "l_year": $#1, "SUM_profit": round($$212, 2)}] project: [$$196]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$n_name(ASC), $#1(DESC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$229, $$230]  |PARTITIONED|
-                {
+        group by ([$$n_name := $$229; $#1 := $$230]) decor ([]) {
+                  aggregate [$$212] <- [agg-global-sql-sum($$228)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$229, $$230]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$229, $$230]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$225, $$198]  |PARTITIONED|
-                    {
+            group by ([$$229 := $$225; $$230 := $$198]) decor ([]) {
+                      aggregate [$$228] <- [agg-local-sql-sum($$218)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$225, $$198]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$198] <- [get-year(date($$219))] project: [$$218, $$225, $$198]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$218, $$219, $$225])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (eq($$210, $$224))
                       -- HYBRID_HASH_JOIN [$$210][$$224]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$210]  |PARTITIONED|
+                          assign [$$210] <- [numeric-mod(numeric-multiply($$199, $$200), 10000)] project: [$$218, $$219, $$210]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$199, $$200, $$218, $$219])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (and(eq($$206, $$200), eq($$217, $$199)))
                                 -- HYBRID_HASH_JOIN [$$200, $$199][$$206, $$217]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$200]  |PARTITIONED|
+                                    assign [$$200, $$199] <- [$$s.getField("s_i_id"), $$s.getField("s_w_id")] project: [$$199, $$200]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$s])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                          data-scan []<-[$$201, $$s] <- test.stock
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$218, $$219, $$206, $$217])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        join (eq($$206, $$207))
                                         -- HYBRID_HASH_JOIN [$$206][$$207]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$206]  |PARTITIONED|
+                                            assign [$$218, $$217, $$206] <- [$$ol.getField("ol_amount"), $$ol.getField("ol_supply_w_id"), $$ol.getField("ol_i_id")] project: [$$218, $$219, $$206, $$217]
                                             -- ASSIGN  |PARTITIONED|
+                                              unnest $$ol <- scan-collection($$215) project: [$$219, $$ol]
                                               -- UNNEST  |PARTITIONED|
+                                                assign [$$219, $$215] <- [$$o.getField("o_entry_d"), $$o.getField("o_orderline")] project: [$$219, $$215]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  project ([$$o])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                      data-scan []<-[$$202, $$o] <- test.orders
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$207]  |PARTITIONED|
+                                            select (like($$i.getField("i_data"), "%bb")) project: [$$207]
                                             -- STREAM_SELECT  |PARTITIONED|
+                                              assign [$$207] <- [$$i.getField("i_id")]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$i])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (test.item)  |PARTITIONED|
+                                                    data-scan []<-[$$203, $$i] <- test.item
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$224]  |PARTITIONED|
+                          project ([$$225, $$224])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              join (eq($$213, $$214))
                               -- HYBRID_HASH_JOIN [$$213][$$214]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$213]  |PARTITIONED|
+                                  assign [$$224, $$213] <- [$$su.getField("su_suppkey"), $$su.getField("su_nationkey")] project: [$$224, $$213]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$su])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                        data-scan []<-[$$204, $$su] <- test.supplier
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$214]  |PARTITIONED|
+                                  assign [$$225, $$214] <- [$$n.getField("n_name"), $$n.getField("n_nationkey")] project: [$$225, $$214]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$n])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                        data-scan []<-[$$205, $$n] <- test.nation
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/collocated.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/collocated.plan
index 8617f74..b2c4781 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/collocated.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/collocated.plan
@@ -1,18 +1,36 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"user_name": $$36, "visitor_name": $$37}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      project ([$$36, $$37])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$32, $$33))
           -- HYBRID_HASH_JOIN [$$32][$$33]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
+              assign [$$36] <- [$$user.getField(1)] project: [$$36, $$32]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (colocated.Users)  |PARTITIONED|
+                  data-scan []<-[$$32, $$user] <- colocated.Users
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$33]  |PARTITIONED|
+              assign [$$37] <- [$$visitor.getField(1)] project: [$$37, $$33]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (colocated.Visitors)  |PARTITIONED|
+                  data-scan []<-[$$33, $$visitor] <- colocated.Visitors
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/column-pushdown/meta.001.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/column-pushdown/meta.001.plan
index d53d82a..7250b17 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/column-pushdown/meta.001.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/column-pushdown/meta.001.plan
@@ -1,107 +1,208 @@
+distribute result [$$176]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$176] <- [{"s_i_id": $$s_i_id, "ordercount": $$194}] project: [$$176]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$194(DESC) ]  |PARTITIONED|
+        order (DESC, $$194)
         -- STABLE_SORT [$$194(DESC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$s_i_id, $$194])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (gt($$193, $$208))
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$223]  |PARTITIONED|
-                            {
+                    group by ([$$s_i_id := $$223]) decor ([]) {
+                              aggregate [$$193, $$194] <- [agg-global-sql-sum($$221), agg-global-sql-sum($$222)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$223]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$223]  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$178]  |PARTITIONED|
-                                {
+                        group by ([$$223 := $$178]) decor ([]) {
+                                  aggregate [$$221, $$222] <- [agg-local-sql-sum($$142), agg-local-sql-sum($$142)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$178]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$142, $$178])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$191, $$192))
                                 -- HYBRID_HASH_JOIN [$$192][$$191]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$192]  |PARTITIONED|
+                                    project ([$$192])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        join (eq($$206, $$207))
                                         -- HYBRID_HASH_JOIN [$$207][$$206]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$207] <- [$$212] project: [$$207]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$212]  |PARTITIONED|
+                                                    select (eq($$197.getField("n_name"), "Germany")) project: [$$212]
                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                      assign [$$212] <- [$$197.getField("n_nationkey")]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$197])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                            data-scan []<-[$$204, $$197, $$205] <- test.nation project ({n_nationkey:any,n_name:any}) project-meta ({})
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$192, $$206] <- [$$210, $$211] project: [$$192, $$206]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$211]  |PARTITIONED|
+                                                    assign [$$210, $$211] <- [$$198.getField("su_suppkey"), $$198.getField("su_nationkey")] project: [$$210, $$211]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$198])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                                          data-scan []<-[$$202, $$198, $$203] <- test.supplier project ({su_suppkey:any,su_nationkey:any}) project-meta ({})
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$191]  |PARTITIONED|
+                                    assign [$$191] <- [numeric-mod(numeric-multiply($$s.getField("s_w_id"), $$178), 10000)] project: [$$142, $$178, $$191]
                                     -- ASSIGN  |PARTITIONED|
+                                      assign [$$178, $$142] <- [$$s.getField("s_i_id"), $$s.getField("s_order_cnt")]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$s])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                  data-scan []<-[$$183, $$s, $$184] <- test.stock project ({s_w_id:any,s_i_id:any,s_order_cnt:any}) project-meta ({})
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    assign [$$208] <- [get-item($$167, 0)] project: [$$208]
                     -- ASSIGN  |UNPARTITIONED|
+                      aggregate [$$167] <- [listify($$166)]
                       -- AGGREGATE  |UNPARTITIONED|
+                        assign [$$166] <- [numeric-multiply($$220, 5.0E-5)] project: [$$166]
                         -- ASSIGN  |UNPARTITIONED|
+                          aggregate [$$220] <- [agg-global-sql-sum($$224)]
                           -- AGGREGATE  |UNPARTITIONED|
+                            exchange
                             -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                              aggregate [$$224] <- [agg-local-sql-sum($$163)]
                               -- AGGREGATE  |PARTITIONED|
+                                project ([$$163])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (eq($$209, $$210))
                                     -- HYBRID_HASH_JOIN [$$210][$$209]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$210]  |PARTITIONED|
+                                        project ([$$210])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            join (eq($$211, $$212))
                                             -- HYBRID_HASH_JOIN [$$212][$$211]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$212]  |PARTITIONED|
+                                                    select (eq($$197.getField("n_name"), "Germany")) project: [$$212]
                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                      assign [$$212] <- [$$197.getField("n_nationkey")]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$197])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                            data-scan []<-[$$204, $$197, $$205] <- test.nation project ({n_nationkey:any,n_name:any}) project-meta ({})
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$211]  |PARTITIONED|
+                                                    assign [$$210, $$211] <- [$$198.getField("su_suppkey"), $$198.getField("su_nationkey")] project: [$$210, $$211]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$198])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                                          data-scan []<-[$$202, $$198, $$203] <- test.supplier project ({su_suppkey:any,su_nationkey:any}) project-meta ({})
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$209]  |PARTITIONED|
+                                        assign [$$209, $$163] <- [numeric-mod(numeric-multiply($$199.getField("s_w_id"), $$199.getField("s_i_id")), 10000), $$199.getField("s_order_cnt")] project: [$$163, $$209]
                                         -- ASSIGN  |PARTITIONED|
+                                          assign [$$199] <- [$$s] project: [$$199]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              replicate
                                               -- REPLICATE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  project ([$$s])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                      data-scan []<-[$$183, $$s, $$184] <- test.stock project ({s_w_id:any,s_i_id:any,s_order_cnt:any}) project-meta ({})
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/common-expr-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/common-expr-01.plan
index 44453cd..9ea6aaf 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/common-expr-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/common-expr-01.plan
@@ -1,61 +1,113 @@
+distribute result [$$176]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$176] <- [{"c11": $$c11, "c3": $$c3, "$1": $$184}] project: [$$176]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- SORT_GROUP_BY[$$194, $$195]  |PARTITIONED|
-                {
+        group by ([$$c3 := $$194; $$c11 := $$195]) decor ([]) {
+                  aggregate [$$184] <- [agg-global-sql-sum($$193)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$194, $$195]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$194, $$195]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$177, $$178]  |PARTITIONED|
-                    {
+            group by ([$$194 := $$177; $$195 := $$178]) decor ([]) {
+                      aggregate [$$193] <- [agg-local-sql-sum($$174)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$177, $$178]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$178] <- [get-hour(duration-from-interval(interval(parse-datetime(print-datetime(current-datetime(), "YYYY-MM-DDThh:mm:ss"), "YYYY-MM-DDThh:mm:ss"), parse-datetime($$183, "YYYY-MM-DDThh:mm:ss"))))] project: [$$174, $$177, $$178]
                 -- ASSIGN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true)
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$177, $$174] <- [get-month(print-datetime(parse-datetime($$179, "YYYY-MM-DDThh:mm:ss"), "YYYY-MM-DDThh:mm:ss")), switch-case(true, contains($$180, "x"), 1, 0)] project: [$$174, $$177]
                         -- ASSIGN  |PARTITIONED|
+                          select ($$164) project: [$$179, $$180]
                           -- STREAM_SELECT  |PARTITIONED|
+                            project ([$$164, $$179, $$180])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- PRE_CLUSTERED_GROUP_BY[$$181]  |PARTITIONED|
-                                        {
+                                group by ([$$191 := $$181]) decor ([$$179; $$180]) {
+                                          aggregate [$$164] <- [empty-stream()]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$190)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- PRE_CLUSTERED_GROUP_BY[$$181]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$181)
                                     -- STABLE_SORT [$$181(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$181]  |PARTITIONED|
+                                        project ([$$179, $$180, $$190, $$181])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            left outer join (not(if-missing-or-null(neq($$180, $#6), false)))
                                             -- NESTED_LOOP  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                select (le(get-day(duration-from-interval(interval(parse-datetime(print-datetime(current-datetime(), "YYYY-MM-DDThh:mm:ss"), "YYYY-MM-DDThh:mm:ss"), parse-datetime($$179, "YYYY-MM-DDThh:mm:ss")))), 30))
                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                  assign [$$180, $$179] <- [$$t1.getField("c2"), $$t1.getField("c1")] project: [$$181, $$180, $$179]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+                                                          data-scan []<-[$$181, $$t1] <- test.t1
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              exchange
                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                assign [$$190] <- [true]
                                                 -- ASSIGN  |UNPARTITIONED|
+                                                  unnest $#6 <- scan-collection(array: [ "a", "b", "c", "d" ])
                                                   -- UNNEST  |UNPARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        aggregate [$$183] <- [agg-global-sql-max($$196)]
                         -- AGGREGATE  |UNPARTITIONED|
+                          exchange
                           -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                            aggregate [$$196] <- [agg-local-sql-max($$148)]
                             -- AGGREGATE  |PARTITIONED|
+                              assign [$$148] <- [print-datetime(parse-datetime($$t1.getField("c5"), "YYYY-MM-DDThh:mm:ss"), "YYYY-MM-DDThh:mm:ss")] project: [$$148]
                               -- ASSIGN  |PARTITIONED|
+                                assign [$$182, $$t1] <- [$$181, $$t1] project: [$$t1]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+                                        data-scan []<-[$$181, $$t1] <- test.t1
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/composite-key/composite-prefix-low-high.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/composite-key/composite-prefix-low-high.plan
index edf4154..3779d39 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/composite-key/composite-prefix-low-high.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/composite-key/composite-prefix-low-high.plan
@@ -1,10 +1,20 @@
+distribute result [$$22]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$22] <- [{"x": $$26, "y": $$27, "z": $$Points.getField(2)}] project: [$$22]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$26(ASC), $$27(ASC) ]  |PARTITIONED|
+        order (ASC, $$26) (ASC, $$27)
         -- STABLE_SORT [$$26(ASC), $$27(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.Points.Points)  |PARTITIONED|
+            unnest-map [$$26, $$27, $$Points] <- index-search("Points", 0, "Default", "test", "Points", false, false, 1, $$32, 1, $$33, true, true, false)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$32, $$33] <- [2, 3]
                 -- ASSIGN  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/copy-to/copy-to.0.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/copy-to/copy-to.0.plan
index bd47279..40d7c43 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/copy-to/copy-to.0.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/copy-to/copy-to.0.plan
@@ -1,29 +1,58 @@
+distribute result []
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    write ($$x) to path ["myPath"] 
     -- SINK_WRITE  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (DESC, $$25)
         -- STABLE_SORT [$$25(DESC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$25(DESC)]  |PARTITIONED|
+            forward: shared-variable = $$28
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    assign [$$25] <- [$$x.getField("id")]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$x])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.OpenDataset)  |PARTITIONED|
+                          data-scan []<-[$$24, $$x] <- test.OpenDataset
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$28] <- [agg-range-map($$26, $$27)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$26, $$27] <- [agg-local-sampling($$25), agg-null-writer($$25)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$25] <- [$$x.getField("id")]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$x])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.OpenDataset)  |PARTITIONED|
+                                  data-scan []<-[$$24, $$x] <- test.OpenDataset
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/copy-to/copy-to.1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/copy-to/copy-to.1.plan
index 4e5d202..402769c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/copy-to/copy-to.1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/copy-to/copy-to.1.plan
@@ -1,31 +1,62 @@
+distribute result []
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    write ($$26) to path ["myPath"] 
     -- SINK_WRITE  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (DESC, $$32) (ASC, $$33)
         -- STABLE_SORT [$$32(DESC), $$33(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$32(DESC), $$33(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$37
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    assign [$$33, $$32] <- [$$26.getField("name"), $$26.getField("id")]
                     -- ASSIGN  |PARTITIONED|
+                      assign [$$26] <- [{"name": $$od.getField("name"), "id": $$od.getField("id")}] project: [$$26]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$od])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.OpenDataset)  |PARTITIONED|
+                            data-scan []<-[$$29, $$od] <- test.OpenDataset
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$37] <- [agg-range-map($$34, $$35, $$36)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$34, $$35, $$36] <- [agg-local-sampling($$32, $$33), agg-null-writer($$32), agg-null-writer($$33)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$33, $$32] <- [$$26.getField("name"), $$26.getField("id")]
                             -- ASSIGN  |PARTITIONED|
+                              assign [$$26] <- [{"name": $$od.getField("name"), "id": $$od.getField("id")}] project: [$$26]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$od])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.OpenDataset)  |PARTITIONED|
+                                    data-scan []<-[$$29, $$od] <- test.OpenDataset
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/copy-to/copy-to.2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/copy-to/copy-to.2.plan
index d6efffc..cde53de 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/copy-to/copy-to.2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/copy-to/copy-to.2.plan
@@ -1,12 +1,24 @@
+distribute result []
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    write ($$x) to path ["myPath"] 
     -- SINK_WRITE  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$25(DESC) ]  |PARTITIONED|
+        order (DESC, $$25)
         -- STABLE_SORT [$$25(DESC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            assign [$$25] <- [$$x.getField("id")]
             -- ASSIGN  |PARTITIONED|
+              project ([$$x])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.OpenDataset)  |PARTITIONED|
+                  data-scan []<-[$$24, $$x] <- test.OpenDataset
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/copy-to/copy-to.3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/copy-to/copy-to.3.plan
index e94b117..ef4d213 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/copy-to/copy-to.3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/copy-to/copy-to.3.plan
@@ -1,13 +1,26 @@
+distribute result []
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    write ($$26) to path ["myPath"] 
     -- SINK_WRITE  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$32(DESC), $$33(ASC) ]  |PARTITIONED|
+        order (DESC, $$32) (ASC, $$33)
         -- STABLE_SORT [$$32(DESC), $$33(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            assign [$$33, $$32] <- [$$26.getField("name"), $$26.getField("id")]
             -- ASSIGN  |PARTITIONED|
+              assign [$$26] <- [{"name": $$od.getField("name"), "id": $$od.getField("id")}] project: [$$26]
               -- ASSIGN  |PARTITIONED|
+                project ([$$od])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.OpenDataset)  |PARTITIONED|
+                    data-scan []<-[$$29, $$od] <- test.OpenDataset
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/cust_group_no_agg.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/cust_group_no_agg.plan
index b2c62ae..b0ff25d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/cust_group_no_agg.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/cust_group_no_agg.plan
@@ -1,14 +1,25 @@
+distribute result [$$name]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- SORT_GROUP_BY[$$37]  |PARTITIONED|
-            {
+    group by ([$$name := $$37]) decor ([]) {
+              aggregate [] <- []
               -- AGGREGATE  |LOCAL|
+                nested tuple source
                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-            }
+           }
+    -- SORT_GROUP_BY[$$37]  |PARTITIONED|
+      exchange
       -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+        assign [$$37] <- [$$c.getField(1)] project: [$$37]
         -- ASSIGN  |PARTITIONED|
+          project ([$$c])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- DATASOURCE_SCAN (group_no_agg.Customers)  |PARTITIONED|
+              data-scan []<-[$$38, $$c] <- group_no_agg.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/denorm-cust-order.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/denorm-cust-order.plan
index 6cab866..f8133ba 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/denorm-cust-order.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/denorm-cust-order.plan
@@ -1,26 +1,49 @@
+distribute result [$$96]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$96] <- [{"cid": $$cid, "cust": $$87, "cnt-orders": $$102, "orders": $$95}] project: [$$96]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$99]  |PARTITIONED|
-                {
+        group by ([$$cid := $$99]) decor ([]) {
+                  aggregate [$$87, $$95, $$102] <- [listify({"c": $$c}), listify({"o": $$o}), agg-sql-count($$o)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$99]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$99)
             -- STABLE_SORT [$$99(ASC)]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$c, $$o, $$99])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$99, $$101))
                     -- HYBRID_HASH_JOIN [$$99][$$101]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$99]  |PARTITIONED|
-                        -- DATASOURCE_SCAN (custorder.Customers)  |PARTITIONED|
+                        data-scan []<-[$$99, $$c] <- custorder.Customers
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$101]  |PARTITIONED|
+                        assign [$$101] <- [$$o.getField(1)]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$o])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (custorder.Orders)  |PARTITIONED|
+                              data-scan []<-[$$100, $$o] <- custorder.Orders
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/disjunction-to-join-delete-3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/disjunction-to-join-delete-3.plan
index 7d9ab0c..12f2c6b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/disjunction-to-join-delete-3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/disjunction-to-join-delete-3.plan
@@ -1,25 +1,50 @@
+commit
 -- COMMIT  |PARTITIONED|
+  project ([$$19])
   -- STREAM_PROJECT  |PARTITIONED|
+    exchange
     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+      delete from TestSetIndex on test.TestSet from [$$24]
       -- INDEX_INSERT_DELETE  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          project ([$$24, $$19])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              delete from test.TestSet from record: $$TestSet partitioned by [$$19]
               -- INSERT_DELETE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  materialize
                   -- MATERIALIZE  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$19]  |PARTITIONED|
+                      assign [$$24, $$19] <- [$$TestSet.getField(1), $$TestSet.getField(0)]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$TestSet])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (eq($$23, $$21))
                             -- HYBRID_HASH_JOIN [$$21][$$23]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$21] <- [$$TestSet.getField(2)]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$TestSet])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.TestSet)  |PARTITIONED|
+                                      data-scan []<-[$$20, $$TestSet] <- test.TestSet
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                unnest $$23 <- scan-collection(array: [ "one", "two" ])
                                 -- UNNEST  |UNPARTITIONED|
-                                  -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
\ No newline at end of file
+                                  empty-tuple-source
+                                  -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/external-cross-product.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/external-cross-product.plan
index 8c77a56..d9f2063 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/external-cross-product.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/external-cross-product.plan
@@ -1,42 +1,84 @@
+distribute result [$$58]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$58] <- [{"$1": $$59}] project: [$$58]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$59] <- [agg-sql-sum($$60)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$60] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (true)
               -- NESTED_LOOP  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (true)
                   -- NESTED_LOOP  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [] <- [] project: []
                       -- ASSIGN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
+                                  data-scan []<-[$$o2] <- test.Orders
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      replicate
                       -- REPLICATE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
+                                  data-scan []<-[$$o2] <- test.Orders
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  assign [] <- [] project: []
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      replicate
                       -- REPLICATE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
+                                  data-scan []<-[$$o2] <- test.Orders
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/extract-common-operators/extract-common-operators.01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/extract-common-operators/extract-common-operators.01.plan
index e0c2670..6984dda 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/extract-common-operators/extract-common-operators.01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/extract-common-operators/extract-common-operators.01.plan
@@ -1,92 +1,184 @@
+distribute result [$$397]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$397] <- [{"DataverseName": $$405, "SynonymName": $$406}] project: [$$397]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$405(ASC), $$406(ASC) ]  |PARTITIONED|
+        order (ASC, $$405) (ASC, $$406)
         -- STABLE_SORT [$$405(ASC), $$406(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$405, $$406])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                left outer join (eq($$414, $$410))
                 -- HYBRID_HASH_JOIN [$$414][$$410]  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$405(ASC), $$406(ASC)] HASH:[$$414]  |PARTITIONED|
+                    order (ASC, $$405) (ASC, $$406)
                     -- STABLE_SORT [$$405(ASC), $$406(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$405, $$406, $$414])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            left outer join (eq($$408, $$414))
                             -- HYBRID_HASH_JOIN [$$414][$$408]  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$414]  |PARTITIONED|
+                                assign [$$414] <- [$$s.getField(3)] project: [$$405, $$406, $$414]
                                 -- ASSIGN  |PARTITIONED|
+                                  assign [$$405, $$406, $$s] <- [$$409, $$410, $$s] project: [$$405, $$406, $$s]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      replicate
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (Metadata.Synonym)  |PARTITIONED|
+                                          data-scan []<-[$$409, $$410, $$s] <- Metadata.Synonym
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$408]  |PARTITIONED|
+                                project ([$$408])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (and(eq($$408, $$ds_name), eq($$407, $$dv_name)))
                                     -- HYBRID_HASH_JOIN [$$408, $$407][$$ds_name, $$dv_name]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$408, $$407]  |PARTITIONED|
+                                            project ([$$408, $$407])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (Metadata.Dataset)  |PARTITIONED|
+                                                data-scan []<-[$$407, $$408, $$d] <- Metadata.Dataset
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$ds_name, $$dv_name]  |PARTITIONED|
+                                        join (true)
                                         -- NESTED_LOOP  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            unnest $$dv_name <- scan-collection(array: [ "test2", "test1" ])
                                             -- UNNEST  |UNPARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            replicate
                                             -- REPLICATE  |UNPARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                unnest $$ds_name <- scan-collection(array: [ "ds2", "ds1" ])
                                                 -- UNNEST  |UNPARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$410]  |PARTITIONED|
+                    project ([$$410])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        left outer join (eq($$412, $$428))
                         -- HYBRID_HASH_JOIN [$$428][$$412]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$428]  |PARTITIONED|
+                            project ([$$410, $$428])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$410, $$syn_name))
                                 -- HYBRID_HASH_JOIN [$$410][$$syn_name]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$410]  |PARTITIONED|
+                                    assign [$$428] <- [$$s.getField(3)] project: [$$410, $$428]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$410, $$s])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (Metadata.Synonym)  |PARTITIONED|
+                                              data-scan []<-[$$409, $$410, $$s] <- Metadata.Synonym
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$syn_name]  |PARTITIONED|
+                                    unnest $$syn_name <- scan-collection(array: [ "syn2", "syn1" ])
                                     -- UNNEST  |UNPARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$412]  |PARTITIONED|
+                            project ([$$412])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (and(eq($$412, $$ds_name), eq($$411, $$dv_name)))
                                 -- HYBRID_HASH_JOIN [$$412, $$411][$$ds_name, $$dv_name]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$412, $$411] <- [$$408, $$407] project: [$$412, $$411]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$408, $$407]  |PARTITIONED|
+                                            project ([$$408, $$407])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (Metadata.Dataset)  |PARTITIONED|
+                                                data-scan []<-[$$407, $$408, $$d] <- Metadata.Dataset
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$ds_name, $$dv_name]  |PARTITIONED|
+                                    join (true)
                                     -- NESTED_LOOP  |UNPARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        assign [$$ds_name] <- [$$ds_name] project: [$$ds_name]
                                         -- ASSIGN  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            replicate
                                             -- REPLICATE  |UNPARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                unnest $$ds_name <- scan-collection(array: [ "ds2", "ds1" ])
                                                 -- UNNEST  |UNPARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        unnest $$dv_name <- scan-collection(array: [ "test2", "test1" ])
                                         -- UNNEST  |UNPARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter/inverted-btree-search-return-optional-field.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter/inverted-btree-search-return-optional-field.plan
index a76d642..22cd3c6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter/inverted-btree-search-return-optional-field.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter/inverted-btree-search-return-optional-field.plan
@@ -1,27 +1,54 @@
+distribute result [$$38]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 2147483647 offset 0
     -- STREAM_LIMIT  |UNPARTITIONED|
+      assign [$$38] <- [{"place.bounding_box": $$45, "user.id": $$46, "id": $$41, "coordinate": $$48, "create_at": $$40}] project: [$$38]
       -- ASSIGN  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$40(DESC) ]  |PARTITIONED|
+          limit 2147483647
           -- STREAM_LIMIT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (topK: 2147483647) (DESC, $$40)
               -- STABLE_SORT [topK: 2147483647] [$$40(DESC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$45, $$46, $$41, $$48, $$40])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (eq($$42, $$27))
                       -- HYBRID_HASH_JOIN [$$27][$$42]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          select (and(ftcontains($$t.getField(2), array: [ "francisco" ], "mode", "all"), ge($$40, datetime: { 2018-02-22T10:53:07.888 }), lt($$40, datetime: { 2018-02-22T18:50:39.301 }))) project: [$$45, $$46, $$41, $$48, $$40, $$27]
                           -- STREAM_SELECT  |PARTITIONED|
+                            assign [$$27, $$45, $$46, $$48, $$40] <- [$$t.getField(14).getField(0), $$t.getField(13).getField(6), $$t.getField(12).getField(0), $$t.getField(6), $$t.getField(0)]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (twitter.ds_tweet.ds_tweet)  |PARTITIONED|
+                                unnest-map [$$41, $$t] <- index-search("ds_tweet", 0, "Default", "twitter", "ds_tweet", false, false, 1, $$53, 1, $$53, true, true, true) with filter on min:[$$54] max:[$$55]
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$53)
                                     -- STABLE_SORT [$$53(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- SINGLE_PARTITION_INVERTED_INDEX_SEARCH (twitter.ds_tweet.text_idx)  |PARTITIONED|
+                                        unnest-map [$$53, $$54, $$55] <- index-search("text_idx", 2, "Default", "twitter", "ds_tweet", false, false, 0, null, 21, true, 1, $$52)
+                                        -- SINGLE_PARTITION_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$52] <- [array: [ "francisco" ]]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          unnest $$42 <- scan-collection(array: [ 51, 37, 24, 11 ])
                           -- UNNEST  |UNPARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_0.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_0.plan
index 190d740..4b697dc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_0.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_0.plan
@@ -1,10 +1,20 @@
+distribute result [$$16]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$16] <- [{"KVStore": $$KVStore}] project: [$$16]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$KVStore.getField(0), 10))
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$KVStore])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (KeyVerse.KVStore)  |PARTITIONED|
+            data-scan []<-[$$17, $$KVStore, $$18] <- KeyVerse.KVStore with filter on min:[$$20] max:[]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                assign [$$20] <- [10]
                 -- ASSIGN  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_1.plan
index 190d740..2bb008b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_1.plan
@@ -1,10 +1,20 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"KVStore": $$KVStore}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$19.getField(6), 11)) project: [$$KVStore]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$KVStore, $$19])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (KeyVerse.KVStore)  |PARTITIONED|
+            data-scan []<-[$$18, $$KVStore, $$19] <- KeyVerse.KVStore with filter on min:[$$21] max:[]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                assign [$$21] <- [11]
                 -- ASSIGN  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_2.plan
index 190d740..42314e0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_2.plan
@@ -1,10 +1,20 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$18] <- [{"k": $$k, "meta": $$21}] project: [$$18]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$20, 12)) project: [$$k, $$21]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$20, $$k, $$21])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (KeyVerse.KVStore)  |PARTITIONED|
+            data-scan []<-[$$20, $$k, $$21] <- KeyVerse.KVStore with filter on min:[$$23] max:[]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                assign [$$23] <- [12]
                 -- ASSIGN  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_3.plan
index 190d740..4b697dc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_3.plan
@@ -1,10 +1,20 @@
+distribute result [$$16]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$16] <- [{"KVStore": $$KVStore}] project: [$$16]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$KVStore.getField(0), 10))
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$KVStore])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (KeyVerse.KVStore)  |PARTITIONED|
+            data-scan []<-[$$17, $$KVStore, $$18] <- KeyVerse.KVStore with filter on min:[$$20] max:[]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                assign [$$20] <- [10]
                 -- ASSIGN  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_4.plan
index 190d740..4529a0b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_4.plan
@@ -1,10 +1,20 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"KVStore": $$KVStore}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$19.getField(8), 10)) project: [$$KVStore]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$KVStore, $$19])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (KeyVerse.KVStore)  |PARTITIONED|
+            data-scan []<-[$$18, $$KVStore, $$19] <- KeyVerse.KVStore with filter on min:[$$21] max:[]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                assign [$$21] <- [10]
                 -- ASSIGN  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_5.plan
index 190d740..9577873 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_5.plan
@@ -1,10 +1,20 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"KVStore": $$KVStore}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$20.getField(8), 10)) project: [$$KVStore]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$KVStore, $$20])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (KeyVerse.KVStore)  |PARTITIONED|
+            data-scan []<-[$$18, $$19, $$KVStore, $$20] <- KeyVerse.KVStore with filter on min:[$$22] max:[]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                assign [$$22] <- [10]
                 -- ASSIGN  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_with_idx_0.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_with_idx_0.plan
index ac9bc4a..20e2c39 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_with_idx_0.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_with_idx_0.plan
@@ -1,47 +1,94 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    union ($$73, $$98, $$34)
     -- UNION_ALL  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        assign [$$73] <- [{"t": $$t}] project: [$$73]
         -- ASSIGN  |PARTITIONED|
+          select (spatial-intersect($$38, $$70.getField(1))) project: [$$t]
           -- STREAM_SELECT  |PARTITIONED|
+            project ([$$t, $$38, $$70])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.OfficerLocations.OfficerLocations)  |PARTITIONED|
+                unnest-map [$$69, $$70] <- index-search("OfficerLocations", 0, "Default", "test", "OfficerLocations", true, false, 1, $$50, 1, $$50, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$t, $$38, $$50])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        split ($$51)
                         -- SPLIT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$t, $$38, $$46, $$47, $$50, $$51])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- RTREE_SEARCH (test.OfficerLocations.o_location)  |PARTITIONED|
+                                unnest-map [$$46, $$47, $$48, $$49, $$50, $$51] <- index-search("o_location", 1, "Default", "test", "OfficerLocations", true, true, 4, $$42, $$43, $$44, $$45)
+                                -- RTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$42, $$43, $$44, $$45] <- [create-mbr($$38, 2, 0), create-mbr($$38, 2, 1), create-mbr($$38, 2, 2), create-mbr($$38, 2, 3)]
                                     -- ASSIGN  |PARTITIONED|
+                                      assign [$$38] <- [create-circle($$t.getField(0), 100.0)]
                                       -- ASSIGN  |PARTITIONED|
+                                        select (gt($$36.getField(2), 100)) project: [$$t]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          project ([$$t, $$36])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.KVStore)  |PARTITIONED|
+                                              data-scan []<-[$$35, $$t, $$36] <- test.KVStore with filter on min:[$$72] max:[]
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                  assign [$$72] <- [100]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        assign [$$98] <- [{"t": $$t}] project: [$$98]
         -- ASSIGN  |PARTITIONED|
+          select (spatial-intersect($$38, create-point($$46, $$47))) project: [$$t]
           -- STREAM_SELECT  |PARTITIONED|
+            project ([$$t, $$38, $$46, $$47])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                split ($$51)
                 -- SPLIT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$t, $$38, $$46, $$47, $$50, $$51])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- RTREE_SEARCH (test.OfficerLocations.o_location)  |PARTITIONED|
+                        unnest-map [$$46, $$47, $$48, $$49, $$50, $$51] <- index-search("o_location", 1, "Default", "test", "OfficerLocations", true, true, 4, $$42, $$43, $$44, $$45)
+                        -- RTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$42, $$43, $$44, $$45] <- [create-mbr($$38, 2, 0), create-mbr($$38, 2, 1), create-mbr($$38, 2, 2), create-mbr($$38, 2, 3)]
                             -- ASSIGN  |PARTITIONED|
+                              assign [$$38] <- [create-circle($$t.getField(0), 100.0)]
                               -- ASSIGN  |PARTITIONED|
+                                select (gt($$36.getField(2), 100)) project: [$$t]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  project ([$$t, $$36])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.KVStore)  |PARTITIONED|
+                                      data-scan []<-[$$35, $$t, $$36] <- test.KVStore with filter on min:[$$72] max:[]
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          assign [$$72] <- [100]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_with_idx_1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_with_idx_1.plan
index 569c903..2b43140 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_with_idx_1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_with_idx_1.plan
@@ -1,22 +1,44 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"t": $$t}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$t])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (spatial-intersect($$38, $$39))
           -- NESTED_LOOP  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              assign [$$38] <- [create-circle($$t.getField(0), 100.0)]
               -- ASSIGN  |PARTITIONED|
+                select (gt($$36.getField(2), 100)) project: [$$t]
                 -- STREAM_SELECT  |PARTITIONED|
+                  project ([$$t, $$36])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.KVStore)  |PARTITIONED|
+                      data-scan []<-[$$35, $$t, $$36] <- test.KVStore with filter on min:[$$42] max:[]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          assign [$$42] <- [100]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- BROADCAST_EXCHANGE  |PARTITIONED|
+              assign [$$39] <- [$$o.getField(1)] project: [$$39]
               -- ASSIGN  |PARTITIONED|
+                project ([$$o])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.OfficerLocations)  |PARTITIONED|
+                    data-scan []<-[$$37, $$o] <- test.OfficerLocations
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_with_idx_2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_with_idx_2.plan
index cccf7a1..1080011 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_with_idx_2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_with_idx_2.plan
@@ -1,22 +1,44 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"t": $$t}] project: [$$33]
     -- ASSIGN  |PARTITIONED|
+      project ([$$t])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$37, $$38))
           -- HYBRID_HASH_JOIN [$$37][$$38]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+              select (gt($$35.getField(2), 100)) project: [$$t, $$37]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$37] <- [$$t.getField(2)]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.KVStore)  |PARTITIONED|
+                      data-scan []<-[$$34, $$t, $$35] <- test.KVStore with filter on min:[$$40] max:[]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          assign [$$40] <- [100]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+              assign [$$38] <- [$$o.getField(2)] project: [$$38]
               -- ASSIGN  |PARTITIONED|
+                project ([$$o])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.OfficerLocations)  |PARTITIONED|
+                    data-scan []<-[$$36, $$o] <- test.OfficerLocations
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_with_idx_3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_with_idx_3.plan
index cccf7a1..1080011 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_with_idx_3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter_on_meta_with_idx_3.plan
@@ -1,22 +1,44 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"t": $$t}] project: [$$33]
     -- ASSIGN  |PARTITIONED|
+      project ([$$t])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$37, $$38))
           -- HYBRID_HASH_JOIN [$$37][$$38]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+              select (gt($$35.getField(2), 100)) project: [$$t, $$37]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$37] <- [$$t.getField(2)]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.KVStore)  |PARTITIONED|
+                      data-scan []<-[$$34, $$t, $$35] <- test.KVStore with filter on min:[$$40] max:[]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          assign [$$40] <- [100]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+              assign [$$38] <- [$$o.getField(2)] project: [$$38]
               -- ASSIGN  |PARTITIONED|
+                project ([$$o])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.OfficerLocations)  |PARTITIONED|
+                    data-scan []<-[$$36, $$o] <- test.OfficerLocations
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/flwr/at07.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/flwr/at07.plan
index 5e95e6a..5cedd1e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/flwr/at07.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/flwr/at07.plan
@@ -1,35 +1,70 @@
+distribute result [$$100]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$100] <- [object-concat-strict(to-object-var-str($$83), {"percentile": $#2, "i": $$i, "cnt": $$103})] project: [$$100]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$#2(ASC) ]  |PARTITIONED|
+        order (ASC, $#2)
         -- STABLE_SORT [$#2(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            assign [$#2] <- [numeric-multiply(numeric-divide($$i, $$103), 100)]
             -- ASSIGN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (true)
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange
                   -- RANDOM_PARTITION_EXCHANGE  |PARTITIONED|
+                    select (eq($$108, "NicholasStroh")) project: [$$83, $$i]
                     -- STREAM_SELECT  |PARTITIONED|
+                      running-aggregate [$$i] <- [tid()]
                       -- RUNNING_AGGREGATE  |PARTITIONED|
+                        assign [$$83] <- [{"name": $$108, "alias": $$110}] project: [$$83, $$108]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- SORT_MERGE_EXCHANGE [$$108(ASC) ]  |PARTITIONED|
+                            order (ASC, $$108)
                             -- STABLE_SORT [$$108(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$110, $$108] <- [$$FacebookUsers.getField(1), $$FacebookUsers.getField(2)] project: [$$108, $$110]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$FacebookUsers])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      replicate
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.FacebookUsers)  |PARTITIONED|
+                                          data-scan []<-[$$101, $$FacebookUsers] <- test.FacebookUsers
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    aggregate [$$103] <- [agg-sql-sum($$112)]
                     -- AGGREGATE  |UNPARTITIONED|
+                      exchange
                       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                        aggregate [$$112] <- [agg-sql-count(1)]
                         -- AGGREGATE  |PARTITIONED|
+                          assign [$$107, $$106] <- [$$101, $$FacebookUsers] project: [$$107, $$106]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.FacebookUsers)  |PARTITIONED|
+                                  data-scan []<-[$$101, $$FacebookUsers] <- test.FacebookUsers
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/flwr/select-let-1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/flwr/select-let-1.plan
index de331ad..7c5d5fc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/flwr/select-let-1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/flwr/select-let-1.plan
@@ -1,4 +1,8 @@
+distribute result [$$x]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$x] <- [2]
     -- ASSIGN  |UNPARTITIONED|
-      -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
\ No newline at end of file
+      empty-tuple-source
+      -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/gby_partitioning_property_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/gby_partitioning_property_01.plan
index 415ce24..8d7db3c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/gby_partitioning_property_01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/gby_partitioning_property_01.plan
@@ -1,33 +1,60 @@
+distribute result [$$62]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$62] <- [{"id": $$id, "count": $$68}] project: [$$62]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$74]  |PARTITIONED|
-                {
+        group by ([$$id := $$74]) decor ([]) {
+                  aggregate [$$68] <- [agg-sql-sum($$73)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$74]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- SORT_GROUP_BY[$$64]  |PARTITIONED|
-                    {
+            group by ([$$74 := $$64]) decor ([]) {
+                      aggregate [$$73] <- [agg-sql-count(1)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$64]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$64])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$64, $$67))
                     -- HYBRID_HASH_JOIN [$$64][$$67]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$64]  |PARTITIONED|
+                        assign [$$64] <- [meta($$user).getField("id")] project: [$$64]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$user])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.GleambookUsers)  |PARTITIONED|
+                              data-scan []<-[$$65, $$user] <- test.GleambookUsers
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$67]  |PARTITIONED|
+                        assign [$$67] <- [$$message.getField("author_id")] project: [$$67]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$message])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.GleambookMessages)  |PARTITIONED|
+                              data-scan []<-[$$66, $$message] <- test.GleambookMessages
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/gby-case-01.3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/gby-case-01.3.plan
index 87ae388..fdb7356 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/gby-case-01.3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/gby-case-01.3.plan
@@ -1,22 +1,38 @@
+distribute result [$$86]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$86] <- [{"x": $$x, "res": switch-case(true, eq($$90, 0), 0, numeric-divide($$91, $$92))}] project: [$$86]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$x(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$99]  |PARTITIONED|
-                {
+        group by ([$$x := $$99]) decor ([]) {
+                  aggregate [$$90, $$91, $$92] <- [agg-global-sql-sum($$96), agg-global-sql-sum($$97), agg-global-sql-sum($$98)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$99]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$99]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$87]  |PARTITIONED|
-                    {
+            group by ([$$99 := $$87]) decor ([]) {
+                      aggregate [$$96, $$97, $$98] <- [agg-local-sql-sum($$67), agg-local-sql-sum(numeric-multiply($$93, $$67)), agg-local-sql-sum($$67)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$87]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$67, $$93, $$87] <- [$$t1.getField("z"), $$t1.getField("y"), $$t1.getField("x")] project: [$$67, $$93, $$87]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t1])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+                      data-scan []<-[$$89, $$t1] <- test.t1
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/gby-case-01.4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/gby-case-01.4.plan
index 8db82ea..1da1bb6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/gby-case-01.4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/gby-case-01.4.plan
@@ -1,22 +1,38 @@
+distribute result [$$111]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$111] <- [{"x": $$x, "res": switch-case(true, eq($$116, 0), 0, numeric-divide($$117, $$118))}] project: [$$111]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$x(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$128]  |PARTITIONED|
-                {
+        group by ([$$x := $$128]) decor ([]) {
+                  aggregate [$$116, $$117, $$118] <- [agg-global-sql-sum($$125), agg-global-sql-sum($$126), agg-global-sql-sum($$127)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$128]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$128]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$113]  |PARTITIONED|
-                    {
+            group by ([$$128 := $$113]) decor ([]) {
+                      aggregate [$$125, $$126, $$127] <- [agg-local-sql-sum($$87), agg-local-sql-sum(numeric-multiply($$119, $$87)), agg-local-sql-sum($$87)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$113]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$87, $$119, $$113] <- [$$t1.getField("z"), $$t1.getField("y"), $$t1.getField("x")] project: [$$87, $$119, $$113]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t1])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+                      data-scan []<-[$$115, $$t1] <- test.t1
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/grouping-sets-1.1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/grouping-sets-1.1.plan
index 5771a6e..c140a17 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/grouping-sets-1.1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/grouping-sets-1.1.plan
@@ -1,112 +1,200 @@
+distribute result [$#3]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$#3])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$391(ASC), $$392(ASC), $$393(ASC) ]  |PARTITIONED|
+        order (ASC, $$391) (ASC, $$392) (ASC, $$393)
         -- STABLE_SORT [$$391(ASC), $$392(ASC), $$393(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            union ($$1093, $$1195, $#3) ($$398, $$ten, $$393) ($$492, $$four, $$392) ($$592, $$two, $$391)
             -- UNION_ALL  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$1093, $$398, $$492, $$592])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    union ($$698, $$ten, $$398) ($$768, $$four, $$492) ($$844, $$two, $$592) ($$1094, $$1144, $$1093)
                     -- UNION_ALL  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        union ($$ten, $$ten, $$698) ($$four, $$four, $$768) ($$two, $$two, $$844) ($$1196, $$1228, $$1094)
                         -- UNION_ALL  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$1196] <- [cast(cast({"two": $$two, "four": $$four, "ten": $$ten, "grp": 3, "agg_sum": $$387}))] project: [$$ten, $$four, $$two, $$1196]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                group by ([$$two := $$1083]) decor ([$$four := $$237; $$ten := $$238]) {
+                                          aggregate [$$387] <- [agg-global-sql-sum($$1082)]
+                                          -- AGGREGATE  |LOCAL|
+                                            nested tuple source
+                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                       }
                                 -- SORT_GROUP_BY[$$1083]  |PARTITIONED|
-                                        {
-                                          -- AGGREGATE  |LOCAL|
-                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$1083]  |PARTITIONED|
+                                    group by ([$$1083 := $$244]) decor ([$$237; $$238]) {
+                                              aggregate [$$1082] <- [agg-local-sql-sum($$185)]
+                                              -- AGGREGATE  |LOCAL|
+                                                nested tuple source
+                                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                           }
                                     -- SORT_GROUP_BY[$$244]  |PARTITIONED|
-                                            {
-                                              -- AGGREGATE  |LOCAL|
-                                                -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$237, $$238, $$185, $$244] <- [null, null, $$tenk.getField(5), $$tenk.getField(2)] project: [$$237, $$238, $$185, $$244]
                                         -- ASSIGN  |PARTITIONED|
+                                          assign [$$tenk] <- [$$tenk] project: [$$tenk]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              replicate
                                               -- REPLICATE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  project ([$$tenk])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                                      data-scan []<-[$$250, $$tenk] <- test.tenk
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$1228] <- [cast(cast({"two": $$two, "four": $$four, "ten": $$ten, "grp": 5, "agg_sum": $$388}))] project: [$$ten, $$four, $$two, $$1228]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                group by ([$$four := $$1085]) decor ([$$two := $$239; $$ten := $$240]) {
+                                          aggregate [$$388] <- [agg-global-sql-sum($$1084)]
+                                          -- AGGREGATE  |LOCAL|
+                                            nested tuple source
+                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                       }
                                 -- SORT_GROUP_BY[$$1085]  |PARTITIONED|
-                                        {
-                                          -- AGGREGATE  |LOCAL|
-                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$1085]  |PARTITIONED|
-                                    -- SORT_GROUP_BY[$$245]  |PARTITIONED|
-                                            {
+                                    group by ([$$1085 := $$245]) decor ([$$239; $$240]) {
+                                              aggregate [$$1084] <- [agg-local-sql-sum($$198)]
                                               -- AGGREGATE  |LOCAL|
+                                                nested tuple source
                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                           }
+                                    -- SORT_GROUP_BY[$$245]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$239, $$240, $$198, $$245] <- [null, null, $$tenk.getField(5), $$tenk.getField(3)] project: [$$239, $$240, $$198, $$245]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            replicate
                                             -- REPLICATE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$tenk])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                                    data-scan []<-[$$250, $$tenk] <- test.tenk
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$1144] <- [cast(cast({"two": $$two, "four": $$four, "ten": $$ten, "grp": 1, "agg_sum": $$389}))] project: [$$ten, $$four, $$two, $$1144]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- SORT_GROUP_BY[$$1087, $$1088]  |PARTITIONED|
-                                    {
+                            group by ([$$two := $$1087; $$four := $$1088]) decor ([$$ten := $$241]) {
+                                      aggregate [$$389] <- [agg-global-sql-sum($$1086)]
                                       -- AGGREGATE  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- SORT_GROUP_BY[$$1087, $$1088]  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$1087, $$1088]  |PARTITIONED|
-                                -- SORT_GROUP_BY[$$246, $$247]  |PARTITIONED|
-                                        {
+                                group by ([$$1087 := $$246; $$1088 := $$247]) decor ([$$241]) {
+                                          aggregate [$$1086] <- [agg-local-sql-sum($$212)]
                                           -- AGGREGATE  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- SORT_GROUP_BY[$$246, $$247]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$241, $$247, $$246, $$212] <- [null, $$tenk.getField(3), $$tenk.getField(2), $$tenk.getField(5)] project: [$$241, $$247, $$246, $$212]
                                     -- ASSIGN  |PARTITIONED|
+                                      assign [$$tenk] <- [$$tenk] project: [$$tenk]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$tenk])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                                  data-scan []<-[$$250, $$tenk] <- test.tenk
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$1195] <- [cast({"two": $$two, "four": $$four, "ten": $$ten, "grp": 6, "agg_sum": $$390})] project: [$$1195, $$ten, $$four, $$two]
                 -- ASSIGN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$1090]  |PARTITIONED|
-                            {
+                    group by ([$$ten := $$1090]) decor ([$$two := $$242; $$four := $$243]) {
+                              aggregate [$$390] <- [agg-global-sql-sum($$1089)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$1090]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$1090]  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$248]  |PARTITIONED|
-                                {
+                        group by ([$$1090 := $$248]) decor ([$$242; $$243]) {
+                                  aggregate [$$1089] <- [agg-local-sql-sum($$225)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$248]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$242, $$243, $$225, $$248] <- [null, null, $$tenk.getField(5), $$tenk.getField(4)] project: [$$242, $$243, $$225, $$248]
                             -- ASSIGN  |PARTITIONED|
+                              assign [$$tenk] <- [$$tenk] project: [$$tenk]
                               -- ASSIGN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  replicate
                                   -- REPLICATE  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$tenk])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                          data-scan []<-[$$250, $$tenk] <- test.tenk
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/grouping-sets-1.2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/grouping-sets-1.2.plan
index 6d00ac3..a772b7f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/grouping-sets-1.2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/grouping-sets-1.2.plan
@@ -1,329 +1,586 @@
+distribute result [$#3]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$#3])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$1231(ASC), $$1232(ASC), $$1233(ASC), $$1234(ASC) ]  |PARTITIONED|
+        order (ASC, $$1231) (ASC, $$1232) (ASC, $$1233) (ASC, $$1234)
         -- STABLE_SORT [$$1231(ASC), $$1232(ASC), $$1233(ASC), $$1234(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            union ($$693, $$10242, $#3) ($$1247, $$twenty, $$1234) ($$1585, $$ten, $$1233) ($$1929, $$four, $$1232) ($$2279, $$two, $$1231)
             -- UNION_ALL  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                union ($$692, $$10241, $$693) ($$2635, $$twenty, $$1247) ($$2941, $$ten, $$1585) ($$3253, $$four, $$1929) ($$3571, $$two, $$2279)
                 -- UNION_ALL  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    union ($$691, $$10240, $$692) ($$3895, $$twenty, $$2635) ($$4173, $$ten, $$2941) ($$4457, $$four, $$3253) ($$4747, $$two, $$3571)
                     -- UNION_ALL  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        union ($$10239, $$10859, $$691) ($$5043, $$twenty, $$3895) ($$5293, $$ten, $$4173) ($$5549, $$four, $$4457) ($$5811, $$two, $$4747)
                         -- UNION_ALL  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$10239, $$5043, $$5293, $$5549, $$5811])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                union ($$6079, $$twenty, $$5043) ($$6301, $$ten, $$5293) ($$6529, $$four, $$5549) ($$6763, $$two, $$5811) ($$10501, $$10679, $$10239)
                                 -- UNION_ALL  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    union ($$7003, $$twenty, $$6079) ($$7197, $$ten, $$6301) ($$7397, $$four, $$6529) ($$7603, $$two, $$6763) ($$10992, $$11151, $$10501)
                                     -- UNION_ALL  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        union ($$7815, $$twenty, $$7003) ($$7981, $$ten, $$7197) ($$8153, $$four, $$7397) ($$8331, $$two, $$7603) ($$11396, $$11534, $$10992)
                                         -- UNION_ALL  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            union ($$8515, $$twenty, $$7815) ($$8653, $$ten, $$7981) ($$8797, $$four, $$8153) ($$8947, $$two, $$8331) ($$11672, $$11787, $$11396)
                                             -- UNION_ALL  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                union ($$9103, $$twenty, $$8515) ($$9213, $$ten, $$8653) ($$9329, $$four, $$8797) ($$9451, $$two, $$8947) ($$11902, $$11994, $$11672)
                                                 -- UNION_ALL  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    union ($$9579, $$twenty, $$9103) ($$9661, $$ten, $$9213) ($$9749, $$four, $$9329) ($$9843, $$two, $$9451) ($$12086, $$12155, $$11902)
                                                     -- UNION_ALL  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        union ($$twenty, $$twenty, $$9579) ($$ten, $$ten, $$9661) ($$four, $$four, $$9749) ($$two, $$two, $$9843) ($$12224, $$12269, $$12086)
                                                         -- UNION_ALL  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            assign [$$12224] <- [cast(cast(cast(cast({"two": $$two, "four": $$four, "ten": $$ten, "twenty": $$twenty, "grp": 0, "agg_sum": $$1219}))))] project: [$$twenty, $$ten, $$four, $$two, $$12224]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                group by ([$$two := $$10196; $$four := $$10197; $$ten := $$10198; $$twenty := $$10199]) decor ([]) {
+                                                                          aggregate [$$1219] <- [agg-global-sql-sum($$10195)]
+                                                                          -- AGGREGATE  |LOCAL|
+                                                                            nested tuple source
+                                                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                                       }
                                                                 -- SORT_GROUP_BY[$$10196, $$10197, $$10198, $$10199]  |PARTITIONED|
-                                                                        {
-                                                                          -- AGGREGATE  |LOCAL|
-                                                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                        }
+                                                                  exchange
                                                                   -- HASH_PARTITION_EXCHANGE [$$10196, $$10197, $$10198, $$10199]  |PARTITIONED|
+                                                                    group by ([$$10196 := $$724; $$10197 := $$725; $$10198 := $$726; $$10199 := $$727]) decor ([]) {
+                                                                              aggregate [$$10195] <- [agg-local-sql-sum($$526)]
+                                                                              -- AGGREGATE  |LOCAL|
+                                                                                nested tuple source
+                                                                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                                           }
                                                                     -- SORT_GROUP_BY[$$724, $$725, $$726, $$727]  |PARTITIONED|
-                                                                            {
-                                                                              -- AGGREGATE  |LOCAL|
-                                                                                -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                            }
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        assign [$$727, $$726, $$725, $$724, $$526] <- [$$tenk.getField(5), $$tenk.getField(4), $$tenk.getField(3), $$tenk.getField(2), $$tenk.getField(6)] project: [$$727, $$726, $$725, $$724, $$526]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          assign [$$tenk] <- [$$tenk] project: [$$tenk]
                                                                           -- ASSIGN  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              replicate
                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  project ([$$tenk])
                                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                      -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                                                                      data-scan []<-[$$750, $$tenk] <- test.tenk
+                                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                          empty-tuple-source
                                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            assign [$$12269] <- [cast(cast(cast({"two": $$two, "four": $$four, "ten": $$ten, "twenty": $$twenty, "grp": 1, "agg_sum": $$1220})))] project: [$$twenty, $$ten, $$four, $$two, $$12269]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                group by ([$$two := $$10201; $$four := $$10202; $$ten := $$10203]) decor ([$$twenty := $$700]) {
+                                                                          aggregate [$$1220] <- [agg-global-sql-sum($$10200)]
+                                                                          -- AGGREGATE  |LOCAL|
+                                                                            nested tuple source
+                                                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                                       }
                                                                 -- SORT_GROUP_BY[$$10201, $$10202, $$10203]  |PARTITIONED|
-                                                                        {
-                                                                          -- AGGREGATE  |LOCAL|
-                                                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                        }
+                                                                  exchange
                                                                   -- HASH_PARTITION_EXCHANGE [$$10201, $$10202, $$10203]  |PARTITIONED|
-                                                                    -- SORT_GROUP_BY[$$728, $$729, $$730]  |PARTITIONED|
-                                                                            {
+                                                                    group by ([$$10201 := $$728; $$10202 := $$729; $$10203 := $$730]) decor ([$$700]) {
+                                                                              aggregate [$$10200] <- [agg-local-sql-sum($$541)]
                                                                               -- AGGREGATE  |LOCAL|
+                                                                                nested tuple source
                                                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                            }
+                                                                           }
+                                                                    -- SORT_GROUP_BY[$$728, $$729, $$730]  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        assign [$$700, $$730, $$729, $$728, $$541] <- [null, $$tenk.getField(4), $$tenk.getField(3), $$tenk.getField(2), $$tenk.getField(6)] project: [$$700, $$730, $$729, $$728, $$541]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            replicate
                                                                             -- REPLICATE  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                project ([$$tenk])
                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                    -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                                                                    data-scan []<-[$$750, $$tenk] <- test.tenk
+                                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        empty-tuple-source
                                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        assign [$$12155] <- [cast(cast(cast({"two": $$two, "four": $$four, "ten": $$ten, "twenty": $$twenty, "grp": 2, "agg_sum": $$1221})))] project: [$$twenty, $$ten, $$four, $$two, $$12155]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            group by ([$$two := $$10205; $$four := $$10206; $$twenty := $$10207]) decor ([$$ten := $$701]) {
+                                                                      aggregate [$$1221] <- [agg-global-sql-sum($$10204)]
+                                                                      -- AGGREGATE  |LOCAL|
+                                                                        nested tuple source
+                                                                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                                   }
                                                             -- SORT_GROUP_BY[$$10205, $$10206, $$10207]  |PARTITIONED|
-                                                                    {
-                                                                      -- AGGREGATE  |LOCAL|
-                                                                        -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                    }
+                                                              exchange
                                                               -- HASH_PARTITION_EXCHANGE [$$10205, $$10206, $$10207]  |PARTITIONED|
-                                                                -- SORT_GROUP_BY[$$731, $$732, $$733]  |PARTITIONED|
-                                                                        {
+                                                                group by ([$$10205 := $$731; $$10206 := $$732; $$10207 := $$733]) decor ([$$701]) {
+                                                                          aggregate [$$10204] <- [agg-local-sql-sum($$556)]
                                                                           -- AGGREGATE  |LOCAL|
+                                                                            nested tuple source
                                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                        }
+                                                                       }
+                                                                -- SORT_GROUP_BY[$$731, $$732, $$733]  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    assign [$$701, $$733, $$732, $$731, $$556] <- [null, $$tenk.getField(5), $$tenk.getField(3), $$tenk.getField(2), $$tenk.getField(6)] project: [$$701, $$733, $$732, $$731, $$556]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      assign [$$tenk] <- [$$tenk] project: [$$tenk]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          replicate
                                                                           -- REPLICATE  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              project ([$$tenk])
                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                                                                  data-scan []<-[$$750, $$tenk] <- test.tenk
+                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      empty-tuple-source
                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$11994] <- [cast(cast(cast({"two": $$two, "four": $$four, "ten": $$ten, "twenty": $$twenty, "grp": 3, "agg_sum": $$1222})))] project: [$$twenty, $$ten, $$four, $$two, $$11994]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        group by ([$$two := $$10209; $$four := $$10210]) decor ([$$ten := $$702; $$twenty := $$703]) {
+                                                                  aggregate [$$1222] <- [agg-global-sql-sum($$10208)]
+                                                                  -- AGGREGATE  |LOCAL|
+                                                                    nested tuple source
+                                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                               }
                                                         -- SORT_GROUP_BY[$$10209, $$10210]  |PARTITIONED|
-                                                                {
-                                                                  -- AGGREGATE  |LOCAL|
-                                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                }
+                                                          exchange
                                                           -- HASH_PARTITION_EXCHANGE [$$10209, $$10210]  |PARTITIONED|
-                                                            -- SORT_GROUP_BY[$$734, $$735]  |PARTITIONED|
-                                                                    {
+                                                            group by ([$$10209 := $$734; $$10210 := $$735]) decor ([$$702; $$703]) {
+                                                                      aggregate [$$10208] <- [agg-local-sql-sum($$570)]
                                                                       -- AGGREGATE  |LOCAL|
+                                                                        nested tuple source
                                                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                    }
+                                                                   }
+                                                            -- SORT_GROUP_BY[$$734, $$735]  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                assign [$$702, $$703, $$735, $$734, $$570] <- [null, null, $$tenk.getField(3), $$tenk.getField(2), $$tenk.getField(6)] project: [$$702, $$703, $$735, $$734, $$570]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  assign [$$tenk] <- [$$tenk] project: [$$tenk]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      replicate
                                                                       -- REPLICATE  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          project ([$$tenk])
                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                              -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                                                              data-scan []<-[$$750, $$tenk] <- test.tenk
+                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  empty-tuple-source
                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                assign [$$11787] <- [cast(cast({"two": $$two, "four": $$four, "ten": $$ten, "twenty": $$twenty, "grp": 4, "agg_sum": $$1223}))] project: [$$twenty, $$ten, $$four, $$two, $$11787]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    group by ([$$two := $$10212; $$ten := $$10213; $$twenty := $$10214]) decor ([$$four := $$704]) {
+                                                              aggregate [$$1223] <- [agg-global-sql-sum($$10211)]
+                                                              -- AGGREGATE  |LOCAL|
+                                                                nested tuple source
+                                                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                           }
                                                     -- SORT_GROUP_BY[$$10212, $$10213, $$10214]  |PARTITIONED|
-                                                            {
-                                                              -- AGGREGATE  |LOCAL|
-                                                                -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                            }
+                                                      exchange
                                                       -- HASH_PARTITION_EXCHANGE [$$10212, $$10213, $$10214]  |PARTITIONED|
-                                                        -- SORT_GROUP_BY[$$736, $$737, $$738]  |PARTITIONED|
-                                                                {
+                                                        group by ([$$10212 := $$736; $$10213 := $$737; $$10214 := $$738]) decor ([$$704]) {
+                                                                  aggregate [$$10211] <- [agg-local-sql-sum($$585)]
                                                                   -- AGGREGATE  |LOCAL|
+                                                                    nested tuple source
                                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                }
+                                                               }
+                                                        -- SORT_GROUP_BY[$$736, $$737, $$738]  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            assign [$$704, $$738, $$737, $$736, $$585] <- [null, $$tenk.getField(5), $$tenk.getField(4), $$tenk.getField(2), $$tenk.getField(6)] project: [$$704, $$738, $$737, $$736, $$585]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              assign [$$tenk] <- [$$tenk] project: [$$tenk]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  replicate
                                                                   -- REPLICATE  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      project ([$$tenk])
                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                          -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                                                          data-scan []<-[$$750, $$tenk] <- test.tenk
+                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              empty-tuple-source
                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$11534] <- [cast(cast({"two": $$two, "four": $$four, "ten": $$ten, "twenty": $$twenty, "grp": 5, "agg_sum": $$1224}))] project: [$$twenty, $$ten, $$four, $$two, $$11534]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                group by ([$$two := $$10216; $$ten := $$10217]) decor ([$$four := $$705; $$twenty := $$706]) {
+                                                          aggregate [$$1224] <- [agg-global-sql-sum($$10215)]
+                                                          -- AGGREGATE  |LOCAL|
+                                                            nested tuple source
+                                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                       }
                                                 -- SORT_GROUP_BY[$$10216, $$10217]  |PARTITIONED|
-                                                        {
-                                                          -- AGGREGATE  |LOCAL|
-                                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                        }
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$10216, $$10217]  |PARTITIONED|
-                                                    -- SORT_GROUP_BY[$$739, $$740]  |PARTITIONED|
-                                                            {
+                                                    group by ([$$10216 := $$739; $$10217 := $$740]) decor ([$$705; $$706]) {
+                                                              aggregate [$$10215] <- [agg-local-sql-sum($$599)]
                                                               -- AGGREGATE  |LOCAL|
+                                                                nested tuple source
                                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                            }
+                                                           }
+                                                    -- SORT_GROUP_BY[$$739, $$740]  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        assign [$$705, $$706, $$740, $$739, $$599] <- [null, null, $$tenk.getField(4), $$tenk.getField(2), $$tenk.getField(6)] project: [$$705, $$706, $$740, $$739, $$599]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          assign [$$tenk] <- [$$tenk] project: [$$tenk]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              replicate
                                                               -- REPLICATE  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  project ([$$tenk])
                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                                                      data-scan []<-[$$750, $$tenk] <- test.tenk
+                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$11151] <- [cast(cast({"two": $$two, "four": $$four, "ten": $$ten, "twenty": $$twenty, "grp": 6, "agg_sum": $$1225}))] project: [$$twenty, $$ten, $$four, $$two, $$11151]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            group by ([$$two := $$10219; $$twenty := $$10220]) decor ([$$four := $$707; $$ten := $$708]) {
+                                                      aggregate [$$1225] <- [agg-global-sql-sum($$10218)]
+                                                      -- AGGREGATE  |LOCAL|
+                                                        nested tuple source
+                                                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                   }
                                             -- SORT_GROUP_BY[$$10219, $$10220]  |PARTITIONED|
-                                                    {
-                                                      -- AGGREGATE  |LOCAL|
-                                                        -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                    }
+                                              exchange
                                               -- HASH_PARTITION_EXCHANGE [$$10219, $$10220]  |PARTITIONED|
-                                                -- SORT_GROUP_BY[$$741, $$742]  |PARTITIONED|
-                                                        {
+                                                group by ([$$10219 := $$741; $$10220 := $$742]) decor ([$$707; $$708]) {
+                                                          aggregate [$$10218] <- [agg-local-sql-sum($$613)]
                                                           -- AGGREGATE  |LOCAL|
+                                                            nested tuple source
                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                        }
+                                                       }
+                                                -- SORT_GROUP_BY[$$741, $$742]  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$707, $$708, $$742, $$741, $$613] <- [null, null, $$tenk.getField(5), $$tenk.getField(2), $$tenk.getField(6)] project: [$$707, $$708, $$742, $$741, $$613]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      assign [$$tenk] <- [$$tenk] project: [$$tenk]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          replicate
                                                           -- REPLICATE  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              project ([$$tenk])
                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                                                  data-scan []<-[$$750, $$tenk] <- test.tenk
+                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$10679] <- [cast(cast({"two": $$two, "four": $$four, "ten": $$ten, "twenty": $$twenty, "grp": 7, "agg_sum": $$1226}))] project: [$$twenty, $$ten, $$four, $$two, $$10679]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- SORT_GROUP_BY[$$10222]  |PARTITIONED|
-                                                {
+                                        group by ([$$two := $$10222]) decor ([$$four := $$709; $$ten := $$710; $$twenty := $$711]) {
+                                                  aggregate [$$1226] <- [agg-global-sql-sum($$10221)]
                                                   -- AGGREGATE  |LOCAL|
+                                                    nested tuple source
                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                               }
+                                        -- SORT_GROUP_BY[$$10222]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$10222]  |PARTITIONED|
-                                            -- SORT_GROUP_BY[$$743]  |PARTITIONED|
-                                                    {
+                                            group by ([$$10222 := $$743]) decor ([$$709; $$710; $$711]) {
+                                                      aggregate [$$10221] <- [agg-local-sql-sum($$626)]
                                                       -- AGGREGATE  |LOCAL|
+                                                        nested tuple source
                                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                    }
+                                                   }
+                                            -- SORT_GROUP_BY[$$743]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                assign [$$709, $$710, $$711, $$626, $$743] <- [null, null, null, $$tenk.getField(6), $$tenk.getField(2)] project: [$$709, $$710, $$711, $$626, $$743]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  assign [$$tenk] <- [$$tenk] project: [$$tenk]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          project ([$$tenk])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                                              data-scan []<-[$$750, $$tenk] <- test.tenk
+                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$10859] <- [cast({"two": $$two, "four": $$four, "ten": $$ten, "twenty": $$twenty, "grp": 12, "agg_sum": $$1227})] project: [$$10859, $$twenty, $$ten, $$four, $$two]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                group by ([$$ten := $$10224; $$twenty := $$10225]) decor ([$$two := $$712; $$four := $$713]) {
+                                          aggregate [$$1227] <- [agg-global-sql-sum($$10223)]
+                                          -- AGGREGATE  |LOCAL|
+                                            nested tuple source
+                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                       }
                                 -- SORT_GROUP_BY[$$10224, $$10225]  |PARTITIONED|
-                                        {
-                                          -- AGGREGATE  |LOCAL|
-                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$10224, $$10225]  |PARTITIONED|
-                                    -- SORT_GROUP_BY[$$744, $$745]  |PARTITIONED|
-                                            {
+                                    group by ([$$10224 := $$744; $$10225 := $$745]) decor ([$$712; $$713]) {
+                                              aggregate [$$10223] <- [agg-local-sql-sum($$640)]
                                               -- AGGREGATE  |LOCAL|
+                                                nested tuple source
                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                           }
+                                    -- SORT_GROUP_BY[$$744, $$745]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$712, $$713, $$745, $$744, $$640] <- [null, null, $$tenk.getField(5), $$tenk.getField(4), $$tenk.getField(6)] project: [$$712, $$713, $$745, $$744, $$640]
                                         -- ASSIGN  |PARTITIONED|
+                                          assign [$$tenk] <- [$$tenk] project: [$$tenk]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              replicate
                                               -- REPLICATE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  project ([$$tenk])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                                      data-scan []<-[$$750, $$tenk] <- test.tenk
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$10240] <- [cast({"two": $$two, "four": $$four, "ten": $$ten, "twenty": $$twenty, "grp": 13, "agg_sum": $$1228})] project: [$$10240, $$twenty, $$ten, $$four, $$two]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            group by ([$$ten := $$10227]) decor ([$$two := $$714; $$four := $$715; $$twenty := $$716]) {
+                                      aggregate [$$1228] <- [agg-global-sql-sum($$10226)]
+                                      -- AGGREGATE  |LOCAL|
+                                        nested tuple source
+                                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                   }
                             -- SORT_GROUP_BY[$$10227]  |PARTITIONED|
-                                    {
-                                      -- AGGREGATE  |LOCAL|
-                                        -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$10227]  |PARTITIONED|
-                                -- SORT_GROUP_BY[$$746]  |PARTITIONED|
-                                        {
+                                group by ([$$10227 := $$746]) decor ([$$714; $$715; $$716]) {
+                                          aggregate [$$10226] <- [agg-local-sql-sum($$653)]
                                           -- AGGREGATE  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- SORT_GROUP_BY[$$746]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$714, $$715, $$716, $$653, $$746] <- [null, null, null, $$tenk.getField(6), $$tenk.getField(4)] project: [$$714, $$715, $$716, $$653, $$746]
                                     -- ASSIGN  |PARTITIONED|
+                                      assign [$$tenk] <- [$$tenk] project: [$$tenk]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$tenk])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                                  data-scan []<-[$$750, $$tenk] <- test.tenk
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    assign [$$10241] <- [cast({"two": $$two, "four": $$four, "ten": $$ten, "twenty": $$twenty, "grp": 14, "agg_sum": $$1229})] project: [$$10241, $$twenty, $$ten, $$four, $$two]
                     -- ASSIGN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$10229]  |PARTITIONED|
-                                {
+                        group by ([$$twenty := $$10229]) decor ([$$two := $$717; $$four := $$718; $$ten := $$719]) {
+                                  aggregate [$$1229] <- [agg-global-sql-sum($$10228)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$10229]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$10229]  |PARTITIONED|
-                            -- SORT_GROUP_BY[$$747]  |PARTITIONED|
-                                    {
+                            group by ([$$10229 := $$747]) decor ([$$717; $$718; $$719]) {
+                                      aggregate [$$10228] <- [agg-local-sql-sum($$666)]
                                       -- AGGREGATE  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- SORT_GROUP_BY[$$747]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$717, $$718, $$719, $$666, $$747] <- [null, null, null, $$tenk.getField(6), $$tenk.getField(5)] project: [$$717, $$718, $$719, $$666, $$747]
                                 -- ASSIGN  |PARTITIONED|
+                                  assign [$$tenk] <- [$$tenk] project: [$$tenk]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      replicate
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$tenk])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                              data-scan []<-[$$750, $$tenk] <- test.tenk
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$10242] <- [cast({"two": $$two, "four": $$four, "ten": $$ten, "twenty": $$twenty, "grp": 15, "agg_sum": $$1230})] project: [$$10242, $$twenty, $$ten, $$four, $$two]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$1230, $$two, $$four, $$ten, $$twenty])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- SORT_GROUP_BY[$$10231]  |PARTITIONED|
-                              {
+                      group by ([$$673 := $$10231]) decor ([$$two := $$720; $$four := $$721; $$ten := $$722; $$twenty := $$723]) {
+                                aggregate [$$1230] <- [agg-global-sql-sum($$10230)]
                                 -- AGGREGATE  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- SORT_GROUP_BY[$$10231]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$10231]  |PARTITIONED|
-                          -- SORT_GROUP_BY[$$748]  |PARTITIONED|
-                                  {
+                          group by ([$$10231 := $$748]) decor ([$$720; $$721; $$722; $$723]) {
+                                    aggregate [$$10230] <- [agg-local-sql-sum($$679)]
                                     -- AGGREGATE  |LOCAL|
+                                      nested tuple source
                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
+                                 }
+                          -- SORT_GROUP_BY[$$748]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$748, $$720, $$721, $$722, $$723, $$679] <- [true, null, null, null, null, $$tenk.getField(6)] project: [$$748, $$720, $$721, $$722, $$723, $$679]
                               -- ASSIGN  |PARTITIONED|
+                                assign [$$tenk] <- [$$tenk] project: [$$tenk]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        project ([$$tenk])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                                            data-scan []<-[$$750, $$tenk] <- test.tenk
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/listify-3.1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/listify-3.1.plan
index d28f82a..dddf48d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/listify-3.1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/listify-3.1.plan
@@ -1,36 +1,72 @@
+distribute result [$$142]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$142] <- [{"std": round-half-to-even(sqrt($$143), 2)}] project: [$$142]
     -- ASSIGN  |LOCAL|
+      aggregate [$$143] <- [agg-global-sql-avg($$164)]
       -- AGGREGATE  |LOCAL|
+        aggregate [$$164] <- [agg-local-sql-avg($$140)]
         -- AGGREGATE  |LOCAL|
+          assign [$$140] <- [power(numeric-subtract(numeric-add(numeric-subtract($$150, $$t), $$151), 1), 2)] project: [$$140]
           -- ASSIGN  |LOCAL|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+              join (true)
               -- NESTED_LOOP  |LOCAL|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                  join (true)
                   -- NESTED_LOOP  |LOCAL|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                      unnest $$t <- range(1, 10)
                       -- UNNEST  |UNPARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                      assign [$$150] <- [get-item($$111, 0).getField(0)] project: [$$150]
                       -- ASSIGN  |LOCAL|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                          replicate
                           -- REPLICATE  |LOCAL|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                              aggregate [$$111] <- [listify($$110)]
                               -- AGGREGATE  |LOCAL|
+                                assign [$$110] <- [{"mean": $$156, "min": $$157}] project: [$$110]
                                 -- ASSIGN  |LOCAL|
+                                  aggregate [$$156, $$157] <- [agg-global-sql-avg($$162), agg-global-sql-min($$163)]
                                   -- AGGREGATE  |LOCAL|
+                                    aggregate [$$162, $$163] <- [agg-local-sql-avg($$149), agg-local-sql-min($$149)]
                                     -- AGGREGATE  |LOCAL|
+                                      unnest $$149 <- range(1, 10)
                                       -- UNNEST  |UNPARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                  assign [$$151] <- [get-item($$127, 0).getField(1)] project: [$$151]
                   -- ASSIGN  |LOCAL|
+                    assign [$$127] <- [$$111] project: [$$127]
                     -- ASSIGN  |LOCAL|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                        replicate
                         -- REPLICATE  |LOCAL|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                            aggregate [$$111] <- [listify($$110)]
                             -- AGGREGATE  |LOCAL|
+                              assign [$$110] <- [{"mean": $$156, "min": $$157}] project: [$$110]
                               -- ASSIGN  |LOCAL|
+                                aggregate [$$156, $$157] <- [agg-global-sql-avg($$162), agg-global-sql-min($$163)]
                                 -- AGGREGATE  |LOCAL|
+                                  aggregate [$$162, $$163] <- [agg-local-sql-avg($$149), agg-local-sql-min($$149)]
                                   -- AGGREGATE  |LOCAL|
+                                    unnest $$149 <- range(1, 10)
                                     -- UNNEST  |UNPARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/sugar-06-distinct.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/sugar-06-distinct.plan
index a33ef53..23c3e27 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/sugar-06-distinct.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/group-by/sugar-06-distinct.plan
@@ -1,25 +1,47 @@
+distribute result [$$56]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 3
     -- STREAM_LIMIT  |UNPARTITIONED|
+      assign [$$56] <- [{"deptno": $$deptno, "salary_agg": $$59}] project: [$$56]
       -- ASSIGN  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$59(DESC) ]  |PARTITIONED|
+          limit 3
           -- STREAM_LIMIT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (topK: 3) (DESC, $$59)
               -- STABLE_SORT [topK: 3] [$$59(DESC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- PRE_CLUSTERED_GROUP_BY[$$57]  |PARTITIONED|
-                          {
+                  group by ([$$deptno := $$57]) decor ([]) {
+                            aggregate [$$59] <- [agg-sql-max($$53)]
                             -- AGGREGATE  |LOCAL|
+                              distinct ([$$53])
                               -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                                order (ASC, $$53)
                                 -- MICRO_STABLE_SORT [$$53(ASC)]  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                          }
+                         }
+                  -- PRE_CLUSTERED_GROUP_BY[$$57]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$57)
                       -- STABLE_SORT [$$57(ASC)]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
+                          assign [$$53, $$57] <- [$$e.getField("salary"), $$e.getField("deptno")] project: [$$53, $$57]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$e])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (gby.Employee)  |PARTITIONED|
+                                data-scan []<-[$$58, $$e] <- gby.Employee
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hash-join-with-redundant-variable/hash-join-with-redundant-variable.1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hash-join-with-redundant-variable/hash-join-with-redundant-variable.1.plan
index 4ee9d7f..f82a9aa 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hash-join-with-redundant-variable/hash-join-with-redundant-variable.1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hash-join-with-redundant-variable/hash-join-with-redundant-variable.1.plan
@@ -1,67 +1,134 @@
+distribute result [$$131]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    aggregate [$$131] <- [agg-sql-sum($$141)]
     -- AGGREGATE  |UNPARTITIONED|
+      exchange
       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+        aggregate [$$141] <- [agg-sql-count(1)]
         -- AGGREGATE  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (and(eq($$134, $$135), eq($$123, $$124)))
             -- HYBRID_HASH_JOIN [$$134, $$124][$$135, $$123]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$134, $$124]  |PARTITIONED|
+                project ([$$124, $$134])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$138, $$139))
                     -- HYBRID_HASH_JOIN [$$139][$$138]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$139]  |PARTITIONED|
+                        project ([$$124, $$139])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (eq($$122, $$124))
                             -- HYBRID_HASH_JOIN [$$124][$$122]  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$124]  |PARTITIONED|
+                                project ([$$124])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (eq($$136, $$137))
                                     -- HYBRID_HASH_JOIN [$$137][$$136]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$137]  |PARTITIONED|
+                                        select (eq($$r.getField("r_name"), "EUROPE")) project: [$$137]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$137] <- [$$r.getField("r_regionkey")]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$r])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.region)  |PARTITIONED|
+                                                data-scan []<-[$$125, $$r] <- test.region
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$136]  |PARTITIONED|
+                                        assign [$$124, $$136] <- [$$n.getField("n_nationkey"), $$n.getField("n_regionkey")] project: [$$124, $$136]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$n])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                              data-scan []<-[$$126, $$n] <- test.nation
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$122]  |PARTITIONED|
+                                project ([$$122, $$139])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (eq($$132, $$133))
                                     -- HYBRID_HASH_JOIN [$$132][$$133]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$132]  |PARTITIONED|
+                                        assign [$$122, $$132] <- [$$c.getField("c_nationkey"), $$c.getField("c_custkey")] project: [$$122, $$132]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$c])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.customer)  |PARTITIONED|
+                                              data-scan []<-[$$127, $$c] <- test.customer
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$133]  |PARTITIONED|
+                                        select (and(ge($$121, "1993-01-01"), lt($$121, "1993-04-01"))) project: [$$139, $$133]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$139, $$133, $$121] <- [$$o.getField("o_orderkey"), $$o.getField("o_custkey"), $$o.getField("o_orderdate")] project: [$$139, $$133, $$121]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$o])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                data-scan []<-[$$128, $$o] <- test.orders
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$138]  |PARTITIONED|
+                        assign [$$134, $$138] <- [$$l.getField("l_suppkey"), $$l.getField("l_orderkey")] project: [$$134, $$138]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$l])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.lineitem)  |PARTITIONED|
+                              data-scan []<-[$$129, $$l] <- test.lineitem
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$135, $$123]  |PARTITIONED|
+                assign [$$135, $$123] <- [$$s.getField("s_suppkey"), $$s.getField("s_nationkey")] project: [$$135, $$123]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$s])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                      data-scan []<-[$$130, $$s] <- test.supplier
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hash-join-with-redundant-variable/hash-join-with-redundant-variable.2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hash-join-with-redundant-variable/hash-join-with-redundant-variable.2.plan
index f995ac2..91ae5c9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hash-join-with-redundant-variable/hash-join-with-redundant-variable.2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hash-join-with-redundant-variable/hash-join-with-redundant-variable.2.plan
@@ -1,32 +1,64 @@
+distribute result [$$73]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    aggregate [$$73] <- [agg-sql-sum($$74)]
     -- AGGREGATE  |UNPARTITIONED|
+      exchange
       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+        aggregate [$$74] <- [agg-sql-count(1)]
         -- AGGREGATE  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$69, $$67))
             -- HYBRID_HASH_JOIN [$$69][$$67]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$69])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$68, $$69))
                     -- HYBRID_HASH_JOIN [$$69][$$68]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$69]  |PARTITIONED|
+                        assign [$$69] <- [$$r.getField("x")] project: [$$69]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$r])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.region)  |PARTITIONED|
+                              data-scan []<-[$$70, $$r] <- test.region
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$68]  |PARTITIONED|
+                        assign [$$68] <- [$$o.getField("x")] project: [$$68]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$o])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                              data-scan []<-[$$71, $$o] <- test.orders
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$67]  |PARTITIONED|
+                assign [$$67] <- [$$n.getField("x")] project: [$$67]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$n])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                      data-scan []<-[$$72, $$n] <- test.nation
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hash-join-with-redundant-variable/hash-join-with-redundant-variable.3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hash-join-with-redundant-variable/hash-join-with-redundant-variable.3.plan
index 8f0ea7c..bf34a02 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hash-join-with-redundant-variable/hash-join-with-redundant-variable.3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hash-join-with-redundant-variable/hash-join-with-redundant-variable.3.plan
@@ -1,32 +1,64 @@
+distribute result [$$76]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    aggregate [$$76] <- [agg-sql-sum($$77)]
     -- AGGREGATE  |UNPARTITIONED|
+      exchange
       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+        aggregate [$$77] <- [agg-sql-count(1)]
         -- AGGREGATE  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$70, $$72))
             -- HYBRID_HASH_JOIN [$$72][$$70]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$72])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$71, $$72))
                     -- HYBRID_HASH_JOIN [$$71][$$72]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$71]  |PARTITIONED|
+                        assign [$$71] <- [$$r.getField("x")] project: [$$71]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$r])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.region)  |PARTITIONED|
+                              data-scan []<-[$$73, $$r] <- test.region
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$72]  |PARTITIONED|
+                        assign [$$72] <- [$$n.getField("x")] project: [$$72]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$n])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                              data-scan []<-[$$74, $$n] <- test.nation
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$70]  |PARTITIONED|
+                assign [$$70] <- [$$o.getField("x")] project: [$$70]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$o])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                      data-scan []<-[$$75, $$o] <- test.orders
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hash-join-with-redundant-variable/hash-join-with-redundant-variable.4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hash-join-with-redundant-variable/hash-join-with-redundant-variable.4.plan
index 4d8bf76..4d016d5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hash-join-with-redundant-variable/hash-join-with-redundant-variable.4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hash-join-with-redundant-variable/hash-join-with-redundant-variable.4.plan
@@ -1,22 +1,44 @@
+distribute result [$$57]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    aggregate [$$57] <- [agg-sql-sum($$58)]
     -- AGGREGATE  |UNPARTITIONED|
+      exchange
       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+        aggregate [$$58] <- [agg-sql-count(1)]
         -- AGGREGATE  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (and(eq($$52, $$55), eq($$59, $$56)))
             -- HYBRID_HASH_JOIN [$$52, $$59][$$55, $$56]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$52, $$59]  |PARTITIONED|
+                assign [$$59] <- [$$52]
                 -- ASSIGN  |PARTITIONED|
+                  assign [$$52] <- [$$r.getField("x")] project: [$$52]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$r])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.region)  |PARTITIONED|
+                        data-scan []<-[$$53, $$r] <- test.region
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$55, $$56]  |PARTITIONED|
+                assign [$$56, $$55] <- [$$o.getField("x"), $$o.getField("y")] project: [$$56, $$55]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$o])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                      data-scan []<-[$$54, $$o] <- test.orders
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_1.plan
index 5467122..bbb7d40 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_1.plan
@@ -1,20 +1,40 @@
+distribute result [$$38]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$38] <- [{"c0": $$47, "c1": $$48}] project: [$$38]
     -- ASSIGN  |PARTITIONED|
+      project ([$$47, $$48])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (and(eq($$41, $$42), eq($$43, $$44), eq($$45, $$46)))
           -- HYBRID_HASH_JOIN [$$41, $$43, $$45][$$42, $$44, $$46]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              assign [$$47, $$45, $$43, $$41] <- [$$t1.getField(4), $$t1.getField(1), $$t1.getField(3), $$t1.getField(2)] project: [$$47, $$41, $$43, $$45]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t1])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+                    data-scan []<-[$$39, $$t1] <- test.t1
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- BROADCAST_EXCHANGE  |PARTITIONED|
+              assign [$$48, $$46, $$44, $$42] <- [$$t2.getField(4), $$t2.getField(1), $$t2.getField(3), $$t2.getField(2)] project: [$$48, $$42, $$44, $$46]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t2])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.t2)  |PARTITIONED|
+                    data-scan []<-[$$40, $$t2] <- test.t2
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_2.plan
index 5467122..bbb7d40 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_2.plan
@@ -1,20 +1,40 @@
+distribute result [$$38]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$38] <- [{"c0": $$47, "c1": $$48}] project: [$$38]
     -- ASSIGN  |PARTITIONED|
+      project ([$$47, $$48])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (and(eq($$41, $$42), eq($$43, $$44), eq($$45, $$46)))
           -- HYBRID_HASH_JOIN [$$41, $$43, $$45][$$42, $$44, $$46]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              assign [$$47, $$45, $$43, $$41] <- [$$t1.getField(4), $$t1.getField(1), $$t1.getField(3), $$t1.getField(2)] project: [$$47, $$41, $$43, $$45]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t1])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+                    data-scan []<-[$$39, $$t1] <- test.t1
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- BROADCAST_EXCHANGE  |PARTITIONED|
+              assign [$$48, $$46, $$44, $$42] <- [$$t2.getField(4), $$t2.getField(1), $$t2.getField(3), $$t2.getField(2)] project: [$$48, $$42, $$44, $$46]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t2])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.t2)  |PARTITIONED|
+                    data-scan []<-[$$40, $$t2] <- test.t2
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_3.plan
index 98e6696..980b156 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_3.plan
@@ -1,20 +1,40 @@
+distribute result [$$38]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$38] <- [{"c0": $$47, "c1": $$48}] project: [$$38]
     -- ASSIGN  |PARTITIONED|
+      project ([$$47, $$48])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (and(eq($$41, $$42), eq($$43, $$44), eq($$45, $$46)))
           -- HYBRID_HASH_JOIN [$$41, $$44, $$45][$$42, $$43, $$46]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              assign [$$47, $$45, $$44, $$41] <- [$$t1.getField(4), $$t1.getField(1), $$t1.getField(3), $$t1.getField(2)] project: [$$47, $$41, $$44, $$45]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t1])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+                    data-scan []<-[$$39, $$t1] <- test.t1
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- BROADCAST_EXCHANGE  |PARTITIONED|
+              assign [$$48, $$46, $$43, $$42] <- [$$t2.getField(4), $$t2.getField(1), $$t2.getField(3), $$t2.getField(2)] project: [$$48, $$42, $$43, $$46]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t2])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.t2)  |PARTITIONED|
+                    data-scan []<-[$$40, $$t2] <- test.t2
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_4.plan
index 6848ad7..7fdd2d1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_4.plan
@@ -1,31 +1,62 @@
+distribute result [$$78]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$78] <- [{"$1": $$82}] project: [$$78]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$82] <- [agg-sql-sum($$87)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$87] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$85, $$86))
               -- HYBRID_HASH_JOIN [$$86][$$85]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  assign [$$86] <- [$$o.getField("o_custkey")] project: [$$86]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$o])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (tpch.orders)  |PARTITIONED|
+                        data-scan []<-[$$79, $$o] <- tpch.orders
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  assign [$$85] <- [{"c": $$c, "n": $$n}.getField("c_custkey")] project: [$$85]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$c, $$n])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$83, $$81))
                         -- HYBRID_HASH_JOIN [$$83][$$81]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$83]  |PARTITIONED|
+                            assign [$$83] <- [$$c.getField("c_nationkey")]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$c])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (tpch.customer)  |PARTITIONED|
+                                  data-scan []<-[$$80, $$c] <- tpch.customer
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$81]  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.nation)  |PARTITIONED|
+                            data-scan []<-[$$81, $$n] <- tpch.nation
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_5.plan
index 6c1b9e2..f11dcb8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_5.plan
@@ -1,31 +1,62 @@
+distribute result [$$78]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$78] <- [{"$1": $$82}] project: [$$78]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$82] <- [agg-sql-sum($$87)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$87] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$85, $$86))
               -- HYBRID_HASH_JOIN [$$85][$$86]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  assign [$$85] <- [{"c": $$c, "n": $$n}.getField("c_custkey")] project: [$$85]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$c, $$n])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$83, $$81))
                         -- HYBRID_HASH_JOIN [$$83][$$81]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$83]  |PARTITIONED|
+                            assign [$$83] <- [$$c.getField("c_nationkey")]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$c])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (tpch.customer)  |PARTITIONED|
+                                  data-scan []<-[$$80, $$c] <- tpch.customer
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$81]  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.nation)  |PARTITIONED|
+                            data-scan []<-[$$81, $$n] <- tpch.nation
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  assign [$$86] <- [$$o.getField("o_custkey")] project: [$$86]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$o])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (tpch.orders)  |PARTITIONED|
+                        data-scan []<-[$$79, $$o] <- tpch.orders
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_6.plan
index 6848ad7..7fdd2d1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_6.plan
@@ -1,31 +1,62 @@
+distribute result [$$78]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$78] <- [{"$1": $$82}] project: [$$78]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$82] <- [agg-sql-sum($$87)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$87] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$85, $$86))
               -- HYBRID_HASH_JOIN [$$86][$$85]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  assign [$$86] <- [$$o.getField("o_custkey")] project: [$$86]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$o])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (tpch.orders)  |PARTITIONED|
+                        data-scan []<-[$$79, $$o] <- tpch.orders
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  assign [$$85] <- [{"c": $$c, "n": $$n}.getField("c_custkey")] project: [$$85]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$c, $$n])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$83, $$81))
                         -- HYBRID_HASH_JOIN [$$83][$$81]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$83]  |PARTITIONED|
+                            assign [$$83] <- [$$c.getField("c_nationkey")]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$c])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (tpch.customer)  |PARTITIONED|
+                                  data-scan []<-[$$80, $$c] <- tpch.customer
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$81]  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.nation)  |PARTITIONED|
+                            data-scan []<-[$$81, $$n] <- tpch.nation
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_7.plan
index 6848ad7..7fdd2d1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/broadcast_join_hint/broadcast_join_hint_7.plan
@@ -1,31 +1,62 @@
+distribute result [$$78]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$78] <- [{"$1": $$82}] project: [$$78]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$82] <- [agg-sql-sum($$87)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$87] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$85, $$86))
               -- HYBRID_HASH_JOIN [$$86][$$85]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  assign [$$86] <- [$$o.getField("o_custkey")] project: [$$86]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$o])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (tpch.orders)  |PARTITIONED|
+                        data-scan []<-[$$79, $$o] <- tpch.orders
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  assign [$$85] <- [{"c": $$c, "n": $$n}.getField("c_custkey")] project: [$$85]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$c, $$n])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$83, $$81))
                         -- HYBRID_HASH_JOIN [$$83][$$81]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$83]  |PARTITIONED|
+                            assign [$$83] <- [$$c.getField("c_nationkey")]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$c])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (tpch.customer)  |PARTITIONED|
+                                  data-scan []<-[$$80, $$c] <- tpch.customer
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$81]  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.nation)  |PARTITIONED|
+                            data-scan []<-[$$81, $$n] <- tpch.nation
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_1.plan
index a27f96b..efea9db 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_1.plan
@@ -1,31 +1,62 @@
+distribute result [$$78]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$78] <- [{"$1": $$82}] project: [$$78]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$82] <- [agg-sql-sum($$87)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$87] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$85, $$86))
               -- HYBRID_HASH_JOIN [$$85][$$86]  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                  assign [$$85] <- [{"c": $$c, "n": $$n}.getField("c_custkey")] project: [$$85]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$c, $$n])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$83, $$81))
                         -- HYBRID_HASH_JOIN [$$83][$$81]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$83]  |PARTITIONED|
+                            assign [$$83] <- [$$c.getField("c_nationkey")]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$c])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (tpch.customer)  |PARTITIONED|
+                                  data-scan []<-[$$80, $$c] <- tpch.customer
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$81]  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.nation)  |PARTITIONED|
+                            data-scan []<-[$$81, $$n] <- tpch.nation
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$86]  |PARTITIONED|
+                  assign [$$86] <- [$$o.getField("o_custkey")] project: [$$86]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$o])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (tpch.orders)  |PARTITIONED|
+                        data-scan []<-[$$79, $$o] <- tpch.orders
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_2.plan
index d495188..1826f6c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_2.plan
@@ -1,31 +1,62 @@
+distribute result [$$78]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$78] <- [{"$1": $$82}] project: [$$78]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$82] <- [agg-sql-sum($$87)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$87] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$85, $$86))
               -- HYBRID_HASH_JOIN [$$86][$$85]  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$86]  |PARTITIONED|
+                  assign [$$86] <- [$$o.getField("o_custkey")] project: [$$86]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$o])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (tpch.orders)  |PARTITIONED|
+                        data-scan []<-[$$79, $$o] <- tpch.orders
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                  assign [$$85] <- [{"c": $$c, "n": $$n}.getField("c_custkey")] project: [$$85]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$c, $$n])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$83, $$81))
                         -- HYBRID_HASH_JOIN [$$83][$$81]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$83]  |PARTITIONED|
+                            assign [$$83] <- [$$c.getField("c_nationkey")]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$c])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (tpch.customer)  |PARTITIONED|
+                                  data-scan []<-[$$80, $$c] <- tpch.customer
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$81]  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.nation)  |PARTITIONED|
+                            data-scan []<-[$$81, $$n] <- tpch.nation
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_3.plan
index d495188..1826f6c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_3.plan
@@ -1,31 +1,62 @@
+distribute result [$$78]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$78] <- [{"$1": $$82}] project: [$$78]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$82] <- [agg-sql-sum($$87)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$87] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$85, $$86))
               -- HYBRID_HASH_JOIN [$$86][$$85]  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$86]  |PARTITIONED|
+                  assign [$$86] <- [$$o.getField("o_custkey")] project: [$$86]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$o])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (tpch.orders)  |PARTITIONED|
+                        data-scan []<-[$$79, $$o] <- tpch.orders
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                  assign [$$85] <- [{"c": $$c, "n": $$n}.getField("c_custkey")] project: [$$85]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$c, $$n])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$83, $$81))
                         -- HYBRID_HASH_JOIN [$$83][$$81]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$83]  |PARTITIONED|
+                            assign [$$83] <- [$$c.getField("c_nationkey")]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$c])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (tpch.customer)  |PARTITIONED|
+                                  data-scan []<-[$$80, $$c] <- tpch.customer
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$81]  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.nation)  |PARTITIONED|
+                            data-scan []<-[$$81, $$n] <- tpch.nation
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_4.plan
index d495188..1826f6c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_4.plan
@@ -1,31 +1,62 @@
+distribute result [$$78]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$78] <- [{"$1": $$82}] project: [$$78]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$82] <- [agg-sql-sum($$87)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$87] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$85, $$86))
               -- HYBRID_HASH_JOIN [$$86][$$85]  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$86]  |PARTITIONED|
+                  assign [$$86] <- [$$o.getField("o_custkey")] project: [$$86]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$o])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (tpch.orders)  |PARTITIONED|
+                        data-scan []<-[$$79, $$o] <- tpch.orders
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                  assign [$$85] <- [{"c": $$c, "n": $$n}.getField("c_custkey")] project: [$$85]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$c, $$n])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$83, $$81))
                         -- HYBRID_HASH_JOIN [$$83][$$81]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$83]  |PARTITIONED|
+                            assign [$$83] <- [$$c.getField("c_nationkey")]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$c])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (tpch.customer)  |PARTITIONED|
+                                  data-scan []<-[$$80, $$c] <- tpch.customer
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$81]  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.nation)  |PARTITIONED|
+                            data-scan []<-[$$81, $$n] <- tpch.nation
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_5.plan
index a27f96b..efea9db 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_5.plan
@@ -1,31 +1,62 @@
+distribute result [$$78]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$78] <- [{"$1": $$82}] project: [$$78]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$82] <- [agg-sql-sum($$87)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$87] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$85, $$86))
               -- HYBRID_HASH_JOIN [$$85][$$86]  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                  assign [$$85] <- [{"c": $$c, "n": $$n}.getField("c_custkey")] project: [$$85]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$c, $$n])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$83, $$81))
                         -- HYBRID_HASH_JOIN [$$83][$$81]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$83]  |PARTITIONED|
+                            assign [$$83] <- [$$c.getField("c_nationkey")]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$c])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (tpch.customer)  |PARTITIONED|
+                                  data-scan []<-[$$80, $$c] <- tpch.customer
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$81]  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.nation)  |PARTITIONED|
+                            data-scan []<-[$$81, $$n] <- tpch.nation
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$86]  |PARTITIONED|
+                  assign [$$86] <- [$$o.getField("o_custkey")] project: [$$86]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$o])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (tpch.orders)  |PARTITIONED|
+                        data-scan []<-[$$79, $$o] <- tpch.orders
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_6.plan
index a27f96b..efea9db 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/hints/hashjoin_hint/hashjoin_hint_6.plan
@@ -1,31 +1,62 @@
+distribute result [$$78]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$78] <- [{"$1": $$82}] project: [$$78]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$82] <- [agg-sql-sum($$87)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$87] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$85, $$86))
               -- HYBRID_HASH_JOIN [$$85][$$86]  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                  assign [$$85] <- [{"c": $$c, "n": $$n}.getField("c_custkey")] project: [$$85]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$c, $$n])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$83, $$81))
                         -- HYBRID_HASH_JOIN [$$83][$$81]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$83]  |PARTITIONED|
+                            assign [$$83] <- [$$c.getField("c_nationkey")]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$c])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (tpch.customer)  |PARTITIONED|
+                                  data-scan []<-[$$80, $$c] <- tpch.customer
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$81]  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.nation)  |PARTITIONED|
+                            data-scan []<-[$$81, $$n] <- tpch.nation
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$86]  |PARTITIONED|
+                  assign [$$86] <- [$$o.getField("o_custkey")] project: [$$86]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$o])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (tpch.orders)  |PARTITIONED|
+                        data-scan []<-[$$79, $$o] <- tpch.orders
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.1.plan
index 788e6be..e12205d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.1.plan
@@ -1,17 +1,34 @@
+distribute result [$$28]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$28] <- [{"U": $$U, "augmentedUser": $$34}] project: [$$28]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$34.getField("name"), "Glenn"))
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$34] <- [object-add($$U, "favoriteColor", "Green")]
         -- ASSIGN  |PARTITIONED|
+          project ([$$U])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- BTREE_SEARCH (test.Users.Users)  |PARTITIONED|
+              unnest-map [$$29, $$U] <- index-search("Users", 0, "Default", "test", "Users", false, false, 1, $$38, 1, $$38, true, true, true)
+              -- BTREE_SEARCH  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$38)
                   -- STABLE_SORT [$$38(ASC)]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$38])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.Users.usersNameIdx)  |PARTITIONED|
+                          unnest-map [$$37, $$38] <- index-search("usersNameIdx", 0, "Default", "test", "Users", false, false, 1, $$35, 1, $$36, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$35, $$36] <- ["Glenn", "Glenn"]
                               -- ASSIGN  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.10.plan
index 21527cf..0e71c72 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.10.plan
@@ -1,19 +1,38 @@
+distribute result [$$83]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$83] <- [{"U1": $$U1, "U2": $$U2, "augmentedUser1": $$101, "augmentedUser2": $$102, "augmentedUser3": object-add($$102, "favoriteColor", "Red"), "augmentedUser4": object-add(object-add($$102, "favoriteColor", "Red"), "favoriteDrink", "Wine")}] project: [$$83]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$102.getField("name"), "Sally"))
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$102] <- [object-add($$U2, "favoriteFood", "Pizza")]
         -- ASSIGN  |PARTITIONED|
+          project ([$$U1, $$101, $$U2])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- BTREE_SEARCH (test.Users.Users)  |PARTITIONED|
+              unnest-map [$$85, $$U2] <- index-search("Users", 0, "Default", "test", "Users", true, true, 1, $$86, 1, $$86, true, true, true)
+              -- BTREE_SEARCH  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$86)
                   -- STABLE_SORT [$$86(ASC)]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$86]  |PARTITIONED|
+                      assign [$$86] <- [to-bigint($$U1.getField("bestFriend"))]
                       -- ASSIGN  |PARTITIONED|
+                        select (eq($$101.getField("name"), "John"))
                         -- STREAM_SELECT  |PARTITIONED|
+                          assign [$$101] <- [object-add($$U1, "favoriteColor", "Green")]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$U1])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.Users)  |PARTITIONED|
+                                data-scan []<-[$$84, $$U1] <- test.Users
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.11.plan
index 9063fe5..c9ae8a3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.11.plan
@@ -1,35 +1,70 @@
+distribute result [$$63]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    union ($$86, $$87, $$63)
     -- UNION_ALL  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        assign [$$86] <- [cast(to-object-var-str($$84))] project: [$$86]
         -- ASSIGN  |PARTITIONED|
+          select (eq($$84.getField(1).getField(0), "Glenn"))
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$84] <- [object-add($$U1, "favoriteColor", "Green")] project: [$$84]
             -- ASSIGN  |PARTITIONED|
+              project ([$$U1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.Users.Users)  |PARTITIONED|
+                  unnest-map [$$64, $$U1] <- index-search("Users", 0, "Default", "test", "Users", false, false, 1, $$79, 1, $$79, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$79)
                       -- STABLE_SORT [$$79(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$79])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.Users.firstUsersNameIdx)  |PARTITIONED|
+                              unnest-map [$$78, $$79] <- index-search("firstUsersNameIdx", 0, "Default", "test", "Users", false, false, 1, $$76, 1, $$77, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$76, $$77] <- ["Glenn", "Glenn"]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        assign [$$87] <- [cast(to-object-var-str($$85))] project: [$$87]
         -- ASSIGN  |PARTITIONED|
+          select (eq($$85.getField(1).getField("last"), "John"))
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$85] <- [object-add($$U2, "favoriteFood", "Pizza")] project: [$$85]
             -- ASSIGN  |PARTITIONED|
+              project ([$$U2])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.Users.Users)  |PARTITIONED|
+                  unnest-map [$$65, $$U2] <- index-search("Users", 0, "Default", "test", "Users", false, false, 1, $$83, 1, $$83, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$83)
                       -- STABLE_SORT [$$83(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$83])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.Users.lastUsersNameIdx)  |PARTITIONED|
+                              unnest-map [$$82, $$83] <- index-search("lastUsersNameIdx", 0, "Default", "test", "Users", false, false, 1, $$80, 1, $$81, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$80, $$81] <- ["John", "John"]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.2.plan
index 9df9cda..ddb4197 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.2.plan
@@ -1,17 +1,34 @@
+distribute result [$$40]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$40] <- [{"U": $$U, "augmentedUser1": $$52, "augmentedUser2": object-add($$52, "favoriteCity", "Irvine")}] project: [$$40]
     -- ASSIGN  |PARTITIONED|
+      select (eq(object-add($$52, "favoriteCity", "Irvine").getField("name"), "Glenn"))
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$52] <- [object-add($$U, "favoriteColor", "Green")]
         -- ASSIGN  |PARTITIONED|
+          project ([$$U])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- BTREE_SEARCH (test.Users.Users)  |PARTITIONED|
+              unnest-map [$$41, $$U] <- index-search("Users", 0, "Default", "test", "Users", false, false, 1, $$51, 1, $$51, true, true, true)
+              -- BTREE_SEARCH  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$51)
                   -- STABLE_SORT [$$51(ASC)]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$51])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.Users.usersNameIdx)  |PARTITIONED|
+                          unnest-map [$$50, $$51] <- index-search("usersNameIdx", 0, "Default", "test", "Users", false, false, 1, $$48, 1, $$49, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$48, $$49] <- ["Glenn", "Glenn"]
                               -- ASSIGN  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.3.plan
index 9014a67..fcb6053 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.3.plan
@@ -1,17 +1,34 @@
+distribute result [$$29]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"U": $$U, "augmentedUser": $$36}] project: [$$29]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$36.getField("name").getField("first"), "Glenn"))
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$36] <- [object-add($$U, "favoriteColor", "Green")]
         -- ASSIGN  |PARTITIONED|
+          project ([$$U])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- BTREE_SEARCH (test.Users.Users)  |PARTITIONED|
+              unnest-map [$$30, $$U] <- index-search("Users", 0, "Default", "test", "Users", false, false, 1, $$40, 1, $$40, true, true, true)
+              -- BTREE_SEARCH  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$40)
                   -- STABLE_SORT [$$40(ASC)]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$40])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.Users.usersNameIdx)  |PARTITIONED|
+                          unnest-map [$$39, $$40] <- index-search("usersNameIdx", 0, "Default", "test", "Users", false, false, 1, $$37, 1, $$38, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$37, $$38] <- ["Glenn", "Glenn"]
                               -- ASSIGN  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.4.plan
index 788e6be..8f14f78 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.4.plan
@@ -1,17 +1,34 @@
+distribute result [$$28]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$28] <- [{"U": $$U, "augmentedUser": $$34}] project: [$$28]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$34.getField("name"), "Glenn"))
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$34] <- [object-remove($$U, "favoriteColor")]
         -- ASSIGN  |PARTITIONED|
+          project ([$$U])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- BTREE_SEARCH (test.Users.Users)  |PARTITIONED|
+              unnest-map [$$29, $$U] <- index-search("Users", 0, "Default", "test", "Users", false, false, 1, $$38, 1, $$38, true, true, true)
+              -- BTREE_SEARCH  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$38)
                   -- STABLE_SORT [$$38(ASC)]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$38])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.Users.usersNameIdx)  |PARTITIONED|
+                          unnest-map [$$37, $$38] <- index-search("usersNameIdx", 0, "Default", "test", "Users", false, false, 1, $$35, 1, $$36, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$35, $$36] <- ["Glenn", "Glenn"]
                               -- ASSIGN  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.5.plan
index 52a0cb5..82b31dc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.5.plan
@@ -1,10 +1,20 @@
+distribute result [$$28]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$28] <- [{"U": $$U, "augmentedUser": $$34}] project: [$$28]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$34.getField(1), "Glenn"))
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$34] <- [object-put($$U, "name", "John")]
         -- ASSIGN  |PARTITIONED|
+          project ([$$U])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Users)  |PARTITIONED|
+              data-scan []<-[$$29, $$U] <- test.Users
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.6.plan
index 3a8b302..c77047a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.6.plan
@@ -1,19 +1,38 @@
+distribute result [$$59]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$59] <- [{"U1": $$U1, "U2": $$U2, "augmentedUser1": $$76, "augmentedUser2": $$77}] project: [$$59]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$77.getField("name"), "Sally"))
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$77] <- [object-add($$U2, "favoriteFood", "Pizza")]
         -- ASSIGN  |PARTITIONED|
+          project ([$$U1, $$76, $$U2])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- BTREE_SEARCH (test.Users.Users)  |PARTITIONED|
+              unnest-map [$$61, $$U2] <- index-search("Users", 0, "Default", "test", "Users", true, true, 1, $$62, 1, $$62, true, true, true)
+              -- BTREE_SEARCH  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$62)
                   -- STABLE_SORT [$$62(ASC)]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                      assign [$$62] <- [to-bigint($$U1.getField("bestFriend"))]
                       -- ASSIGN  |PARTITIONED|
+                        select (eq($$76.getField("name"), "John"))
                         -- STREAM_SELECT  |PARTITIONED|
+                          assign [$$76] <- [object-add($$U1, "favoriteColor", "Green")]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$U1])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.Users)  |PARTITIONED|
+                                data-scan []<-[$$60, $$U1] <- test.Users
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.7.plan
index 52a0cb5..bcef379 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.7.plan
@@ -1,10 +1,20 @@
+distribute result [$$29]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"U": $$U, "augmentedUser": $$35}] project: [$$29]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$35.getField("firstName"), "Glenn"))
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$35] <- [object-add(object-remove($$U, "name"), "name", "Glenn")]
         -- ASSIGN  |PARTITIONED|
+          project ([$$U])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Users)  |PARTITIONED|
+              data-scan []<-[$$30, $$U] <- test.Users
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.8.plan
index 9014a67..2bd78fc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.8.plan
@@ -1,17 +1,34 @@
+distribute result [$$30]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$30] <- [{"U": $$U, "augmentedUser": $$36}] project: [$$30]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$36.getField("name"), "Glenn"))
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$36] <- [object-concat({ "favoriteColor": "Green" }, $$U, { "birthdate": "10/09/1996" })]
         -- ASSIGN  |PARTITIONED|
+          project ([$$U])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- BTREE_SEARCH (test.Users.Users)  |PARTITIONED|
+              unnest-map [$$31, $$U] <- index-search("Users", 0, "Default", "test", "Users", false, false, 1, $$40, 1, $$40, true, true, true)
+              -- BTREE_SEARCH  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$40)
                   -- STABLE_SORT [$$40(ASC)]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$40])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.Users.usersNameIdx)  |PARTITIONED|
+                          unnest-map [$$39, $$40] <- index-search("usersNameIdx", 0, "Default", "test", "Users", false, false, 1, $$37, 1, $$38, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$37, $$38] <- ["Glenn", "Glenn"]
                               -- ASSIGN  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.9.plan
index a3cce2e..1ace4a8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.9.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/index-through-object/index-through-object.9.plan
@@ -1,38 +1,76 @@
+distribute result [$$85]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$85] <- [{"U1": $$U1, "U2": $$U2, "E1": { "name": "Glenn" }, "augmentedUser1": $$105, "augmentedUser2": $$107, "augmentedUser3": { "name": "Glenn", "favoriteColor": "Blue" }}] project: [$$85]
     -- ASSIGN  |PARTITIONED|
+      project ([$$U1, $$105, $$U2, $$107])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$88, $$89))
           -- HYBRID_HASH_JOIN [$$88][$$89]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$88]  |PARTITIONED|
+              assign [$$88] <- [$$105.getField("bestFriend")]
               -- ASSIGN  |PARTITIONED|
+                select (eq($$105.getField("name"), "John"))
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$105] <- [object-add($$U1, "favoriteColor", "Green")]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$U1])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Users.Users)  |PARTITIONED|
+                        unnest-map [$$86, $$U1] <- index-search("Users", 0, "Default", "test", "Users", false, false, 1, $$111, 1, $$111, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$111)
                             -- STABLE_SORT [$$111(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$111])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.Users.usersNameIdx)  |PARTITIONED|
+                                    unnest-map [$$110, $$111] <- index-search("usersNameIdx", 0, "Default", "test", "Users", false, false, 1, $$108, 1, $$109, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$108, $$109] <- ["John", "John"]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$89]  |PARTITIONED|
+              select (eq($$107.getField("name"), "Sally"))
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$89] <- [$$107.getField(0)]
                 -- ASSIGN  |PARTITIONED|
+                  assign [$$107] <- [object-add($$U2, "favoriteFood", "Pizza")]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$U2])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Users.Users)  |PARTITIONED|
+                        unnest-map [$$87, $$U2] <- index-search("Users", 0, "Default", "test", "Users", false, false, 1, $$115, 1, $$115, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$115)
                             -- STABLE_SORT [$$115(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$115])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.Users.usersNameIdx)  |PARTITIONED|
+                                    unnest-map [$$114, $$115] <- index-search("usersNameIdx", 0, "Default", "test", "Users", false, false, 1, $$112, 1, $$113, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$112, $$113] <- ["Sally", "Sally"]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inline-single-reference/inline-single-reference_1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inline-single-reference/inline-single-reference_1.plan
index 3745304..9c35527 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inline-single-reference/inline-single-reference_1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inline-single-reference/inline-single-reference_1.plan
@@ -1,12 +1,24 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"doc": $$40, "name": $$41, "uname": switch-case(true, not(is-unknown($$36)), $$36, null)}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      select (ge($$h.getField("ts"), "1999-03-02T08:04:57.750006+00:00")) project: [$$41, $$40, $$36]
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$36] <- [$$h.getField("uname")]
         -- ASSIGN  |PARTITIONED|
+          unnest $$h <- scan-collection($$38) project: [$$41, $$40, $$h]
           -- UNNEST  |PARTITIONED|
+            assign [$$41, $$40, $$38] <- [$$a.getField("name"), $$a.getField("doc"), $$a.getField("history")] project: [$$41, $$40, $$38]
             -- ASSIGN  |PARTITIONED|
+              project ([$$a])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+                  data-scan []<-[$$37, $$a] <- test.t1
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inline-single-reference/inline-single-reference_2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inline-single-reference/inline-single-reference_2.plan
index 3c9b8ec..69a4521 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inline-single-reference/inline-single-reference_2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inline-single-reference/inline-single-reference_2.plan
@@ -1,9 +1,18 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$18] <- [{"doc": $$a.getField("doc"), "name": $$a.getField("name")}] project: [$$18]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$a.getField("new"), 1))
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$a])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+            data-scan []<-[$$19, $$a] <- test.t1
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inline-single-reference/inline-single-reference_3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inline-single-reference/inline-single-reference_3.plan
index aa769d2..e51a701 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inline-single-reference/inline-single-reference_3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inline-single-reference/inline-single-reference_3.plan
@@ -1,10 +1,20 @@
+distribute result [$$16]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$16] <- [{"doc": $$a.getField("doc"), "name": $$a.getField("name")}] project: [$$16]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$18(ASC) ]  |PARTITIONED|
+          order (ASC, $$18)
           -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+              data-scan []<-[$$18, $$a] <- test.t1
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inline-single-reference/inline-single-reference_4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inline-single-reference/inline-single-reference_4.plan
index 30d22c2..647c467 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inline-single-reference/inline-single-reference_4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inline-single-reference/inline-single-reference_4.plan
@@ -1,23 +1,46 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"doc": $$38, "name": $$39}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      project ([$$38, $$39])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$33(ASC) ]  |PARTITIONED|
+          order (ASC, $$33)
           -- STABLE_SORT [$$33(ASC)]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$38, $$39, $$33])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$35, $$36))
                   -- HYBRID_HASH_JOIN [$$35][$$36]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+                      assign [$$38, $$35] <- [$$a.getField("doc"), $$a.getField("jn")] project: [$$38, $$33, $$35]
                       -- ASSIGN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+                          data-scan []<-[$$33, $$a] <- test.t1
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                      assign [$$39, $$36] <- [$$b.getField("name"), $$b.getField("jn")] project: [$$39, $$36]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$b])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.t2)  |PARTITIONED|
+                            data-scan []<-[$$34, $$b] <- test.t2
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/insert-and-scan-dataset.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/insert-and-scan-dataset.plan
index 0fba5fc..92acff0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/insert-and-scan-dataset.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/insert-and-scan-dataset.plan
@@ -1,14 +1,28 @@
+commit
 -- COMMIT  |PARTITIONED|
+  project ([$$17])
   -- STREAM_PROJECT  |PARTITIONED|
+    exchange
     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+      insert into test.myData from record: $$18 partitioned by [$$17]
       -- INSERT_DELETE  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          materialize
           -- MATERIALIZE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$17]  |PARTITIONED|
+              assign [$$17] <- [$$18.getField(0)]
               -- ASSIGN  |PARTITIONED|
+                assign [$$18] <- [cast({"id": numeric-add($$19, 1)})] project: [$$18]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$19])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.myData)  |PARTITIONED|
+                      data-scan []<-[$$19, $$x] <- test.myData
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/introhashpartitionmerge.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/introhashpartitionmerge.plan
index 1461b41..4e3ca5c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/introhashpartitionmerge.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/introhashpartitionmerge.plan
@@ -1,22 +1,44 @@
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$45(ASC) ]  |PARTITIONED|
+    order (ASC, $$45)
     -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        project ([$$45])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$46, $$47))
             -- HYBRID_HASH_JOIN [$$46][$$47]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$46]  |PARTITIONED|
+                assign [$$46] <- [$$token1.getField(0)] project: [$$46]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$token1])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (fuzzyjoin.TOKENSRANKEDADM)  |PARTITIONED|
+                      data-scan []<-[$$44, $$token1] <- fuzzyjoin.TOKENSRANKEDADM
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$45(ASC)] HASH:[$$47]  |PARTITIONED|
+                assign [$$47] <- [$$tokenRanked.getField(0)] project: [$$45, $$47]
                 -- ASSIGN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$45)
                     -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (fuzzyjoin.TOKENSRANKEDADM)  |PARTITIONED|
+                        data-scan []<-[$$45, $$tokenRanked] <- fuzzyjoin.TOKENSRANKEDADM
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-contains-panic.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-contains-panic.plan
index da22292..37dbbc0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-contains-panic.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-contains-panic.plan
@@ -1,11 +1,22 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$16(ASC) ]  |PARTITIONED|
+        order (ASC, $$16)
         -- STABLE_SORT [$$16(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (contains($$o.getField(2), "Mu"))
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                data-scan []<-[$$16, $$o] <- test.DBLP
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-contains-panic_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-contains-panic_ps.plan
index 93ca5bd..2c2fae0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-contains-panic_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-contains-panic_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$15)
         -- STABLE_SORT [$$15(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$15(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$20
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField(2), "Mu"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                        data-scan []<-[$$15, $$o] <- test.DBLP
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$20] <- [agg-range-map($$18, $$19)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$18, $$19] <- [agg-local-sampling($$15), agg-null-writer($$15)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$15])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField(2), "Mu"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                  data-scan []<-[$$15, $$o] <- test.DBLP
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-contains.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-contains.plan
index 005ab46..7b6d669 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-contains.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-contains.plan
@@ -1,16 +1,32 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$16(ASC) ]  |PARTITIONED|
+        order (ASC, $$16)
         -- STABLE_SORT [$$16(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (contains($$o.getField(2), "Multimedia"))
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                unnest-map [$$16, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$20, 1, $$20, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$20)
                     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                        unnest-map [$$20] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 0, missing, 12, false, 1, $$19)
+                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$19] <- ["Multimedia"]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-contains_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-contains_ps.plan
index ed6a9c5..9d9e819 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-contains_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-contains_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- STABLE_SORT [$$15(ASC)]  |PARTITIONED|
-          -- RANGE_PARTITION_EXCHANGE [$$15(ASC)]  |PARTITIONED|
+        order (ASC, $$16)
+        -- STABLE_SORT [$$16(ASC)]  |PARTITIONED|
+          exchange
+          -- RANGE_PARTITION_EXCHANGE [$$16(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$23
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField(2), "Multimedia"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                        unnest-map [$$16, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$20, 1, $$20, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+                            order (ASC, $$20)
+                            -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                unnest-map [$$20] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 0, missing, 12, false, 1, $$19)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$19] <- ["Multimedia"]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$23] <- [agg-range-map($$21, $$22)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$21, $$22] <- [agg-local-sampling($$16), agg-null-writer($$16)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$16])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField(2), "Multimedia"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                                  unnest-map [$$16, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$20, 1, $$20, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+                                      order (ASC, $$20)
+                                      -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                          unnest-map [$$20] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 0, missing, 12, false, 1, $$19)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$19] <- ["Multimedia"]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-edit-distance-check.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-edit-distance-check.plan
index 0589004..c2f25e6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-edit-distance-check.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-edit-distance-check.plan
@@ -1,13 +1,26 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(edit-distance-check($$o.getField(3), "Amihay Motro", 1), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$16, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$19, 1, $$19, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+              order (ASC, $$19)
+              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                  unnest-map [$$19] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 2, 1, 12, false, 1, $$18)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$18] <- ["Amihay Motro"]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-edit-distance.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-edit-distance.plan
index 0589004..c2f25e6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-edit-distance.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-edit-distance.plan
@@ -1,13 +1,26 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(edit-distance-check($$o.getField(3), "Amihay Motro", 1), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$16, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$19, 1, $$19, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+              order (ASC, $$19)
+              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                  unnest-map [$$19] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 2, 1, 12, false, 1, $$18)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$18] <- ["Amihay Motro"]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-fuzzyeq-edit-distance.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-fuzzyeq-edit-distance.plan
index 8112a91..7df57d4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-fuzzyeq-edit-distance.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-fuzzyeq-edit-distance.plan
@@ -1,13 +1,26 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(edit-distance-check($$o.getField(3), "Amihay Motro", 1), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$15, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$18, 1, $$18, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
+              order (ASC, $$18)
+              -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                  unnest-map [$$18] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 2, 1, 12, false, 1, $$17)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$17] <- ["Amihay Motro"]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-fuzzyeq-jaccard.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-fuzzyeq-jaccard.plan
index 334be33..468c0c2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-fuzzyeq-jaccard.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-fuzzyeq-jaccard.plan
@@ -1,13 +1,26 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check(gram-tokens($$o.getField(2), 3, false), array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ], 0.8), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$17, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+              order (ASC, $$20)
+              -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                  unnest-map [$$20] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 1, 0.8, 21, false, 1, $$19)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$19] <- [array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-jaccard-check.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-jaccard-check.plan
index b415aa0..3b334eb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-jaccard-check.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-jaccard-check.plan
@@ -1,13 +1,26 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check(gram-tokens($$o.getField(2), 3, false), array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ], 0.5), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$18, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$21, 1, $$21, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+              order (ASC, $$21)
+              -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                  unnest-map [$$21] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 1, 0.5, 21, false, 1, $$20)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$20] <- [array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-jaccard.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-jaccard.plan
index b415aa0..3b334eb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-jaccard.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ngram-jaccard.plan
@@ -1,13 +1,26 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check(gram-tokens($$o.getField(2), 3, false), array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ], 0.5), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$18, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$21, 1, $$21, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+              order (ASC, $$21)
+              -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                  unnest-map [$$21] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 1, 0.5, 21, false, 1, $$20)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$20] <- [array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-check-panic.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-check-panic.plan
index d478d3e..ed86fea 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-check-panic.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-check-panic.plan
@@ -1,11 +1,22 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$18(ASC) ]  |PARTITIONED|
+        order (ASC, $$18)
         -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 3), 0))
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                data-scan []<-[$$18, $$c] <- test.Customers
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-check-panic_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-check-panic_ps.plan
index 1e433b8..61d5347 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-check-panic_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-check-panic_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$17)
         -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$17(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$22
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 3), 0))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                        data-scan []<-[$$17, $$c] <- test.Customers
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$22] <- [agg-range-map($$20, $$21)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$20, $$21] <- [agg-local-sampling($$17), agg-null-writer($$17)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$17])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 3), 0))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                  data-scan []<-[$$17, $$c] <- test.Customers
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-check.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-check.plan
index 971ae76..6cdaa29 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-check.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-check.plan
@@ -1,16 +1,32 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$18(ASC) ]  |PARTITIONED|
+        order (ASC, $$18)
         -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                unnest-map [$$18, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$22, 1, $$22, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$22)
                     -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                        unnest-map [$$22] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$21)
+                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$21] <- [array: [ "computers", "wine", "walking" ]]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-check_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-check_ps.plan
index 7a151d5..69a2593 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-check_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-check_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
-          -- RANGE_PARTITION_EXCHANGE [$$17(ASC)]  |PARTITIONED|
+        order (ASC, $$18)
+        -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+          exchange
+          -- RANGE_PARTITION_EXCHANGE [$$18(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$25
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$18, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$22, 1, $$22, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                            order (ASC, $$22)
+                            -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$22] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$21)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$21] <- [array: [ "computers", "wine", "walking" ]]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$25] <- [agg-range-map($$23, $$24)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$23, $$24] <- [agg-local-sampling($$18), agg-null-writer($$18)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$18])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                                  unnest-map [$$18, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$22, 1, $$22, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                                      order (ASC, $$22)
+                                      -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                          unnest-map [$$22] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$21)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$21] <- [array: [ "computers", "wine", "walking" ]]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-panic.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-panic.plan
index d478d3e..ed86fea 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-panic.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-panic.plan
@@ -1,11 +1,22 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$18(ASC) ]  |PARTITIONED|
+        order (ASC, $$18)
         -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 3), 0))
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                data-scan []<-[$$18, $$c] <- test.Customers
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-panic_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-panic_ps.plan
index 1e433b8..61d5347 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-panic_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance-panic_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$17)
         -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$17(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$22
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 3), 0))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                        data-scan []<-[$$17, $$c] <- test.Customers
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$22] <- [agg-range-map($$20, $$21)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$20, $$21] <- [agg-local-sampling($$17), agg-null-writer($$17)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$17])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 3), 0))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                  data-scan []<-[$$17, $$c] <- test.Customers
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance.plan
index 971ae76..6cdaa29 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance.plan
@@ -1,16 +1,32 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$18(ASC) ]  |PARTITIONED|
+        order (ASC, $$18)
         -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                unnest-map [$$18, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$22, 1, $$22, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$22)
                     -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                        unnest-map [$$22] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$21)
+                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$21] <- [array: [ "computers", "wine", "walking" ]]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance_ps.plan
index 7a151d5..69a2593 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-edit-distance_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
-          -- RANGE_PARTITION_EXCHANGE [$$17(ASC)]  |PARTITIONED|
+        order (ASC, $$18)
+        -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+          exchange
+          -- RANGE_PARTITION_EXCHANGE [$$18(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$25
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$18, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$22, 1, $$22, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                            order (ASC, $$22)
+                            -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$22] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$21)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$21] <- [array: [ "computers", "wine", "walking" ]]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$25] <- [agg-range-map($$23, $$24)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$23, $$24] <- [agg-local-sampling($$18), agg-null-writer($$18)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$18])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                                  unnest-map [$$18, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$22, 1, $$22, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                                      order (ASC, $$22)
+                                      -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                          unnest-map [$$22] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$21)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$21] <- [array: [ "computers", "wine", "walking" ]]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-fuzzyeq-edit-distance.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-fuzzyeq-edit-distance.plan
index ad32edd..9d4b2a9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-fuzzyeq-edit-distance.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-fuzzyeq-edit-distance.plan
@@ -1,16 +1,32 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$17(ASC) ]  |PARTITIONED|
+        order (ASC, $$17)
         -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                unnest-map [$$17, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$21, 1, $$21, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$21)
                     -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                        unnest-map [$$21] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$20)
+                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$20] <- [array: [ "computers", "wine", "walking" ]]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-fuzzyeq-edit-distance_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-fuzzyeq-edit-distance_ps.plan
index b9cf357..1bb0cff 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-fuzzyeq-edit-distance_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-fuzzyeq-edit-distance_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- STABLE_SORT [$$16(ASC)]  |PARTITIONED|
-          -- RANGE_PARTITION_EXCHANGE [$$16(ASC)]  |PARTITIONED|
+        order (ASC, $$17)
+        -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
+          exchange
+          -- RANGE_PARTITION_EXCHANGE [$$17(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$24
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$17, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$21, 1, $$21, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                            order (ASC, $$21)
+                            -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$21] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$20)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$20] <- [array: [ "computers", "wine", "walking" ]]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$24] <- [agg-range-map($$22, $$23)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$22, $$23] <- [agg-local-sampling($$17), agg-null-writer($$17)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$17])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                                  unnest-map [$$17, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$21, 1, $$21, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                                      order (ASC, $$21)
+                                      -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                          unnest-map [$$21] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$20)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$20] <- [array: [ "computers", "wine", "walking" ]]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-fuzzyeq-jaccard.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-fuzzyeq-jaccard.plan
index 79c9758..4a76eb7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-fuzzyeq-jaccard.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-fuzzyeq-jaccard.plan
@@ -1,13 +1,26 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check($$c.getField(4), array: [ "databases", "computers", "wine" ], 0.8), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$16, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$19, 1, $$19, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+              order (ASC, $$19)
+              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                  unnest-map [$$19] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 1, 0.8, 21, false, 1, $$18)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$18] <- [array: [ "databases", "computers", "wine" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-jaccard-check.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-jaccard-check.plan
index a9465ae..938db91c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-jaccard-check.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-jaccard-check.plan
@@ -1,13 +1,26 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check($$c.getField(4), array: [ "databases", "computers", "wine" ], 0.7), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$17, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+              order (ASC, $$20)
+              -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                  unnest-map [$$20] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 1, 0.7, 21, false, 1, $$19)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$19] <- [array: [ "databases", "computers", "wine" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-jaccard.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-jaccard.plan
index a9465ae..938db91c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-jaccard.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/olist-jaccard.plan
@@ -1,13 +1,26 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check($$c.getField(4), array: [ "databases", "computers", "wine" ], 0.7), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$17, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+              order (ASC, $$20)
+              -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                  unnest-map [$$20] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 1, 0.7, 21, false, 1, $$19)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$19] <- [array: [ "databases", "computers", "wine" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ulist-fuzzyeq-jaccard.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ulist-fuzzyeq-jaccard.plan
index 79c9758..129adb8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ulist-fuzzyeq-jaccard.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ulist-fuzzyeq-jaccard.plan
@@ -1,13 +1,26 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check($$c.getField(4), multiset: {{ "computers", "wine", "databases" }}, 0.8), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$16, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$19, 1, $$19, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+              order (ASC, $$19)
+              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                  unnest-map [$$19] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 1, 0.8, 22, false, 1, $$18)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$18] <- [multiset: {{ "computers", "wine", "databases" }}]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ulist-jaccard-check.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ulist-jaccard-check.plan
index a9465ae..4f94523 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ulist-jaccard-check.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ulist-jaccard-check.plan
@@ -1,13 +1,26 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check($$c.getField(4), multiset: {{ "computers", "wine", "databases" }}, 0.7), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$17, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+              order (ASC, $$20)
+              -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                  unnest-map [$$20] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 1, 0.7, 22, false, 1, $$19)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$19] <- [multiset: {{ "computers", "wine", "databases" }}]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ulist-jaccard.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ulist-jaccard.plan
index a9465ae..0fb1cda 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ulist-jaccard.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/ulist-jaccard.plan
@@ -1,13 +1,26 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check($$c.getField(4), multiset: {{ "computers", "databases", "wine" }}, 0.7), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$17, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+              order (ASC, $$20)
+              -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                  unnest-map [$$20] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 1, 0.7, 22, false, 1, $$19)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$19] <- [multiset: {{ "computers", "databases", "wine" }}]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-contains.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-contains.plan
index da22292..2786f49 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-contains.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-contains.plan
@@ -1,11 +1,22 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$16(ASC) ]  |PARTITIONED|
+        order (ASC, $$16)
         -- STABLE_SORT [$$16(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (contains($$o.getField(2), "Multimedia"))
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                data-scan []<-[$$16, $$o] <- test.DBLP
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-contains_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-contains_ps.plan
index 93ca5bd..d6a002c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-contains_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-contains_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$15)
         -- STABLE_SORT [$$15(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$15(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$20
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField(2), "Multimedia"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                        data-scan []<-[$$15, $$o] <- test.DBLP
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$20] <- [agg-range-map($$18, $$19)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$18, $$19] <- [agg-local-sampling($$15), agg-null-writer($$15)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$15])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField(2), "Multimedia"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                  data-scan []<-[$$15, $$o] <- test.DBLP
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-fuzzyeq-jaccard.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-fuzzyeq-jaccard.plan
index 062460e..76157c8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-fuzzyeq-jaccard.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-fuzzyeq-jaccard.plan
@@ -1,13 +1,26 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check(word-tokens($$o.getField(2)), array: [ "transactions", "for", "cooperative", "environments" ], 0.5), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$17, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+              order (ASC, $$20)
+              -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.keyword_index)  |PARTITIONED|
+                  unnest-map [$$20] <- index-search("keyword_index", 4, "Default", "test", "DBLP", false, false, 1, 0.5, 21, false, 1, $$19)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$19] <- [array: [ "transactions", "for", "cooperative", "environments" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-jaccard-check.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-jaccard-check.plan
index f4a3522..ceaff43 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-jaccard-check.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-jaccard-check.plan
@@ -1,13 +1,26 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check(word-tokens($$o.getField(2)), array: [ "transactions", "for", "cooperative", "environments" ], 0.5), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$18, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$21, 1, $$21, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+              order (ASC, $$21)
+              -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.keyword_index)  |PARTITIONED|
+                  unnest-map [$$21] <- index-search("keyword_index", 4, "Default", "test", "DBLP", false, false, 1, 0.5, 21, false, 1, $$20)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$20] <- [array: [ "transactions", "for", "cooperative", "environments" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-jaccard.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-jaccard.plan
index f4a3522..ceaff43 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-jaccard.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-basic/word-jaccard.plan
@@ -1,13 +1,26 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check(word-tokens($$o.getField(2)), array: [ "transactions", "for", "cooperative", "environments" ], 0.5), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$18, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$21, 1, $$21, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+              order (ASC, $$21)
+              -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.keyword_index)  |PARTITIONED|
+                  unnest-map [$$21] <- index-search("keyword_index", 4, "Default", "test", "DBLP", false, false, 1, 0.5, 21, false, 1, $$20)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$20] <- [array: [ "transactions", "for", "cooperative", "environments" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-edit-distance-check-let-panic-nopanic_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-edit-distance-check-let-panic-nopanic_01.plan
index b0c4d3b..9aaa90b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-edit-distance-check-let-panic-nopanic_01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-edit-distance-check-let-panic-nopanic_01.plan
@@ -1,14 +1,28 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(get-item(edit-distance-check($$42, "Amihay Motro", 5), 0), get-item(edit-distance-check($$42, "Amihay Motro", 3), 0))) project: [$$o]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$42] <- [$$o.getField(3)]
       -- ASSIGN  |PARTITIONED|
+        project ([$$o])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+            unnest-map [$$43, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$45, 1, $$45, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$45)
                 -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                    unnest-map [$$45] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 2, 3, 12, false, 1, $$44)
+                    -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$44] <- ["Amihay Motro"]
                         -- ASSIGN  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-edit-distance-check-let-panic-nopanic_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-edit-distance-check-let-panic-nopanic_02.plan
index b0c4d3b..fd1612c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-edit-distance-check-let-panic-nopanic_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-edit-distance-check-let-panic-nopanic_02.plan
@@ -1,14 +1,28 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(get-item(edit-distance-check($$42, "Amihay Motro", 3), 0), get-item(edit-distance-check($$42, "Amihay Motro", 5), 0))) project: [$$o]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$42] <- [$$o.getField(3)]
       -- ASSIGN  |PARTITIONED|
+        project ([$$o])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+            unnest-map [$$43, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$45, 1, $$45, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$45)
                 -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                    unnest-map [$$45] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 2, 3, 12, false, 1, $$44)
+                    -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$44] <- ["Amihay Motro"]
                         -- ASSIGN  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-edit-distance-check-let.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-edit-distance-check-let.plan
index 117d73c..6267946 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-edit-distance-check-let.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-edit-distance-check-let.plan
@@ -1,13 +1,26 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(edit-distance-check($$o.getField(3), "Amihay Motro", 1), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$27, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$30, 1, $$30, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+              order (ASC, $$30)
+              -- STABLE_SORT [$$30(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                  unnest-map [$$30] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 2, 1, 12, false, 1, $$29)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$29] <- ["Amihay Motro"]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-edit-distance-check-substring.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-edit-distance-check-substring.plan
index 3321d55..671cfaa 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-edit-distance-check-substring.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-edit-distance-check-substring.plan
@@ -1,14 +1,28 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$20] <- [{"id": $$22, "title": $$21}] project: [$$20]
     -- ASSIGN  |PARTITIONED|
+      select (get-item(edit-distance-check(substring($$21, 0, 8), "datbase", 1), 0))
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$21] <- [$$paper.getField(2)] project: [$$22, $$21]
         -- ASSIGN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+            unnest-map [$$22, $$paper] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$25, 1, $$25, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$25)
                 -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                    unnest-map [$$25] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 2, 1, 12, false, 1, $$24)
+                    -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$24] <- ["datbase"]
                         -- ASSIGN  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-jaccard-check-let.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-jaccard-check-let.plan
index f1cac23..58eadee 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-jaccard-check-let.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-jaccard-check-let.plan
@@ -1,13 +1,26 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check(gram-tokens($$o.getField(2), 3, false), array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ], 0.5), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$29, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$32, 1, $$32, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$30(ASC)]  |PARTITIONED|
+              order (ASC, $$32)
+              -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                  unnest-map [$$32] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 1, 0.5, 21, false, 1, $$31)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$31] <- [array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-jaccard-check-multi-let.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-jaccard-check-multi-let.plan
index fb9a209..e7606bc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-jaccard-check-multi-let.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ngram-jaccard-check-multi-let.plan
@@ -1,15 +1,30 @@
+distribute result [$$52]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$52] <- [{"Paper": $$59, "Query": array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ]}] project: [$$52]
     -- ASSIGN  |PARTITIONED|
+      select (get-item(similarity-jaccard-check($$59, array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ], 0.5), 0))
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$59] <- [gram-tokens($$paper.getField(2), 3, false)] project: [$$59]
         -- ASSIGN  |PARTITIONED|
+          project ([$$paper])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+              unnest-map [$$53, $$paper] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$58, 1, $$58, true, true, true)
+              -- BTREE_SEARCH  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$58)
                   -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                      unnest-map [$$58] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 1, 0.5, 21, false, 1, $$57)
+                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$57] <- [array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ]]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-edit-distance-check-let-panic.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-edit-distance-check-let-panic.plan
index 801b97f..0f55155 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-edit-distance-check-let-panic.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-edit-distance-check-let-panic.plan
@@ -1,11 +1,22 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$29(ASC) ]  |PARTITIONED|
+        order (ASC, $$29)
         -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 3), 0))
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                data-scan []<-[$$29, $$c] <- test.Customers
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-edit-distance-check-let-panic_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-edit-distance-check-let-panic_ps.plan
index 9b6e544..da8a269 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-edit-distance-check-let-panic_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-edit-distance-check-let-panic_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$27)
         -- STABLE_SORT [$$27(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$27(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$32
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 3), 0))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                        data-scan []<-[$$27, $$c] <- test.Customers
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$32] <- [agg-range-map($$30, $$31)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$30, $$31] <- [agg-local-sampling($$27), agg-null-writer($$27)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$27])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 3), 0))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                  data-scan []<-[$$27, $$c] <- test.Customers
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-edit-distance-check-let.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-edit-distance-check-let.plan
index 5b54be6..75856f5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-edit-distance-check-let.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-edit-distance-check-let.plan
@@ -1,16 +1,32 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$29(ASC) ]  |PARTITIONED|
+        order (ASC, $$29)
         -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                unnest-map [$$29, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$33, 1, $$33, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$33)
                     -- STABLE_SORT [$$33(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                        unnest-map [$$33] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$32)
+                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$32] <- [array: [ "computers", "wine", "walking" ]]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-edit-distance-check-let_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-edit-distance-check-let_ps.plan
index bbd3d0a..f8637c5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-edit-distance-check-let_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-edit-distance-check-let_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- STABLE_SORT [$$27(ASC)]  |PARTITIONED|
-          -- RANGE_PARTITION_EXCHANGE [$$27(ASC)]  |PARTITIONED|
+        order (ASC, $$29)
+        -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+          exchange
+          -- RANGE_PARTITION_EXCHANGE [$$29(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$36
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$29, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$33, 1, $$33, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                            order (ASC, $$33)
+                            -- STABLE_SORT [$$33(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$33] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$32)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$32] <- [array: [ "computers", "wine", "walking" ]]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$36] <- [agg-range-map($$34, $$35)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$34, $$35] <- [agg-local-sampling($$29), agg-null-writer($$29)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$29])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                                  unnest-map [$$29, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$33, 1, $$33, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                                      order (ASC, $$33)
+                                      -- STABLE_SORT [$$33(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                          unnest-map [$$33] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$32)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$32] <- [array: [ "computers", "wine", "walking" ]]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-jaccard-check-let.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-jaccard-check-let.plan
index cc2976d..e417d08 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-jaccard-check-let.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/olist-jaccard-check-let.plan
@@ -1,13 +1,26 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check($$c.getField(4), array: [ "databases", "computers", "wine" ], 0.7), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$28, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$31, 1, $$31, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+              order (ASC, $$31)
+              -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                  unnest-map [$$31] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 1, 0.7, 21, false, 1, $$30)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$30] <- [array: [ "databases", "computers", "wine" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ulist-jaccard-check-let.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ulist-jaccard-check-let.plan
index cc2976d..e417d08 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ulist-jaccard-check-let.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/ulist-jaccard-check-let.plan
@@ -1,13 +1,26 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check($$c.getField(4), array: [ "databases", "computers", "wine" ], 0.7), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$28, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$31, 1, $$31, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+              order (ASC, $$31)
+              -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                  unnest-map [$$31] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 1, 0.7, 21, false, 1, $$30)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$30] <- [array: [ "databases", "computers", "wine" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/word-jaccard-check-let.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/word-jaccard-check-let.plan
index 2011066..2d096fb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/word-jaccard-check-let.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/word-jaccard-check-let.plan
@@ -1,13 +1,26 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check(word-tokens($$o.getField(2)), array: [ "transactions", "for", "cooperative", "environments" ], 0.5), 0))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$29, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$32, 1, $$32, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$30(ASC)]  |PARTITIONED|
+              order (ASC, $$32)
+              -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.keyword_index)  |PARTITIONED|
+                  unnest-map [$$32] <- index-search("keyword_index", 4, "Default", "test", "DBLP", false, false, 1, 0.5, 21, false, 1, $$31)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$31] <- [array: [ "transactions", "for", "cooperative", "environments" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/word-jaccard-check-multi-let.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/word-jaccard-check-multi-let.plan
index 9feb07e..84b4286 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/word-jaccard-check-multi-let.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-complex/word-jaccard-check-multi-let.plan
@@ -1,15 +1,30 @@
+distribute result [$$52]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$52] <- [{"Paper": $$59, "Query": array: [ "transactions", "for", "cooperative", "environments" ]}] project: [$$52]
     -- ASSIGN  |PARTITIONED|
+      select (get-item(similarity-jaccard-check($$59, array: [ "transactions", "for", "cooperative", "environments" ], 0.8), 0))
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$59] <- [word-tokens($$paper.getField(2))] project: [$$59]
         -- ASSIGN  |PARTITIONED|
+          project ([$$paper])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+              unnest-map [$$53, $$paper] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$58, 1, $$58, true, true, true)
+              -- BTREE_SEARCH  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$58)
                   -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.keyword_index)  |PARTITIONED|
+                      unnest-map [$$58] <- index-search("keyword_index", 4, "Default", "test", "DBLP", false, false, 1, 0.8, 21, false, 1, $$57)
+                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$57] <- [array: [ "transactions", "for", "cooperative", "environments" ]]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/ngram-edit-distance-inline.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/ngram-edit-distance-inline.plan
index 2c0f23e..7c4982c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/ngram-edit-distance-inline.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/ngram-edit-distance-inline.plan
@@ -1,54 +1,108 @@
+distribute result [$$47]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    union ($$63, $$72, $$47)
     -- UNION_ALL  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        assign [$$63] <- [{"aauthors": $$48, "bauthors": $$49, "ed": get-item($$81, 1)}] project: [$$63]
         -- ASSIGN  |PARTITIONED|
+          select (and(get-item($$81, 0), lt($$50, $$51))) project: [$$48, $$49, $$81]
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$81] <- [edit-distance-check($$48, $$49, 2)]
             -- ASSIGN  |PARTITIONED|
+              assign [$$49] <- [$$b.getField(3)] project: [$$50, $$48, $$51, $$49]
               -- ASSIGN  |PARTITIONED|
+                project ([$$50, $$48, $$51, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                    unnest-map [$$51, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$62, 1, $$62, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$62)
                         -- STABLE_SORT [$$62(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                            unnest-map [$$62] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 2, 2, 12, false, 1, $$48)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                select (edit-distance-string-is-filterable($$48, 2, 3, true))
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$48] <- [$$58.getField(3)] project: [$$50, $$48]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                                data-scan []<-[$$50, $$58] <- test.DBLP
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        assign [$$72] <- [{"aauthors": $$48, "bauthors": $$59, "ed": get-item(edit-distance-check($$48, $$59, 2), 1)}] project: [$$72]
         -- ASSIGN  |PARTITIONED|
+          project ([$$59, $$48])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (and(get-item(edit-distance-check($$48, $$59, 2), 0), lt($$50, $$61)))
               -- NESTED_LOOP  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  assign [$$61, $$59] <- [$$50, $$48] project: [$$61, $$59]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      replicate
                       -- REPLICATE  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$48] <- [$$58.getField(3)] project: [$$50, $$48]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                              data-scan []<-[$$50, $$58] <- test.DBLP
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  select (not(edit-distance-string-is-filterable($$48, 2, 3, true)))
                   -- STREAM_SELECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      replicate
                       -- REPLICATE  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$48] <- [$$58.getField(3)] project: [$$50, $$48]
                               -- ASSIGN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                  data-scan []<-[$$50, $$58] <- test.DBLP
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/ngram-fuzzyeq-edit-distance.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/ngram-fuzzyeq-edit-distance.plan
index 05daf89..ecdbfb5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/ngram-fuzzyeq-edit-distance.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/ngram-fuzzyeq-edit-distance.plan
@@ -1,45 +1,90 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    union ($$50, $$59, $$35)
     -- UNION_ALL  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        assign [$$50] <- [{"aauthors": $$36, "bauthors": $$37}] project: [$$50]
         -- ASSIGN  |PARTITIONED|
+          select (and(get-item(edit-distance-check($$36, $$37, 3), 0), lt($$38, $$39))) project: [$$36, $$37]
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$37] <- [$$b.getField(3)] project: [$$38, $$36, $$39, $$37]
             -- ASSIGN  |PARTITIONED|
+              project ([$$38, $$36, $$39, $$b])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                  unnest-map [$$39, $$b] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$49, 1, $$49, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$49)
                       -- STABLE_SORT [$$49(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.CSX.ngram_index)  |PARTITIONED|
+                          unnest-map [$$49] <- index-search("ngram_index", 5, "Default", "test", "CSX", true, true, 2, 3, 12, false, 1, $$36)
+                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                            exchange
                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                              select (edit-distance-string-is-filterable($$36, 3, 3, true))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  replicate
                                   -- REPLICATE  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$36] <- [$$45.getField(3)] project: [$$38, $$36]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                          data-scan []<-[$$38, $$45] <- test.DBLP
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        assign [$$59] <- [{"aauthors": $$36, "bauthors": $$46}] project: [$$59]
         -- ASSIGN  |PARTITIONED|
+          project ([$$46, $$36])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (and(get-item(edit-distance-check($$36, $$46, 3), 0), lt($$38, $$48)))
               -- NESTED_LOOP  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  assign [$$46] <- [$$47.getField(3)] project: [$$48, $$46]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                      data-scan []<-[$$48, $$47] <- test.CSX
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  select (not(edit-distance-string-is-filterable($$36, 3, 3, true)))
                   -- STREAM_SELECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      replicate
                       -- REPLICATE  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$36] <- [$$45.getField(3)] project: [$$38, $$36]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                              data-scan []<-[$$38, $$45] <- test.DBLP
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/ngram-jaccard-inline.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/ngram-jaccard-inline.plan
index ec68814..7c4233f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/ngram-jaccard-inline.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/ngram-jaccard-inline.plan
@@ -1,29 +1,58 @@
+distribute result [$$49]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$49] <- [{"atitle": $$50, "btitle": $$51, "jacc": get-item(similarity-jaccard-check(gram-tokens($$50, 3, false), $$56, 0.5), 1)}] project: [$$49]
     -- ASSIGN  |PARTITIONED|
+      project ([$$50, $$51, $$56])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$61, $$52))
           -- HYBRID_HASH_JOIN [$$61][$$52]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$61]  |PARTITIONED|
+              assign [$$50] <- [$$a.getField(2)] project: [$$50, $$61]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                  data-scan []<-[$$61, $$a] <- test.DBLP
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$52]  |PARTITIONED|
+              select (and(get-item(similarity-jaccard-check($$55, $$56, 0.5), 0), lt($$52, $$53))) project: [$$51, $$56, $$52]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$56] <- [gram-tokens($$51, 3, false)]
                 -- ASSIGN  |PARTITIONED|
+                  assign [$$51] <- [$$b.getField(2)] project: [$$52, $$55, $$53, $$51]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$52, $$55, $$53, $$b])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                        unnest-map [$$53, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$64, 1, $$64, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$64)
                             -- STABLE_SORT [$$64(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                unnest-map [$$64] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 1, 0.5, 21, false, 1, $$55)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$55] <- [gram-tokens($$63.getField(2), 3, false)] project: [$$52, $$55]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                        data-scan []<-[$$52, $$63] <- test.DBLP
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/olist-edit-distance-inline.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/olist-edit-distance-inline.plan
index 0ffaa6f..9a670d0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/olist-edit-distance-inline.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/olist-edit-distance-inline.plan
@@ -1,54 +1,108 @@
+distribute result [$$47]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    union ($$63, $$72, $$47)
     -- UNION_ALL  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        assign [$$63] <- [{"ainterests": $$48, "binterests": $$49, "ed": get-item($$81, 1)}] project: [$$63]
         -- ASSIGN  |PARTITIONED|
+          select (and(get-item($$81, 0), lt($$50, $$51))) project: [$$48, $$49, $$81]
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$81] <- [edit-distance-check($$48, $$49, 2)]
             -- ASSIGN  |PARTITIONED|
+              assign [$$49] <- [$$b.getField(4)] project: [$$50, $$48, $$51, $$49]
               -- ASSIGN  |PARTITIONED|
+                project ([$$50, $$48, $$51, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                    unnest-map [$$51, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$62, 1, $$62, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$62)
                         -- STABLE_SORT [$$62(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                            unnest-map [$$62] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 2, 2, 21, false, 1, $$48)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                select (edit-distance-list-is-filterable($$48, 2))
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$48] <- [$$58.getField(4)] project: [$$50, $$48]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                                data-scan []<-[$$50, $$58] <- test.Customers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        assign [$$72] <- [{"ainterests": $$48, "binterests": $$59, "ed": get-item(edit-distance-check($$48, $$59, 2), 1)}] project: [$$72]
         -- ASSIGN  |PARTITIONED|
+          project ([$$59, $$48])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (and(get-item(edit-distance-check($$48, $$59, 2), 0), lt($$50, $$61)))
               -- NESTED_LOOP  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  assign [$$61, $$59] <- [$$50, $$48] project: [$$61, $$59]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      replicate
                       -- REPLICATE  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$48] <- [$$58.getField(4)] project: [$$50, $$48]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                              data-scan []<-[$$50, $$58] <- test.Customers
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  select (not(edit-distance-list-is-filterable($$48, 2)))
                   -- STREAM_SELECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      replicate
                       -- REPLICATE  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$48] <- [$$58.getField(4)] project: [$$50, $$48]
                               -- ASSIGN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                  data-scan []<-[$$50, $$58] <- test.Customers
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/olist-jaccard-inline.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/olist-jaccard-inline.plan
index a8bd7bb..79337a2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/olist-jaccard-inline.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/olist-jaccard-inline.plan
@@ -1,19 +1,38 @@
+distribute result [$$47]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$47] <- [{"ainterests": $$48, "binterests": $$49, "jacc": get-item($$60, 1)}] project: [$$47]
     -- ASSIGN  |PARTITIONED|
+      select (and(get-item($$60, 0), lt($$50, $$51))) project: [$$48, $$49, $$60]
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$60] <- [similarity-jaccard-check($$48, $$49, 0.7)]
         -- ASSIGN  |PARTITIONED|
+          assign [$$49] <- [$$b.getField(4)] project: [$$50, $$48, $$51, $$49]
           -- ASSIGN  |PARTITIONED|
+            project ([$$50, $$48, $$51, $$b])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                unnest-map [$$51, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$59, 1, $$59, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$59)
                     -- STABLE_SORT [$$59(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                        unnest-map [$$59] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 1, 0.7, 21, false, 1, $$48)
+                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$48] <- [$$58.getField(4)] project: [$$50, $$48]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                data-scan []<-[$$50, $$58] <- test.Customers
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/ulist-jaccard-inline.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/ulist-jaccard-inline.plan
index a8bd7bb..79f5095 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/ulist-jaccard-inline.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/ulist-jaccard-inline.plan
@@ -1,19 +1,38 @@
+distribute result [$$47]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$47] <- [{"ainterests": $$48, "binterests": $$49, "jacc": get-item($$60, 1)}] project: [$$47]
     -- ASSIGN  |PARTITIONED|
+      select (and(get-item($$60, 0), lt($$50, $$51))) project: [$$48, $$49, $$60]
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$60] <- [similarity-jaccard-check($$48, $$49, 0.7)]
         -- ASSIGN  |PARTITIONED|
+          assign [$$49] <- [$$b.getField(4)] project: [$$50, $$48, $$51, $$49]
           -- ASSIGN  |PARTITIONED|
+            project ([$$50, $$48, $$51, $$b])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                unnest-map [$$51, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$59, 1, $$59, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$59)
                     -- STABLE_SORT [$$59(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                        unnest-map [$$59] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 1, 0.7, 22, false, 1, $$48)
+                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$48] <- [$$58.getField(4)] project: [$$50, $$48]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                data-scan []<-[$$50, $$58] <- test.Customers
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/word-jaccard-inline.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/word-jaccard-inline.plan
index 9cb276a..737d09b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/word-jaccard-inline.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join-noeqjoin/word-jaccard-inline.plan
@@ -1,29 +1,58 @@
+distribute result [$$49]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$49] <- [{"atitle": $$50, "btitle": $$51, "jacc": get-item(similarity-jaccard-check(word-tokens($$50), $$56, 0.5), 1)}] project: [$$49]
     -- ASSIGN  |PARTITIONED|
+      project ([$$50, $$51, $$56])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$61, $$52))
           -- HYBRID_HASH_JOIN [$$61][$$52]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$61]  |PARTITIONED|
+              assign [$$50] <- [$$a.getField(2)] project: [$$50, $$61]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                  data-scan []<-[$$61, $$a] <- test.DBLP
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$52]  |PARTITIONED|
+              select (and(get-item(similarity-jaccard-check($$55, $$56, 0.5), 0), lt($$52, $$53))) project: [$$51, $$56, $$52]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$56] <- [word-tokens($$51)]
                 -- ASSIGN  |PARTITIONED|
+                  assign [$$51] <- [$$b.getField(2)] project: [$$52, $$55, $$53, $$51]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$52, $$55, $$53, $$b])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                        unnest-map [$$53, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$64, 1, $$64, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$64)
                             -- STABLE_SORT [$$64(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.keyword_index)  |PARTITIONED|
+                                unnest-map [$$64] <- index-search("keyword_index", 4, "Default", "test", "DBLP", true, true, 1, 0.5, 21, false, 1, $$55)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$55] <- [word-tokens($$63.getField(2))] project: [$$52, $$55]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                        data-scan []<-[$$52, $$63] <- test.DBLP
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/issue741.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/issue741.plan
index 734201e..36a6df9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/issue741.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/issue741.plan
@@ -1,39 +1,75 @@
+distribute result [$$58]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$58] <- [{"tweet": $$68, "similar-tweets": $$57}] project: [$$58]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$60]  |PARTITIONED|
-                {
+        group by ([$$68 := $$60]) decor ([]) {
+                  aggregate [$$57] <- [listify($$61)]
                   -- AGGREGATE  |LOCAL|
+                    select (not(is-missing($$61)))
                     -- STREAM_SELECT  |LOCAL|
+                      nested tuple source
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$60]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$60)
             -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$60]  |PARTITIONED|
+                project ([$$61, $$60])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$71, $$60))
                     -- HYBRID_HASH_JOIN [$$71][$$60]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$71]  |PARTITIONED|
+                        select (and(ge($$59, datetime: { 2011-06-18T14:10:17.000 }), lt($$59, datetime: { 2011-06-18T15:10:17.000 }))) project: [$$71]
                         -- STREAM_SELECT  |PARTITIONED|
+                          assign [$$59] <- [$$t.getField(3)] project: [$$71, $$59]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.TweetMessages)  |PARTITIONED|
+                              data-scan []<-[$$71, $$t] <- test.TweetMessages
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$60]  |PARTITIONED|
+                        select (and(neq($$61, $$60), get-item(similarity-jaccard-check($$64, $$t2.getField(4), 0.6), 0))) retain-untrue ($$61 <- missing) project: [$$61, $$60]
                         -- STREAM_SELECT  |PARTITIONED|
+                          project ([$$60, $$64, $$61, $$t2])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                              left-outer-unnest-map [$$61, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$74, 1, $$74, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$74)
                                   -- STABLE_SORT [$$74(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.TweetMessages.topicIIx)  |PARTITIONED|
+                                      left-outer-unnest-map [$$74] <- index-search("topicIIx", 4, "Default", "test", "TweetMessages", true, true, 1, 0.6, 22, false, 1, $$64)
+                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          select (and(ge($$72, datetime: { 2011-06-18T14:10:17.000 }), lt($$72, datetime: { 2011-06-18T15:10:17.000 }))) project: [$$60, $$64]
                                           -- STREAM_SELECT  |PARTITIONED|
+                                            assign [$$64, $$72] <- [$$73.getField(4), $$73.getField(3)] project: [$$60, $$64, $$72]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.TweetMessages)  |PARTITIONED|
+                                                data-scan []<-[$$60, $$73] <- test.TweetMessages
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan
index 416527f..5952503 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan
@@ -1,71 +1,139 @@
+distribute result [$$59]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$59] <- [{"tweet": {"id": $$72, "topics": $$67}, "similar-tweets": $$58}] project: [$$59]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$72(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
-                {
+        group by ([$$72 := $$62]) decor ([$$67]) {
+                  aggregate [$$58] <- [listify({"id": $$63, "topics": $$65})]
                   -- AGGREGATE  |LOCAL|
+                    select (not(is-missing($$63)))
                     -- STREAM_SELECT  |LOCAL|
+                      nested tuple source
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$62) (ASC, $$63)
             -- STABLE_SORT [$$62(ASC), $$63(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                project ([$$67, $$63, $$65, $$62])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$78, $$62))
                     -- HYBRID_HASH_JOIN [$$78][$$62]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$78]  |PARTITIONED|
+                        assign [$$78, $$t1] <- [$$62, $$79] project: [$$78]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$80] <- [240]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                        union ($$63, $$85, $$63) ($$65, $$83, $$65) ($$62, $$62, $$62) ($$67, $$67, $$67)
                         -- UNION_ALL  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (and(neq($$63, $$62), get-item(edit-distance-check($$67, $$65, 7), 0))) retain-untrue ($$63 <- missing) project: [$$63, $$65, $$62, $$67]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$65] <- [$$t2.getField(5)] project: [$$62, $$67, $$63, $$65]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$62, $$67, $$63, $$t2])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                    left-outer-unnest-map [$$63, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$86, 1, $$86, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$86)
                                         -- STABLE_SORT [$$86(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.TweetMessages.msgNgramIx)  |PARTITIONED|
+                                            left-outer-unnest-map [$$86] <- index-search("msgNgramIx", 5, "Default", "test", "TweetMessages", true, true, 2, 7, 12, false, 1, $$67)
+                                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                              exchange
                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                select (edit-distance-string-is-filterable($$67, 7, 3, true))
                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    replicate
                                                     -- REPLICATE  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        assign [$$67] <- [$$79.getField(5)] project: [$$62, $$67]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            replicate
                                                             -- REPLICATE  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    assign [$$80] <- [240]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            left outer join (and(neq($$85, $$62), get-item(edit-distance-check($$67, $$83, 7), 0)))
                             -- NESTED_LOOP  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$83] <- [$$84.getField(5)] project: [$$85, $$83]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.TweetMessages)  |PARTITIONED|
+                                    data-scan []<-[$$85, $$84] <- test.TweetMessages
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                select (not(edit-distance-string-is-filterable($$67, 7, 3, true)))
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$67] <- [$$79.getField(5)] project: [$$62, $$67]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            replicate
                                             -- REPLICATE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$80] <- [240]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01_ps.plan
index ddafba9..045a498 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01_ps.plan
@@ -1,152 +1,298 @@
+distribute result [$$59]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$59] <- [{"tweet": {"id": $$72, "topics": $$67}, "similar-tweets": $$58}] project: [$$59]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$72)
         -- STABLE_SORT [$$72(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$72(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$89
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
-                            {
+                    group by ([$$72 := $$62]) decor ([$$67]) {
+                              aggregate [$$58] <- [listify({"id": $$63, "topics": $$65})]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$63)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$62) (ASC, $$63)
                         -- STABLE_SORT [$$62(ASC), $$63(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                            project ([$$67, $$63, $$65, $$62])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$78, $$62))
                                 -- HYBRID_HASH_JOIN [$$78][$$62]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$78]  |PARTITIONED|
+                                    assign [$$78, $$t1] <- [$$62, $$79] project: [$$78]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                            unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                            -- BTREE_SEARCH  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                assign [$$80] <- [240]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                                    union ($$63, $$85, $$63) ($$65, $$83, $$65) ($$62, $$62, $$62) ($$67, $$67, $$67)
                                     -- UNION_ALL  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        select (and(neq($$63, $$62), get-item(edit-distance-check($$67, $$65, 7), 0))) retain-untrue ($$63 <- missing) project: [$$63, $$65, $$62, $$67]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$65] <- [$$t2.getField(5)] project: [$$62, $$67, $$63, $$65]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$62, $$67, $$63, $$t2])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                left-outer-unnest-map [$$63, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$86, 1, $$86, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    order (ASC, $$86)
                                                     -- STABLE_SORT [$$86(ASC)]  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.TweetMessages.msgNgramIx)  |PARTITIONED|
+                                                        left-outer-unnest-map [$$86] <- index-search("msgNgramIx", 5, "Default", "test", "TweetMessages", true, true, 2, 7, 12, false, 1, $$67)
+                                                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                          exchange
                                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                            select (edit-distance-string-is-filterable($$67, 7, 3, true))
                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                replicate
                                                                 -- REPLICATE  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    assign [$$67] <- [$$79.getField(5)] project: [$$62, $$67]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        replicate
                                                                         -- REPLICATE  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                            unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                assign [$$80] <- [240]
                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                  empty-tuple-source
                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        left outer join (and(neq($$85, $$62), get-item(edit-distance-check($$67, $$83, 7), 0)))
                                         -- NESTED_LOOP  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$83] <- [$$84.getField(5)] project: [$$85, $$83]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.TweetMessages)  |PARTITIONED|
+                                                data-scan []<-[$$85, $$84] <- test.TweetMessages
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            select (not(edit-distance-string-is-filterable($$67, 7, 3, true)))
                                             -- STREAM_SELECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$67] <- [$$79.getField(5)] project: [$$62, $$67]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        replicate
                                                         -- REPLICATE  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                            unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                assign [$$80] <- [240]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$89] <- [agg-range-map($$87, $$88)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$87, $$88] <- [agg-local-sampling($$72), agg-null-writer($$72)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$72])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
-                                      {
+                              group by ([$$72 := $$62]) decor ([$$67]) {
+                                        aggregate [$$58] <- [listify({"id": $$63, "topics": $$65})]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$63)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$62) (ASC, $$63)
                                   -- STABLE_SORT [$$62(ASC), $$63(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                                      project ([$$67, $$63, $$65, $$62])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          join (eq($$78, $$62))
                                           -- HYBRID_HASH_JOIN [$$78][$$62]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$78]  |PARTITIONED|
+                                              assign [$$78, $$t1] <- [$$62, $$79] project: [$$78]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  replicate
                                                   -- REPLICATE  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                      unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          assign [$$80] <- [240]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                                              union ($$63, $$85, $$63) ($$65, $$83, $$65) ($$62, $$62, $$62) ($$67, $$67, $$67)
                                               -- UNION_ALL  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  select (and(neq($$63, $$62), get-item(edit-distance-check($$67, $$65, 7), 0))) retain-untrue ($$63 <- missing) project: [$$63, $$65, $$62, $$67]
                                                   -- STREAM_SELECT  |PARTITIONED|
+                                                    assign [$$65] <- [$$t2.getField(5)] project: [$$62, $$67, $$63, $$65]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$62, $$67, $$63, $$t2])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                          left-outer-unnest-map [$$63, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$86, 1, $$86, true, true, true)
+                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              order (ASC, $$86)
                                                               -- STABLE_SORT [$$86(ASC)]  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.TweetMessages.msgNgramIx)  |PARTITIONED|
+                                                                  left-outer-unnest-map [$$86] <- index-search("msgNgramIx", 5, "Default", "test", "TweetMessages", true, true, 2, 7, 12, false, 1, $$67)
+                                                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                                    exchange
                                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                      select (edit-distance-string-is-filterable($$67, 7, 3, true))
                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          replicate
                                                                           -- REPLICATE  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              assign [$$67] <- [$$79.getField(5)] project: [$$62, $$67]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  replicate
                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                      -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                                      unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                          assign [$$80] <- [240]
                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                            empty-tuple-source
                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  left outer join (and(neq($$85, $$62), get-item(edit-distance-check($$67, $$83, 7), 0)))
                                                   -- NESTED_LOOP  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      assign [$$83] <- [$$84.getField(5)] project: [$$85, $$83]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.TweetMessages)  |PARTITIONED|
+                                                          data-scan []<-[$$85, $$84] <- test.TweetMessages
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                      select (not(edit-distance-string-is-filterable($$67, 7, 3, true)))
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          replicate
                                                           -- REPLICATE  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              assign [$$67] <- [$$79.getField(5)] project: [$$62, $$67]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  replicate
                                                                   -- REPLICATE  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                      unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          assign [$$80] <- [240]
                                                                           -- ASSIGN  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01.plan
index 89bf4d3..825a5f8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01.plan
@@ -1,44 +1,85 @@
+distribute result [$$59]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$59] <- [{"tweet": {"id": $$72, "topics": $$67}, "similar-tweets": $$58}] project: [$$59]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$72(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
-                {
+        group by ([$$72 := $$62]) decor ([$$67]) {
+                  aggregate [$$58] <- [listify({"id": $$63, "topics": $$65})]
                   -- AGGREGATE  |LOCAL|
+                    select (not(is-missing($$63)))
                     -- STREAM_SELECT  |LOCAL|
+                      nested tuple source
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$62) (ASC, $$63)
             -- STABLE_SORT [$$62(ASC), $$63(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                project ([$$67, $$63, $$65, $$62])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$78, $$62))
                     -- HYBRID_HASH_JOIN [$$78][$$62]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$78]  |PARTITIONED|
+                        assign [$$78, $$t1] <- [$$62, $$79] project: [$$78]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$80] <- [240]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                        select (and(neq($$63, $$62), get-item(similarity-jaccard-check($$67, $$65, 0.5), 0))) retain-untrue ($$63 <- missing)
                         -- STREAM_SELECT  |PARTITIONED|
+                          assign [$$65] <- [$$t2.getField(4)] project: [$$62, $$67, $$63, $$65]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$62, $$67, $$63, $$t2])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                left-outer-unnest-map [$$63, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$82, 1, $$82, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$82)
                                     -- STABLE_SORT [$$82(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.TweetMessages.topicKeywordIx)  |PARTITIONED|
+                                        left-outer-unnest-map [$$82] <- index-search("topicKeywordIx", 4, "Default", "test", "TweetMessages", true, true, 1, 0.5, 22, false, 1, $$67)
+                                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            assign [$$67] <- [$$79.getField(4)] project: [$$62, $$67]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                    unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        assign [$$80] <- [240]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01_ps.plan
index 72b7990..980f630 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01_ps.plan
@@ -1,98 +1,190 @@
+distribute result [$$59]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$59] <- [{"tweet": {"id": $$72, "topics": $$67}, "similar-tweets": $$58}] project: [$$59]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$72)
         -- STABLE_SORT [$$72(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$72(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$85
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
-                            {
+                    group by ([$$72 := $$62]) decor ([$$67]) {
+                              aggregate [$$58] <- [listify({"id": $$63, "topics": $$65})]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$63)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$62) (ASC, $$63)
                         -- STABLE_SORT [$$62(ASC), $$63(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                            project ([$$67, $$63, $$65, $$62])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$78, $$62))
                                 -- HYBRID_HASH_JOIN [$$78][$$62]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$78]  |PARTITIONED|
+                                    assign [$$78, $$t1] <- [$$62, $$79] project: [$$78]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                            unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                            -- BTREE_SEARCH  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                assign [$$80] <- [240]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                                    select (and(neq($$63, $$62), get-item(similarity-jaccard-check($$67, $$65, 0.5), 0))) retain-untrue ($$63 <- missing)
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      assign [$$65] <- [$$t2.getField(4)] project: [$$62, $$67, $$63, $$65]
                                       -- ASSIGN  |PARTITIONED|
+                                        project ([$$62, $$67, $$63, $$t2])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                            left-outer-unnest-map [$$63, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$82, 1, $$82, true, true, true)
+                                            -- BTREE_SEARCH  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                order (ASC, $$82)
                                                 -- STABLE_SORT [$$82(ASC)]  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.TweetMessages.topicKeywordIx)  |PARTITIONED|
+                                                    left-outer-unnest-map [$$82] <- index-search("topicKeywordIx", 4, "Default", "test", "TweetMessages", true, true, 1, 0.5, 22, false, 1, $$67)
+                                                    -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        assign [$$67] <- [$$79.getField(4)] project: [$$62, $$67]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            replicate
                                                             -- REPLICATE  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    assign [$$80] <- [240]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$85] <- [agg-range-map($$83, $$84)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$83, $$84] <- [agg-local-sampling($$72), agg-null-writer($$72)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$72])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
-                                      {
+                              group by ([$$72 := $$62]) decor ([$$67]) {
+                                        aggregate [$$58] <- [listify({"id": $$63, "topics": $$65})]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$63)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$62) (ASC, $$63)
                                   -- STABLE_SORT [$$62(ASC), $$63(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                                      project ([$$67, $$63, $$65, $$62])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          join (eq($$78, $$62))
                                           -- HYBRID_HASH_JOIN [$$78][$$62]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$78]  |PARTITIONED|
+                                              assign [$$78, $$t1] <- [$$62, $$79] project: [$$78]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  replicate
                                                   -- REPLICATE  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                      unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          assign [$$80] <- [240]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                                              select (and(neq($$63, $$62), get-item(similarity-jaccard-check($$67, $$65, 0.5), 0))) retain-untrue ($$63 <- missing)
                                               -- STREAM_SELECT  |PARTITIONED|
+                                                assign [$$65] <- [$$t2.getField(4)] project: [$$62, $$67, $$63, $$65]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  project ([$$62, $$67, $$63, $$t2])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                      left-outer-unnest-map [$$63, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$82, 1, $$82, true, true, true)
+                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          order (ASC, $$82)
                                                           -- STABLE_SORT [$$82(ASC)]  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.TweetMessages.topicKeywordIx)  |PARTITIONED|
+                                                              left-outer-unnest-map [$$82] <- index-search("topicKeywordIx", 4, "Default", "test", "TweetMessages", true, true, 1, 0.5, 22, false, 1, $$67)
+                                                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$67] <- [$$79.getField(4)] project: [$$62, $$67]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      replicate
                                                                       -- REPLICATE  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                          -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                          unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              assign [$$80] <- [240]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                empty-tuple-source
                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-contains_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-contains_ps.plan
index 903f710..bc19770 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-contains_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-contains_ps.plan
@@ -1,49 +1,98 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"title1": $$38, "title2": $$39}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      project ([$$38, $$39])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$40) (ASC, $$41)
           -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$54
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (and(contains($$38, $$39), lt($$40, $$41)))
                       -- STREAM_SELECT  |PARTITIONED|
+                        assign [$$39] <- [$$o2.getField(2)] project: [$$40, $$38, $$41, $$39]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$40, $$38, $$41, $$o2])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                              unnest-map [$$41, $$o2] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$50, 1, $$50, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$50)
                                   -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                      unnest-map [$$50] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 0, missing, 12, false, 1, $$38)
+                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          assign [$$38] <- [$$49.getField(2)] project: [$$40, $$38]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                              data-scan []<-[$$40, $$49] <- test.DBLP
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$54] <- [agg-range-map($$51, $$52, $$53)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$51, $$52, $$53] <- [agg-local-sampling($$40, $$41), agg-null-writer($$40), agg-null-writer($$41)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$40, $$41])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (and(contains($$38, $$39), lt($$40, $$41)))
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$39] <- [$$o2.getField(2)] project: [$$40, $$38, $$41, $$39]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$40, $$38, $$41, $$o2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                                        unnest-map [$$41, $$o2] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$50, 1, $$50, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$50)
                                             -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                                unnest-map [$$50] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 0, missing, 12, false, 1, $$38)
+                                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$38] <- [$$49.getField(2)] project: [$$40, $$38]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                                        data-scan []<-[$$40, $$49] <- test.DBLP
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance-check_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance-check_02.plan
index a2c86fa..6f32e6d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance-check_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance-check_02.plan
@@ -1,51 +1,102 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"arec": $$a, "brec": $$b}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$43, $$35))
           -- HYBRID_HASH_JOIN [$$43][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$43, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              union ($$b, $$46, $$b) ($$35, $$35, $$35)
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (and(lt($$35, $$36), get-item(edit-distance-check($$39, $$b.getField(3), 3), 0))) project: [$$b, $$35]
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$35, $$39, $$36, $$b])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                        unnest-map [$$36, $$b] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$48, 1, $$48, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$48)
                             -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.CSX.ngram_index)  |PARTITIONED|
+                                unnest-map [$$48] <- index-search("ngram_index", 5, "Default", "test", "CSX", true, true, 2, 3, 12, false, 1, $$39)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    select (edit-distance-string-is-filterable($$39, 3, 3, true))
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$39] <- [$$44.getField(3)] project: [$$35, $$39]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                                data-scan []<-[$$35, $$44] <- test.DBLP
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$46, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (and(lt($$35, $$47), get-item(edit-distance-check($$39, $$45, 3), 0)))
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$45] <- [$$46.getField(3)]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                              data-scan []<-[$$47, $$46] <- test.CSX
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          select (not(edit-distance-string-is-filterable($$39, 3, 3, true)))
                           -- STREAM_SELECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$39] <- [$$44.getField(3)] project: [$$35, $$39]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                      data-scan []<-[$$35, $$44] <- test.DBLP
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance-check_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance-check_03.plan
index 37d392b..7dc4d2d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance-check_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance-check_03.plan
@@ -1,51 +1,102 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"arec": $$a, "brec": $$b}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$43, $$35))
           -- HYBRID_HASH_JOIN [$$43][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$43, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              union ($$b, $$46, $$b) ($$35, $$35, $$35)
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (and(lt($$35, $$36), get-item(edit-distance-check($$39, $$b.getField(3), 3), 0))) project: [$$b, $$35]
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$35, $$39, $$36, $$b])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                        unnest-map [$$36, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$48, 1, $$48, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$48)
                             -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                unnest-map [$$48] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 2, 3, 12, false, 1, $$39)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    select (edit-distance-string-is-filterable($$39, 3, 3, true))
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$39] <- [$$44.getField(3)] project: [$$35, $$39]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                                data-scan []<-[$$35, $$44] <- test.DBLP
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$46, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (and(lt($$35, $$47), get-item(edit-distance-check($$39, $$45, 3), 0)))
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$45] <- [$$46.getField(3)]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                              data-scan []<-[$$47, $$46] <- test.DBLP
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          select (not(edit-distance-string-is-filterable($$39, 3, 3, true)))
                           -- STREAM_SELECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$39] <- [$$44.getField(3)] project: [$$35, $$39]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                      data-scan []<-[$$35, $$44] <- test.DBLP
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance-check_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance-check_04.plan
index 4139775..5f5d2e7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance-check_04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance-check_04.plan
@@ -1,53 +1,106 @@
+distribute result [$$46]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$46] <- [{"arec": $$a, "brec": $$b, "ed": get-item($$63, 1)}] project: [$$46]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b, $$63])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$57, $$47))
           -- HYBRID_HASH_JOIN [$$57][$$47]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$57, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
+              union ($$b, $$60, $$b) ($$47, $$47, $$47) ($$82, $$73, $$63)
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (and(get-item($$82, 0), lt($$47, $$48))) project: [$$b, $$47, $$82]
                   -- STREAM_SELECT  |PARTITIONED|
+                    assign [$$82] <- [edit-distance-check($$49, $$b.getField(3), 3)] project: [$$47, $$48, $$b, $$82]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$47, $$49, $$48, $$b])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                          unnest-map [$$48, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$62, 1, $$62, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$62)
                               -- STABLE_SORT [$$62(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                  unnest-map [$$62] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 2, 3, 12, false, 1, $$49)
+                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                      select (edit-distance-string-is-filterable($$49, 3, 3, true))
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$49] <- [$$58.getField(3)] project: [$$47, $$49]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                                  data-scan []<-[$$47, $$58] <- test.DBLP
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  assign [$$73] <- [edit-distance-check($$49, $$59, 3)] project: [$$60, $$47, $$73]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$60, $$59, $$47, $$49])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (and(get-item(edit-distance-check($$49, $$59, 3), 0), lt($$47, $$61)))
                         -- NESTED_LOOP  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$59] <- [$$60.getField(3)]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                data-scan []<-[$$61, $$60] <- test.DBLP
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            select (not(edit-distance-string-is-filterable($$49, 3, 3, true)))
                             -- STREAM_SELECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                replicate
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$49] <- [$$58.getField(3)] project: [$$47, $$49]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                        data-scan []<-[$$47, $$58] <- test.DBLP
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance_02.plan
index a2c86fa..1d02e13 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance_02.plan
@@ -1,51 +1,102 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"arec": $$a, "brec": $$b}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$43, $$35))
           -- HYBRID_HASH_JOIN [$$43][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$43, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              union ($$b, $$46, $$b) ($$35, $$35, $$35)
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (and(lt($$35, $$36), get-item(edit-distance-check($$39, $$b.getField(3), 2), 0))) project: [$$b, $$35]
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$35, $$39, $$36, $$b])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                        unnest-map [$$36, $$b] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$48, 1, $$48, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$48)
                             -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.CSX.ngram_index)  |PARTITIONED|
+                                unnest-map [$$48] <- index-search("ngram_index", 5, "Default", "test", "CSX", true, true, 2, 2, 12, false, 1, $$39)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    select (edit-distance-string-is-filterable($$39, 2, 3, true))
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$39] <- [$$44.getField(3)] project: [$$35, $$39]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                                data-scan []<-[$$35, $$44] <- test.DBLP
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$46, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (and(lt($$35, $$47), get-item(edit-distance-check($$39, $$45, 2), 0)))
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$45] <- [$$46.getField(3)]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                              data-scan []<-[$$47, $$46] <- test.CSX
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          select (not(edit-distance-string-is-filterable($$39, 2, 3, true)))
                           -- STREAM_SELECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$39] <- [$$44.getField(3)] project: [$$35, $$39]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                      data-scan []<-[$$35, $$44] <- test.DBLP
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance_03.plan
index 37d392b..bef4fb4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance_03.plan
@@ -1,51 +1,102 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"arec": $$a, "brec": $$b}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$43, $$35))
           -- HYBRID_HASH_JOIN [$$43][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$43, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              union ($$b, $$46, $$b) ($$35, $$35, $$35)
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (and(lt($$35, $$36), get-item(edit-distance-check($$39, $$b.getField(3), 2), 0))) project: [$$b, $$35]
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$35, $$39, $$36, $$b])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                        unnest-map [$$36, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$48, 1, $$48, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$48)
                             -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                unnest-map [$$48] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 2, 2, 12, false, 1, $$39)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    select (edit-distance-string-is-filterable($$39, 2, 3, true))
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$39] <- [$$44.getField(3)] project: [$$35, $$39]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                                data-scan []<-[$$35, $$44] <- test.DBLP
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$46, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (and(lt($$35, $$47), get-item(edit-distance-check($$39, $$45, 2), 0)))
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$45] <- [$$46.getField(3)]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                              data-scan []<-[$$47, $$46] <- test.DBLP
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          select (not(edit-distance-string-is-filterable($$39, 2, 3, true)))
                           -- STREAM_SELECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$39] <- [$$44.getField(3)] project: [$$35, $$39]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                      data-scan []<-[$$35, $$44] <- test.DBLP
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance_04.plan
index 9c656dc..3350bc0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance_04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-edit-distance_04.plan
@@ -1,53 +1,106 @@
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"arec": $$a, "brec": $$b, "ed": get-item($$63, 1)}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b, $$63])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$57, $$46))
           -- HYBRID_HASH_JOIN [$$57][$$46]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$57, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$46]  |PARTITIONED|
+              union ($$b, $$60, $$b) ($$46, $$46, $$46) ($$82, $$73, $$63)
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (and(get-item($$82, 0), lt($$46, $$47))) project: [$$b, $$46, $$82]
                   -- STREAM_SELECT  |PARTITIONED|
+                    assign [$$82] <- [edit-distance-check($$49, $$b.getField(3), 2)] project: [$$46, $$47, $$b, $$82]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$46, $$49, $$47, $$b])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                          unnest-map [$$47, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$62, 1, $$62, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$62)
                               -- STABLE_SORT [$$62(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                  unnest-map [$$62] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 2, 2, 12, false, 1, $$49)
+                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                      select (edit-distance-string-is-filterable($$49, 2, 3, true))
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$49] <- [$$58.getField(3)] project: [$$46, $$49]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                                  data-scan []<-[$$46, $$58] <- test.DBLP
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  assign [$$73] <- [edit-distance-check($$49, $$59, 2)] project: [$$60, $$46, $$73]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$60, $$59, $$46, $$49])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (and(get-item(edit-distance-check($$49, $$59, 2), 0), lt($$46, $$61)))
                         -- NESTED_LOOP  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$59] <- [$$60.getField(3)]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                data-scan []<-[$$61, $$60] <- test.DBLP
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            select (not(edit-distance-string-is-filterable($$49, 2, 3, true)))
                             -- STREAM_SELECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                replicate
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$49] <- [$$58.getField(3)] project: [$$46, $$49]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                        data-scan []<-[$$46, $$58] <- test.DBLP
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-fuzzyeq-edit-distance_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-fuzzyeq-edit-distance_01.plan
index 466f854..cff50d4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-fuzzyeq-edit-distance_01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-fuzzyeq-edit-distance_01.plan
@@ -1,51 +1,102 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"arec": $$a, "brec": $$b}] project: [$$33]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$42, $$34))
           -- HYBRID_HASH_JOIN [$$42][$$34]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$42]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$42, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
+              union ($$b, $$45, $$b) ($$34, $$34, $$34)
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (and(lt($$34, $$35), get-item(edit-distance-check($$38, $$b.getField(3), 3), 0))) project: [$$b, $$34]
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$34, $$38, $$35, $$b])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                        unnest-map [$$35, $$b] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$47, 1, $$47, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$47)
                             -- STABLE_SORT [$$47(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.CSX.ngram_index)  |PARTITIONED|
+                                unnest-map [$$47] <- index-search("ngram_index", 5, "Default", "test", "CSX", true, true, 2, 3, 12, false, 1, $$38)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    select (edit-distance-string-is-filterable($$38, 3, 3, true))
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$38] <- [$$43.getField(3)] project: [$$34, $$38]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                                data-scan []<-[$$34, $$43] <- test.DBLP
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$45, $$34])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (and(lt($$34, $$46), get-item(edit-distance-check($$38, $$44, 3), 0)))
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$44] <- [$$45.getField(3)]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                              data-scan []<-[$$46, $$45] <- test.CSX
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          select (not(edit-distance-string-is-filterable($$38, 3, 3, true)))
                           -- STREAM_SELECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$38] <- [$$43.getField(3)] project: [$$34, $$38]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                      data-scan []<-[$$34, $$43] <- test.DBLP
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-fuzzyeq-edit-distance_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-fuzzyeq-edit-distance_03.plan
index 094ea28..3b6e65c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-fuzzyeq-edit-distance_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-fuzzyeq-edit-distance_03.plan
@@ -1,51 +1,102 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"arec": $$a, "brec": $$b}] project: [$$33]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$42, $$34))
           -- HYBRID_HASH_JOIN [$$42][$$34]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$42]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$42, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
+              union ($$b, $$45, $$b) ($$34, $$34, $$34)
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (and(lt($$34, $$35), get-item(edit-distance-check($$38, $$b.getField(3), 3), 0))) project: [$$b, $$34]
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$34, $$38, $$35, $$b])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                        unnest-map [$$35, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$47, 1, $$47, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$47)
                             -- STABLE_SORT [$$47(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                unnest-map [$$47] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 2, 3, 12, false, 1, $$38)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    select (edit-distance-string-is-filterable($$38, 3, 3, true))
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$38] <- [$$43.getField(3)] project: [$$34, $$38]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                                data-scan []<-[$$34, $$43] <- test.DBLP
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$45, $$34])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (and(lt($$34, $$46), get-item(edit-distance-check($$38, $$44, 3), 0)))
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$44] <- [$$45.getField(3)]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                              data-scan []<-[$$46, $$45] <- test.DBLP
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          select (not(edit-distance-string-is-filterable($$38, 3, 3, true)))
                           -- STREAM_SELECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$38] <- [$$43.getField(3)] project: [$$34, $$38]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                      data-scan []<-[$$34, $$43] <- test.DBLP
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-fuzzyeq-jaccard_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-fuzzyeq-jaccard_02.plan
index 1c0ee3c..a22ca54 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-fuzzyeq-jaccard_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-fuzzyeq-jaccard_02.plan
@@ -1,25 +1,50 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"arec": $$a, "brec": $$b}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$46, $$36))
           -- HYBRID_HASH_JOIN [$$46][$$36]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$46]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$46, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+              select (and(lt($$36, $$37), get-item(similarity-jaccard-check($$40, gram-tokens($$b.getField(2), 3, false), 0.5), 0))) project: [$$b, $$36]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$36, $$40, $$37, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                    unnest-map [$$37, $$b] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$49, 1, $$49, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$49)
                         -- STABLE_SORT [$$49(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.CSX.ngram_index)  |PARTITIONED|
+                            unnest-map [$$49] <- index-search("ngram_index", 5, "Default", "test", "CSX", true, true, 1, 0.5, 21, false, 1, $$40)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$40] <- [gram-tokens($$48.getField(2), 3, false)] project: [$$36, $$40]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                    data-scan []<-[$$36, $$48] <- test.DBLP
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-fuzzyeq-jaccard_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-fuzzyeq-jaccard_03.plan
index 18170c0..6a189db 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-fuzzyeq-jaccard_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-fuzzyeq-jaccard_03.plan
@@ -1,25 +1,50 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"arec": $$a, "brec": $$b}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$46, $$36))
           -- HYBRID_HASH_JOIN [$$46][$$36]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$46]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$46, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+              select (and(lt($$36, $$37), get-item(similarity-jaccard-check($$40, gram-tokens($$b.getField(2), 3, false), 0.5), 0))) project: [$$b, $$36]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$36, $$40, $$37, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                    unnest-map [$$37, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$49, 1, $$49, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$49)
                         -- STABLE_SORT [$$49(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                            unnest-map [$$49] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 1, 0.5, 21, false, 1, $$40)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$40] <- [gram-tokens($$48.getField(2), 3, false)] project: [$$36, $$40]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                    data-scan []<-[$$36, $$48] <- test.DBLP
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard-check_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard-check_02.plan
index a9d8491..b19014a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard-check_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard-check_02.plan
@@ -1,25 +1,50 @@
+distribute result [$$36]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$36] <- [{"arec": $$a, "brec": $$b}] project: [$$36]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$47, $$37))
           -- HYBRID_HASH_JOIN [$$47][$$37]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$47, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+              select (and(lt($$37, $$38), get-item(similarity-jaccard-check($$41, gram-tokens($$b.getField(2), 3, false), 0.5), 0))) project: [$$b, $$37]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$37, $$41, $$38, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                    unnest-map [$$38, $$b] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$50, 1, $$50, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$50)
                         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.CSX.ngram_index)  |PARTITIONED|
+                            unnest-map [$$50] <- index-search("ngram_index", 5, "Default", "test", "CSX", true, true, 1, 0.5, 21, false, 1, $$41)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$41] <- [gram-tokens($$49.getField(2), 3, false)] project: [$$37, $$41]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                    data-scan []<-[$$37, $$49] <- test.DBLP
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard-check_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard-check_03.plan
index caf734c..77d34c8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard-check_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard-check_03.plan
@@ -1,25 +1,50 @@
+distribute result [$$36]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$36] <- [{"arec": $$a, "brec": $$b}] project: [$$36]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$47, $$37))
           -- HYBRID_HASH_JOIN [$$47][$$37]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$47, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+              select (and(lt($$37, $$38), get-item(similarity-jaccard-check($$41, gram-tokens($$b.getField(2), 3, false), 0.5), 0))) project: [$$b, $$37]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$37, $$41, $$38, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                    unnest-map [$$38, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$50, 1, $$50, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$50)
                         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                            unnest-map [$$50] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 1, 0.5, 21, false, 1, $$41)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$41] <- [gram-tokens($$49.getField(2), 3, false)] project: [$$37, $$41]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                    data-scan []<-[$$37, $$49] <- test.DBLP
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard-check_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard-check_04.plan
index 243faab..2ed980e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard-check_04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard-check_04.plan
@@ -1,28 +1,56 @@
+distribute result [$$48]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$48] <- [{"arec": $$a, "brec": $$b, "jacc": get-item(similarity-jaccard-check(gram-tokens($$55, 3, false), $$52, 0.5), 1)}] project: [$$48]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$55, $$b, $$52])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$61, $$49))
           -- HYBRID_HASH_JOIN [$$61][$$49]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$61]  |PARTITIONED|
+              assign [$$55] <- [$$a.getField(2)]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                  data-scan []<-[$$61, $$a] <- test.DBLP
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$49]  |PARTITIONED|
+              select (and(get-item(similarity-jaccard-check($$51, $$52, 0.5), 0), lt($$49, $$50))) project: [$$b, $$52, $$49]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$52] <- [gram-tokens($$b.getField(2), 3, false)]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$49, $$51, $$50, $$b])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                      unnest-map [$$50, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$64, 1, $$64, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$64)
                           -- STABLE_SORT [$$64(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                              unnest-map [$$64] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 1, 0.5, 21, false, 1, $$51)
+                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                exchange
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  assign [$$51] <- [gram-tokens($$63.getField(2), 3, false)] project: [$$49, $$51]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                      data-scan []<-[$$49, $$63] <- test.DBLP
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard_02.plan
index a9d8491..b19014a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard_02.plan
@@ -1,25 +1,50 @@
+distribute result [$$36]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$36] <- [{"arec": $$a, "brec": $$b}] project: [$$36]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$47, $$37))
           -- HYBRID_HASH_JOIN [$$47][$$37]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$47, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+              select (and(lt($$37, $$38), get-item(similarity-jaccard-check($$41, gram-tokens($$b.getField(2), 3, false), 0.5), 0))) project: [$$b, $$37]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$37, $$41, $$38, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                    unnest-map [$$38, $$b] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$50, 1, $$50, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$50)
                         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.CSX.ngram_index)  |PARTITIONED|
+                            unnest-map [$$50] <- index-search("ngram_index", 5, "Default", "test", "CSX", true, true, 1, 0.5, 21, false, 1, $$41)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$41] <- [gram-tokens($$49.getField(2), 3, false)] project: [$$37, $$41]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                    data-scan []<-[$$37, $$49] <- test.DBLP
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard_03.plan
index caf734c..77d34c8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard_03.plan
@@ -1,25 +1,50 @@
+distribute result [$$36]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$36] <- [{"arec": $$a, "brec": $$b}] project: [$$36]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$47, $$37))
           -- HYBRID_HASH_JOIN [$$47][$$37]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$47, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+              select (and(lt($$37, $$38), get-item(similarity-jaccard-check($$41, gram-tokens($$b.getField(2), 3, false), 0.5), 0))) project: [$$b, $$37]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$37, $$41, $$38, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                    unnest-map [$$38, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$50, 1, $$50, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$50)
                         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                            unnest-map [$$50] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 1, 0.5, 21, false, 1, $$41)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$41] <- [gram-tokens($$49.getField(2), 3, false)] project: [$$37, $$41]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                    data-scan []<-[$$37, $$49] <- test.DBLP
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard_04.plan
index 2382014..1449181 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard_04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ngram-jaccard_04.plan
@@ -1,28 +1,56 @@
+distribute result [$$47]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$47] <- [{"arec": $$a, "brec": $$b, "jacc": get-item(similarity-jaccard-check(gram-tokens($$55, 3, false), $$52, 0.5), 1)}] project: [$$47]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$55, $$b, $$52])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$61, $$48))
           -- HYBRID_HASH_JOIN [$$61][$$48]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$61]  |PARTITIONED|
+              assign [$$55] <- [$$a.getField(2)]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                  data-scan []<-[$$61, $$a] <- test.DBLP
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+              select (and(get-item(similarity-jaccard-check($$51, $$52, 0.5), 0), lt($$48, $$49))) project: [$$b, $$52, $$48]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$52] <- [gram-tokens($$b.getField(2), 3, false)]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$48, $$51, $$49, $$b])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                      unnest-map [$$49, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$64, 1, $$64, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$64)
                           -- STABLE_SORT [$$64(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                              unnest-map [$$64] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 1, 0.5, 21, false, 1, $$51)
+                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                exchange
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  assign [$$51] <- [gram-tokens($$63.getField(2), 3, false)] project: [$$48, $$51]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                      data-scan []<-[$$48, $$63] <- test.DBLP
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance-check_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance-check_02.plan
index 1fdd9ca..bcbc2a4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance-check_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance-check_02.plan
@@ -1,51 +1,102 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"arec": $$a, "brec": $$b}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$43, $$35))
           -- HYBRID_HASH_JOIN [$$43][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$43, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              union ($$b, $$46, $$b) ($$35, $$35, $$35)
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (and(lt($$35, $$36), get-item(edit-distance-check($$39, $$b.getField(4), 3), 0))) project: [$$b, $$35]
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$35, $$39, $$36, $$b])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers2.Customers2)  |PARTITIONED|
+                        unnest-map [$$36, $$b] <- index-search("Customers2", 0, "Default", "test", "Customers2", true, false, 1, $$48, 1, $$48, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$48)
                             -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers2.interests_index)  |PARTITIONED|
+                                unnest-map [$$48] <- index-search("interests_index", 4, "Default", "test", "Customers2", true, true, 2, 3, 21, false, 1, $$39)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    select (edit-distance-list-is-filterable($$39, 3))
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$39] <- [$$44.getField(4)] project: [$$35, $$39]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                                data-scan []<-[$$35, $$44] <- test.Customers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$46, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (and(lt($$35, $$47), get-item(edit-distance-check($$39, $$45, 3), 0)))
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$45] <- [$$46.getField(4)]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.Customers2)  |PARTITIONED|
+                              data-scan []<-[$$47, $$46] <- test.Customers2
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          select (not(edit-distance-list-is-filterable($$39, 3)))
                           -- STREAM_SELECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$39] <- [$$44.getField(4)] project: [$$35, $$39]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                      data-scan []<-[$$35, $$44] <- test.Customers
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance-check_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance-check_03.plan
index 382f807..2bef1ee 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance-check_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance-check_03.plan
@@ -1,51 +1,102 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"arec": $$a, "brec": $$b}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$43, $$35))
           -- HYBRID_HASH_JOIN [$$43][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$43, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              union ($$b, $$46, $$b) ($$35, $$35, $$35)
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (and(lt($$35, $$36), get-item(edit-distance-check($$39, $$b.getField(4), 3), 0))) project: [$$b, $$35]
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$35, $$39, $$36, $$b])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$36, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$48, 1, $$48, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$48)
                             -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$48] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 2, 3, 21, false, 1, $$39)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    select (edit-distance-list-is-filterable($$39, 3))
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$39] <- [$$44.getField(4)] project: [$$35, $$39]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                                data-scan []<-[$$35, $$44] <- test.Customers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$46, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (and(lt($$35, $$47), get-item(edit-distance-check($$39, $$45, 3), 0)))
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$45] <- [$$46.getField(4)]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                              data-scan []<-[$$47, $$46] <- test.Customers
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          select (not(edit-distance-list-is-filterable($$39, 3)))
                           -- STREAM_SELECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$39] <- [$$44.getField(4)] project: [$$35, $$39]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                      data-scan []<-[$$35, $$44] <- test.Customers
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance-check_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance-check_04.plan
index ab7cb7c..08f9f07 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance-check_04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance-check_04.plan
@@ -1,53 +1,106 @@
+distribute result [$$46]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$46] <- [{"arec": $$a, "brec": $$b, "ed": get-item($$63, 1)}] project: [$$46]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b, $$63])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$57, $$47))
           -- HYBRID_HASH_JOIN [$$57][$$47]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$57, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
+              union ($$b, $$60, $$b) ($$47, $$47, $$47) ($$82, $$73, $$63)
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (and(get-item($$82, 0), lt($$47, $$48))) project: [$$b, $$47, $$82]
                   -- STREAM_SELECT  |PARTITIONED|
+                    assign [$$82] <- [edit-distance-check($$49, $$b.getField(4), 3)] project: [$$47, $$48, $$b, $$82]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$47, $$49, $$48, $$b])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                          unnest-map [$$48, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$62, 1, $$62, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$62)
                               -- STABLE_SORT [$$62(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                  unnest-map [$$62] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 2, 3, 21, false, 1, $$49)
+                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                      select (edit-distance-list-is-filterable($$49, 3))
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$49] <- [$$58.getField(4)] project: [$$47, $$49]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                                  data-scan []<-[$$47, $$58] <- test.Customers
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  assign [$$73] <- [edit-distance-check($$49, $$59, 3)] project: [$$60, $$47, $$73]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$60, $$59, $$47, $$49])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (and(get-item(edit-distance-check($$49, $$59, 3), 0), lt($$47, $$61)))
                         -- NESTED_LOOP  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$59] <- [$$60.getField(4)]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                data-scan []<-[$$61, $$60] <- test.Customers
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            select (not(edit-distance-list-is-filterable($$49, 3)))
                             -- STREAM_SELECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                replicate
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$49] <- [$$58.getField(4)] project: [$$47, $$49]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                        data-scan []<-[$$47, $$58] <- test.Customers
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance_02.plan
index 1fdd9ca..ad96ed3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance_02.plan
@@ -1,51 +1,102 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"arec": $$a, "brec": $$b}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$43, $$35))
           -- HYBRID_HASH_JOIN [$$43][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$43, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              union ($$b, $$46, $$b) ($$35, $$35, $$35)
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (and(lt($$35, $$36), get-item(edit-distance-check($$39, $$b.getField(4), 2), 0))) project: [$$b, $$35]
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$35, $$39, $$36, $$b])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers2.Customers2)  |PARTITIONED|
+                        unnest-map [$$36, $$b] <- index-search("Customers2", 0, "Default", "test", "Customers2", true, false, 1, $$48, 1, $$48, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$48)
                             -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers2.interests_index)  |PARTITIONED|
+                                unnest-map [$$48] <- index-search("interests_index", 4, "Default", "test", "Customers2", true, true, 2, 2, 21, false, 1, $$39)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    select (edit-distance-list-is-filterable($$39, 2))
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$39] <- [$$44.getField(4)] project: [$$35, $$39]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                                data-scan []<-[$$35, $$44] <- test.Customers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$46, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (and(lt($$35, $$47), get-item(edit-distance-check($$39, $$45, 2), 0)))
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$45] <- [$$46.getField(4)]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.Customers2)  |PARTITIONED|
+                              data-scan []<-[$$47, $$46] <- test.Customers2
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          select (not(edit-distance-list-is-filterable($$39, 2)))
                           -- STREAM_SELECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$39] <- [$$44.getField(4)] project: [$$35, $$39]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                      data-scan []<-[$$35, $$44] <- test.Customers
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance_03.plan
index 382f807..1681bb7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance_03.plan
@@ -1,51 +1,102 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"arec": $$a, "brec": $$b}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$43, $$35))
           -- HYBRID_HASH_JOIN [$$43][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$43, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              union ($$b, $$46, $$b) ($$35, $$35, $$35)
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (and(lt($$35, $$36), get-item(edit-distance-check($$39, $$b.getField(4), 2), 0))) project: [$$b, $$35]
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$35, $$39, $$36, $$b])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$36, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$48, 1, $$48, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$48)
                             -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$48] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 2, 2, 21, false, 1, $$39)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    select (edit-distance-list-is-filterable($$39, 2))
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$39] <- [$$44.getField(4)] project: [$$35, $$39]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                                data-scan []<-[$$35, $$44] <- test.Customers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$46, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (and(lt($$35, $$47), get-item(edit-distance-check($$39, $$45, 2), 0)))
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$45] <- [$$46.getField(4)]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                              data-scan []<-[$$47, $$46] <- test.Customers
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          select (not(edit-distance-list-is-filterable($$39, 2)))
                           -- STREAM_SELECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$39] <- [$$44.getField(4)] project: [$$35, $$39]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                      data-scan []<-[$$35, $$44] <- test.Customers
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance_04.plan
index 59bc5b8..67a2547 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance_04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-edit-distance_04.plan
@@ -1,53 +1,106 @@
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"arec": $$a, "brec": $$b, "ed": get-item($$63, 1)}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b, $$63])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$57, $$46))
           -- HYBRID_HASH_JOIN [$$57][$$46]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$57, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$46]  |PARTITIONED|
+              union ($$b, $$60, $$b) ($$46, $$46, $$46) ($$82, $$73, $$63)
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (and(get-item($$82, 0), lt($$46, $$47))) project: [$$b, $$46, $$82]
                   -- STREAM_SELECT  |PARTITIONED|
+                    assign [$$82] <- [edit-distance-check($$49, $$b.getField(4), 2)] project: [$$46, $$47, $$b, $$82]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$46, $$49, $$47, $$b])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                          unnest-map [$$47, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$62, 1, $$62, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$62)
                               -- STABLE_SORT [$$62(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                  unnest-map [$$62] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 2, 2, 21, false, 1, $$49)
+                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                      select (edit-distance-list-is-filterable($$49, 2))
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$49] <- [$$58.getField(4)] project: [$$46, $$49]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                                  data-scan []<-[$$46, $$58] <- test.Customers
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  assign [$$73] <- [edit-distance-check($$49, $$59, 2)] project: [$$60, $$46, $$73]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$60, $$59, $$46, $$49])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (and(get-item(edit-distance-check($$49, $$59, 2), 0), lt($$46, $$61)))
                         -- NESTED_LOOP  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$59] <- [$$60.getField(4)]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                data-scan []<-[$$61, $$60] <- test.Customers
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            select (not(edit-distance-list-is-filterable($$49, 2)))
                             -- STREAM_SELECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                replicate
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$49] <- [$$58.getField(4)] project: [$$46, $$49]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                        data-scan []<-[$$46, $$58] <- test.Customers
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-fuzzyeq-edit-distance_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-fuzzyeq-edit-distance_02.plan
index e39f17b..7b809e6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-fuzzyeq-edit-distance_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-fuzzyeq-edit-distance_02.plan
@@ -1,51 +1,102 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"arec": $$a, "brec": $$b}] project: [$$33]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$42, $$34))
           -- HYBRID_HASH_JOIN [$$42][$$34]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$42]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$42, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
+              union ($$b, $$45, $$b) ($$34, $$34, $$34)
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (and(lt($$34, $$35), get-item(edit-distance-check($$38, $$b.getField(4), 3), 0))) project: [$$b, $$34]
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$34, $$38, $$35, $$b])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers2.Customers2)  |PARTITIONED|
+                        unnest-map [$$35, $$b] <- index-search("Customers2", 0, "Default", "test", "Customers2", true, false, 1, $$47, 1, $$47, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$47)
                             -- STABLE_SORT [$$47(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers2.interests_index)  |PARTITIONED|
+                                unnest-map [$$47] <- index-search("interests_index", 4, "Default", "test", "Customers2", true, true, 2, 3, 21, false, 1, $$38)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    select (edit-distance-list-is-filterable($$38, 3))
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$38] <- [$$43.getField(4)] project: [$$34, $$38]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                                data-scan []<-[$$34, $$43] <- test.Customers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$45, $$34])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (and(lt($$34, $$46), get-item(edit-distance-check($$38, $$44, 3), 0)))
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$44] <- [$$45.getField(4)]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.Customers2)  |PARTITIONED|
+                              data-scan []<-[$$46, $$45] <- test.Customers2
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          select (not(edit-distance-list-is-filterable($$38, 3)))
                           -- STREAM_SELECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$38] <- [$$43.getField(4)] project: [$$34, $$38]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                      data-scan []<-[$$34, $$43] <- test.Customers
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-fuzzyeq-edit-distance_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-fuzzyeq-edit-distance_03.plan
index 96186f4..9125e66 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-fuzzyeq-edit-distance_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-fuzzyeq-edit-distance_03.plan
@@ -1,51 +1,102 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"arec": $$a, "brec": $$b}] project: [$$33]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$42, $$34))
           -- HYBRID_HASH_JOIN [$$42][$$34]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$42]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$42, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
+              union ($$b, $$45, $$b) ($$34, $$34, $$34)
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (and(lt($$34, $$35), get-item(edit-distance-check($$38, $$b.getField(4), 3), 0))) project: [$$b, $$34]
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$34, $$38, $$35, $$b])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$35, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$47, 1, $$47, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$47)
                             -- STABLE_SORT [$$47(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$47] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 2, 3, 21, false, 1, $$38)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    select (edit-distance-list-is-filterable($$38, 3))
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$38] <- [$$43.getField(4)] project: [$$34, $$38]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                                data-scan []<-[$$34, $$43] <- test.Customers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$45, $$34])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (and(lt($$34, $$46), get-item(edit-distance-check($$38, $$44, 3), 0)))
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$44] <- [$$45.getField(4)]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                              data-scan []<-[$$46, $$45] <- test.Customers
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          select (not(edit-distance-list-is-filterable($$38, 3)))
                           -- STREAM_SELECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$38] <- [$$43.getField(4)] project: [$$34, $$38]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                      data-scan []<-[$$34, $$43] <- test.Customers
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-fuzzyeq-jaccard_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-fuzzyeq-jaccard_02.plan
index 336840b..4761111 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-fuzzyeq-jaccard_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-fuzzyeq-jaccard_02.plan
@@ -1,25 +1,50 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"arec": $$a, "brec": $$b}] project: [$$33]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$42, $$34))
           -- HYBRID_HASH_JOIN [$$42][$$34]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$42]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$42, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
+              select (and(lt($$34, $$35), get-item(similarity-jaccard-check($$38, $$b.getField(4), 0.7), 0))) project: [$$b, $$34]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$34, $$38, $$35, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.Customers2.Customers2)  |PARTITIONED|
+                    unnest-map [$$35, $$b] <- index-search("Customers2", 0, "Default", "test", "Customers2", true, false, 1, $$44, 1, $$44, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$44)
                         -- STABLE_SORT [$$44(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers2.interests_index)  |PARTITIONED|
+                            unnest-map [$$44] <- index-search("interests_index", 4, "Default", "test", "Customers2", true, true, 1, 0.7, 21, false, 1, $$38)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$38] <- [$$43.getField(4)] project: [$$34, $$38]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                    data-scan []<-[$$34, $$43] <- test.Customers
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-fuzzyeq-jaccard_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-fuzzyeq-jaccard_03.plan
index a08ef41..81f3c80 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-fuzzyeq-jaccard_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-fuzzyeq-jaccard_03.plan
@@ -1,25 +1,50 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"arec": $$a, "brec": $$b}] project: [$$33]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$42, $$34))
           -- HYBRID_HASH_JOIN [$$42][$$34]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$42]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$42, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
+              select (and(lt($$34, $$35), get-item(similarity-jaccard-check($$38, $$b.getField(4), 0.7), 0))) project: [$$b, $$34]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$34, $$38, $$35, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                    unnest-map [$$35, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$44, 1, $$44, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$44)
                         -- STABLE_SORT [$$44(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                            unnest-map [$$44] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 1, 0.7, 21, false, 1, $$38)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$38] <- [$$43.getField(4)] project: [$$34, $$38]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                    data-scan []<-[$$34, $$43] <- test.Customers
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard-check_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard-check_02.plan
index 572a9b9..19e440d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard-check_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard-check_02.plan
@@ -1,25 +1,50 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"arec": $$a, "brec": $$b}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$43, $$35))
           -- HYBRID_HASH_JOIN [$$43][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$43, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              select (and(lt($$35, $$36), get-item(similarity-jaccard-check($$39, $$b.getField(4), 0.7), 0))) project: [$$b, $$35]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$35, $$39, $$36, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.Customers2.Customers2)  |PARTITIONED|
+                    unnest-map [$$36, $$b] <- index-search("Customers2", 0, "Default", "test", "Customers2", true, false, 1, $$45, 1, $$45, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$45)
                         -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers2.interests_index)  |PARTITIONED|
+                            unnest-map [$$45] <- index-search("interests_index", 4, "Default", "test", "Customers2", true, true, 1, 0.7, 21, false, 1, $$39)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$39] <- [$$44.getField(4)] project: [$$35, $$39]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                    data-scan []<-[$$35, $$44] <- test.Customers
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard-check_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard-check_03.plan
index 0452e66..70f2b35 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard-check_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard-check_03.plan
@@ -1,25 +1,50 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"arec": $$a, "brec": $$b}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$43, $$35))
           -- HYBRID_HASH_JOIN [$$43][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$43, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              select (and(lt($$35, $$36), get-item(similarity-jaccard-check($$39, $$b.getField(4), 0.7), 0))) project: [$$b, $$35]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$35, $$39, $$36, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                    unnest-map [$$36, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$45, 1, $$45, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$45)
                         -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                            unnest-map [$$45] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 1, 0.7, 21, false, 1, $$39)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$39] <- [$$44.getField(4)] project: [$$35, $$39]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                    data-scan []<-[$$35, $$44] <- test.Customers
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard-check_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard-check_04.plan
index f76eaa7..3f866ed 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard-check_04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard-check_04.plan
@@ -1,26 +1,52 @@
+distribute result [$$46]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$46] <- [{"arec": $$a, "brec": $$b, "jacc": get-item($$61, 1)}] project: [$$46]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b, $$61])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$57, $$47))
           -- HYBRID_HASH_JOIN [$$57][$$47]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$57, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
+              select (and(get-item($$61, 0), lt($$47, $$48))) project: [$$b, $$61, $$47]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$61] <- [similarity-jaccard-check($$49, $$b.getField(4), 0.7)] project: [$$47, $$48, $$b, $$61]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$47, $$49, $$48, $$b])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                      unnest-map [$$48, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$59, 1, $$59, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$59)
                           -- STABLE_SORT [$$59(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                              unnest-map [$$59] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 1, 0.7, 21, false, 1, $$49)
+                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                exchange
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  assign [$$49] <- [$$58.getField(4)] project: [$$47, $$49]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                      data-scan []<-[$$47, $$58] <- test.Customers
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard_02.plan
index 572a9b9..19e440d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard_02.plan
@@ -1,25 +1,50 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"arec": $$a, "brec": $$b}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$43, $$35))
           -- HYBRID_HASH_JOIN [$$43][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$43, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              select (and(lt($$35, $$36), get-item(similarity-jaccard-check($$39, $$b.getField(4), 0.7), 0))) project: [$$b, $$35]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$35, $$39, $$36, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.Customers2.Customers2)  |PARTITIONED|
+                    unnest-map [$$36, $$b] <- index-search("Customers2", 0, "Default", "test", "Customers2", true, false, 1, $$45, 1, $$45, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$45)
                         -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers2.interests_index)  |PARTITIONED|
+                            unnest-map [$$45] <- index-search("interests_index", 4, "Default", "test", "Customers2", true, true, 1, 0.7, 21, false, 1, $$39)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$39] <- [$$44.getField(4)] project: [$$35, $$39]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                    data-scan []<-[$$35, $$44] <- test.Customers
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard_03.plan
index 0452e66..70f2b35 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard_03.plan
@@ -1,25 +1,50 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"arec": $$a, "brec": $$b}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$43, $$35))
           -- HYBRID_HASH_JOIN [$$43][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$43, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              select (and(lt($$35, $$36), get-item(similarity-jaccard-check($$39, $$b.getField(4), 0.7), 0))) project: [$$b, $$35]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$35, $$39, $$36, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                    unnest-map [$$36, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$45, 1, $$45, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$45)
                         -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                            unnest-map [$$45] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 1, 0.7, 21, false, 1, $$39)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$39] <- [$$44.getField(4)] project: [$$35, $$39]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                    data-scan []<-[$$35, $$44] <- test.Customers
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard_04.plan
index 6b8b2f1..6d0121e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard_04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/olist-jaccard_04.plan
@@ -1,26 +1,52 @@
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"arec": $$a, "brec": $$b, "jacc": get-item($$61, 1)}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b, $$61])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$57, $$46))
           -- HYBRID_HASH_JOIN [$$57][$$46]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$57, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$46]  |PARTITIONED|
+              select (and(get-item($$61, 0), lt($$46, $$47))) project: [$$b, $$61, $$46]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$61] <- [similarity-jaccard-check($$49, $$b.getField(4), 0.7)] project: [$$46, $$47, $$b, $$61]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$46, $$49, $$47, $$b])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                      unnest-map [$$47, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$59, 1, $$59, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$59)
                           -- STABLE_SORT [$$59(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                              unnest-map [$$59] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 1, 0.7, 21, false, 1, $$49)
+                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                exchange
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  assign [$$49] <- [$$58.getField(4)] project: [$$46, $$49]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                      data-scan []<-[$$46, $$58] <- test.Customers
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-fuzzyeq-jaccard_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-fuzzyeq-jaccard_02.plan
index 336840b..527152a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-fuzzyeq-jaccard_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-fuzzyeq-jaccard_02.plan
@@ -1,25 +1,50 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"arec": $$a, "brec": $$b}] project: [$$33]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$42, $$34))
           -- HYBRID_HASH_JOIN [$$42][$$34]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$42]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$42, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
+              select (and(lt($$34, $$35), get-item(similarity-jaccard-check($$38, $$b.getField(4), 0.7), 0))) project: [$$b, $$34]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$34, $$38, $$35, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.Customers2.Customers2)  |PARTITIONED|
+                    unnest-map [$$35, $$b] <- index-search("Customers2", 0, "Default", "test", "Customers2", true, false, 1, $$44, 1, $$44, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$44)
                         -- STABLE_SORT [$$44(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers2.interests_index)  |PARTITIONED|
+                            unnest-map [$$44] <- index-search("interests_index", 4, "Default", "test", "Customers2", true, true, 1, 0.7, 22, false, 1, $$38)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$38] <- [$$43.getField(4)] project: [$$34, $$38]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                    data-scan []<-[$$34, $$43] <- test.Customers
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-fuzzyeq-jaccard_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-fuzzyeq-jaccard_03.plan
index a08ef41..140101b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-fuzzyeq-jaccard_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-fuzzyeq-jaccard_03.plan
@@ -1,25 +1,50 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"arec": $$a, "brec": $$b}] project: [$$33]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$42, $$34))
           -- HYBRID_HASH_JOIN [$$42][$$34]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$42]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$42, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
+              select (and(lt($$34, $$35), get-item(similarity-jaccard-check($$38, $$b.getField(4), 0.7), 0))) project: [$$b, $$34]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$34, $$38, $$35, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                    unnest-map [$$35, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$44, 1, $$44, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$44)
                         -- STABLE_SORT [$$44(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                            unnest-map [$$44] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 1, 0.7, 22, false, 1, $$38)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$38] <- [$$43.getField(4)] project: [$$34, $$38]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                    data-scan []<-[$$34, $$43] <- test.Customers
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard-check_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard-check_02.plan
index 572a9b9..bea5acb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard-check_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard-check_02.plan
@@ -1,25 +1,50 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"arec": $$a, "brec": $$b}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$43, $$35))
           -- HYBRID_HASH_JOIN [$$43][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$43, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              select (and(lt($$35, $$36), get-item(similarity-jaccard-check($$39, $$b.getField(4), 0.7), 0))) project: [$$b, $$35]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$35, $$39, $$36, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.Customers2.Customers2)  |PARTITIONED|
+                    unnest-map [$$36, $$b] <- index-search("Customers2", 0, "Default", "test", "Customers2", true, false, 1, $$45, 1, $$45, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$45)
                         -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers2.interests_index)  |PARTITIONED|
+                            unnest-map [$$45] <- index-search("interests_index", 4, "Default", "test", "Customers2", true, true, 1, 0.7, 22, false, 1, $$39)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$39] <- [$$44.getField(4)] project: [$$35, $$39]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                    data-scan []<-[$$35, $$44] <- test.Customers
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard-check_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard-check_03.plan
index 0452e66..4b92305 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard-check_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard-check_03.plan
@@ -1,25 +1,50 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"arec": $$a, "brec": $$b}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$43, $$35))
           -- HYBRID_HASH_JOIN [$$43][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$43, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              select (and(lt($$35, $$36), get-item(similarity-jaccard-check($$39, $$b.getField(4), 0.7), 0))) project: [$$b, $$35]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$35, $$39, $$36, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                    unnest-map [$$36, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$45, 1, $$45, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$45)
                         -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                            unnest-map [$$45] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 1, 0.7, 22, false, 1, $$39)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$39] <- [$$44.getField(4)] project: [$$35, $$39]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                    data-scan []<-[$$35, $$44] <- test.Customers
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard-check_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard-check_04.plan
index f76eaa7..08d569c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard-check_04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard-check_04.plan
@@ -1,26 +1,52 @@
+distribute result [$$46]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$46] <- [{"arec": $$a, "brec": $$b, "jacc": get-item($$61, 1)}] project: [$$46]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b, $$61])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$57, $$47))
           -- HYBRID_HASH_JOIN [$$57][$$47]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$57, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
+              select (and(get-item($$61, 0), lt($$47, $$48))) project: [$$b, $$61, $$47]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$61] <- [similarity-jaccard-check($$49, $$b.getField(4), 0.7)] project: [$$47, $$48, $$b, $$61]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$47, $$49, $$48, $$b])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                      unnest-map [$$48, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$59, 1, $$59, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$59)
                           -- STABLE_SORT [$$59(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                              unnest-map [$$59] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 1, 0.7, 22, false, 1, $$49)
+                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                exchange
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  assign [$$49] <- [$$58.getField(4)] project: [$$47, $$49]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                      data-scan []<-[$$47, $$58] <- test.Customers
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard_02.plan
index 572a9b9..bea5acb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard_02.plan
@@ -1,25 +1,50 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"arec": $$a, "brec": $$b}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$43, $$35))
           -- HYBRID_HASH_JOIN [$$43][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$43, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              select (and(lt($$35, $$36), get-item(similarity-jaccard-check($$39, $$b.getField(4), 0.7), 0))) project: [$$b, $$35]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$35, $$39, $$36, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.Customers2.Customers2)  |PARTITIONED|
+                    unnest-map [$$36, $$b] <- index-search("Customers2", 0, "Default", "test", "Customers2", true, false, 1, $$45, 1, $$45, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$45)
                         -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers2.interests_index)  |PARTITIONED|
+                            unnest-map [$$45] <- index-search("interests_index", 4, "Default", "test", "Customers2", true, true, 1, 0.7, 22, false, 1, $$39)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$39] <- [$$44.getField(4)] project: [$$35, $$39]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                    data-scan []<-[$$35, $$44] <- test.Customers
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard_03.plan
index 0452e66..4b92305 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard_03.plan
@@ -1,25 +1,50 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"arec": $$a, "brec": $$b}] project: [$$34]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$43, $$35))
           -- HYBRID_HASH_JOIN [$$43][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$43, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              select (and(lt($$35, $$36), get-item(similarity-jaccard-check($$39, $$b.getField(4), 0.7), 0))) project: [$$b, $$35]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$35, $$39, $$36, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                    unnest-map [$$36, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$45, 1, $$45, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$45)
                         -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                            unnest-map [$$45] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 1, 0.7, 22, false, 1, $$39)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$39] <- [$$44.getField(4)] project: [$$35, $$39]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                    data-scan []<-[$$35, $$44] <- test.Customers
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard_04.plan
index 6b8b2f1..6b2a10b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard_04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/ulist-jaccard_04.plan
@@ -1,26 +1,52 @@
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"arec": $$a, "brec": $$b, "jacc": get-item($$61, 1)}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b, $$61])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$57, $$46))
           -- HYBRID_HASH_JOIN [$$57][$$46]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+              data-scan []<-[$$57, $$a] <- test.Customers
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$46]  |PARTITIONED|
+              select (and(get-item($$61, 0), lt($$46, $$47))) project: [$$b, $$61, $$46]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$61] <- [similarity-jaccard-check($$49, $$b.getField(4), 0.7)] project: [$$46, $$47, $$b, $$61]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$46, $$49, $$47, $$b])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                      unnest-map [$$47, $$b] <- index-search("Customers", 0, "Default", "test", "Customers", true, false, 1, $$59, 1, $$59, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$59)
                           -- STABLE_SORT [$$59(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                              unnest-map [$$59] <- index-search("interests_index", 4, "Default", "test", "Customers", true, true, 1, 0.7, 22, false, 1, $$49)
+                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                exchange
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  assign [$$49] <- [$$58.getField(4)] project: [$$46, $$49]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                      data-scan []<-[$$46, $$58] <- test.Customers
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-fuzzyeq-jaccard_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-fuzzyeq-jaccard_02.plan
index a1a21d9..e7ccec2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-fuzzyeq-jaccard_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-fuzzyeq-jaccard_02.plan
@@ -1,25 +1,50 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"arec": $$a, "brec": $$b}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$46, $$36))
           -- HYBRID_HASH_JOIN [$$46][$$36]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$46]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$46, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+              select (and(lt($$36, $$37), get-item(similarity-jaccard-check($$40, word-tokens($$b.getField(2)), 0.5), 0))) project: [$$b, $$36]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$36, $$40, $$37, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                    unnest-map [$$37, $$b] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$49, 1, $$49, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$49)
                         -- STABLE_SORT [$$49(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.CSX.keyword_index)  |PARTITIONED|
+                            unnest-map [$$49] <- index-search("keyword_index", 4, "Default", "test", "CSX", true, true, 1, 0.5, 21, false, 1, $$40)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$40] <- [word-tokens($$48.getField(2))] project: [$$36, $$40]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                    data-scan []<-[$$36, $$48] <- test.DBLP
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-fuzzyeq-jaccard_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-fuzzyeq-jaccard_03.plan
index 025274c..c5e62dd 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-fuzzyeq-jaccard_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-fuzzyeq-jaccard_03.plan
@@ -1,25 +1,50 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"arec": $$a, "brec": $$b}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$46, $$36))
           -- HYBRID_HASH_JOIN [$$46][$$36]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$46]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$46, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+              select (and(lt($$36, $$37), get-item(similarity-jaccard-check($$40, word-tokens($$b.getField(2)), 0.5), 0))) project: [$$b, $$36]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$36, $$40, $$37, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                    unnest-map [$$37, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$49, 1, $$49, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$49)
                         -- STABLE_SORT [$$49(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.keyword_index)  |PARTITIONED|
+                            unnest-map [$$49] <- index-search("keyword_index", 4, "Default", "test", "DBLP", true, true, 1, 0.5, 21, false, 1, $$40)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$40] <- [word-tokens($$48.getField(2))] project: [$$36, $$40]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                    data-scan []<-[$$36, $$48] <- test.DBLP
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard-check-after-btree-access.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard-check-after-btree-access.plan
index 792cf8f..4ad9902 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard-check-after-btree-access.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard-check-after-btree-access.plan
@@ -1,35 +1,70 @@
+distribute result [$$53]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$53] <- [{"t1": $$56, "t2": $$57, "sim": get-item(similarity-jaccard-check(word-tokens($$60), $$59, 0.6), 1)}] project: [$$53]
     -- ASSIGN  |PARTITIONED|
+      project ([$$60, $$56, $$57, $$59])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$69, $$56))
           -- HYBRID_HASH_JOIN [$$69][$$56]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$69]  |PARTITIONED|
+              assign [$$60] <- [$$t1.getField(5)] project: [$$60, $$69]
               -- ASSIGN  |PARTITIONED|
+                assign [$$69, $$t1] <- [$$56, $$71] project: [$$69, $$t1]
                 -- ASSIGN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    replicate
                     -- REPLICATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                        unnest-map [$$56, $$71] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$72, true, false, false)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$72] <- [20]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$56]  |PARTITIONED|
+              select (and(neq($$57, $$56), get-item(similarity-jaccard-check($$58, $$59, 0.6), 0))) project: [$$56, $$57, $$59]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$59] <- [word-tokens($$t2.getField(5))] project: [$$56, $$58, $$57, $$59]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$56, $$58, $$57, $$t2])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                      unnest-map [$$57, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$74, 1, $$74, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$74)
                           -- STABLE_SORT [$$74(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.TweetMessages.msgTextIx)  |PARTITIONED|
+                              unnest-map [$$74] <- index-search("msgTextIx", 4, "Default", "test", "TweetMessages", true, true, 1, 0.6, 21, false, 1, $$58)
+                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                exchange
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  assign [$$58] <- [word-tokens($$71.getField(5))] project: [$$56, $$58]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      replicate
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                          unnest-map [$$56, $$71] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$72, true, false, false)
+                                          -- BTREE_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$72] <- [20]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard-check_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard-check_02.plan
index 3d53c70..6c3238b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard-check_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard-check_02.plan
@@ -1,25 +1,50 @@
+distribute result [$$36]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$36] <- [{"arec": $$a, "brec": $$b}] project: [$$36]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$47, $$37))
           -- HYBRID_HASH_JOIN [$$47][$$37]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$47, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+              select (and(lt($$37, $$38), get-item(similarity-jaccard-check($$41, word-tokens($$b.getField(2)), 0.5), 0))) project: [$$b, $$37]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$37, $$41, $$38, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                    unnest-map [$$38, $$b] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$50, 1, $$50, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$50)
                         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.CSX.keyword_index)  |PARTITIONED|
+                            unnest-map [$$50] <- index-search("keyword_index", 4, "Default", "test", "CSX", true, true, 1, 0.5, 21, false, 1, $$41)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$41] <- [word-tokens($$49.getField(2))] project: [$$37, $$41]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                    data-scan []<-[$$37, $$49] <- test.DBLP
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard-check_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard-check_03.plan
index 6a14525..c281852 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard-check_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard-check_03.plan
@@ -1,25 +1,50 @@
+distribute result [$$36]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$36] <- [{"arec": $$a, "brec": $$b}] project: [$$36]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$47, $$37))
           -- HYBRID_HASH_JOIN [$$47][$$37]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$47, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+              select (and(lt($$37, $$38), get-item(similarity-jaccard-check($$41, word-tokens($$b.getField(2)), 0.5), 0))) project: [$$b, $$37]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$37, $$41, $$38, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                    unnest-map [$$38, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$50, 1, $$50, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$50)
                         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.keyword_index)  |PARTITIONED|
+                            unnest-map [$$50] <- index-search("keyword_index", 4, "Default", "test", "DBLP", true, true, 1, 0.5, 21, false, 1, $$41)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$41] <- [word-tokens($$49.getField(2))] project: [$$37, $$41]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                    data-scan []<-[$$37, $$49] <- test.DBLP
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard-check_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard-check_04.plan
index 623f0c5..c973504 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard-check_04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard-check_04.plan
@@ -1,28 +1,56 @@
+distribute result [$$48]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$48] <- [{"arec": $$a, "brec": $$b, "jacc": get-item(similarity-jaccard-check(word-tokens($$55), $$52, 0.5), 1)}] project: [$$48]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$55, $$b, $$52])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$61, $$49))
           -- HYBRID_HASH_JOIN [$$61][$$49]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$61]  |PARTITIONED|
+              assign [$$55] <- [$$a.getField(2)]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                  data-scan []<-[$$61, $$a] <- test.DBLP
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$49]  |PARTITIONED|
+              select (and(get-item(similarity-jaccard-check($$51, $$52, 0.5), 0), lt($$49, $$50))) project: [$$b, $$52, $$49]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$52] <- [word-tokens($$b.getField(2))]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$49, $$51, $$50, $$b])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                      unnest-map [$$50, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$64, 1, $$64, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$64)
                           -- STABLE_SORT [$$64(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.keyword_index)  |PARTITIONED|
+                              unnest-map [$$64] <- index-search("keyword_index", 4, "Default", "test", "DBLP", true, true, 1, 0.5, 21, false, 1, $$51)
+                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                exchange
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  assign [$$51] <- [word-tokens($$63.getField(2))] project: [$$49, $$51]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                      data-scan []<-[$$49, $$63] <- test.DBLP
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard_02.plan
index 3d53c70..6c3238b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard_02.plan
@@ -1,25 +1,50 @@
+distribute result [$$36]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$36] <- [{"arec": $$a, "brec": $$b}] project: [$$36]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$47, $$37))
           -- HYBRID_HASH_JOIN [$$47][$$37]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$47, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+              select (and(lt($$37, $$38), get-item(similarity-jaccard-check($$41, word-tokens($$b.getField(2)), 0.5), 0))) project: [$$b, $$37]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$37, $$41, $$38, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                    unnest-map [$$38, $$b] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$50, 1, $$50, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$50)
                         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.CSX.keyword_index)  |PARTITIONED|
+                            unnest-map [$$50] <- index-search("keyword_index", 4, "Default", "test", "CSX", true, true, 1, 0.5, 21, false, 1, $$41)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$41] <- [word-tokens($$49.getField(2))] project: [$$37, $$41]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                    data-scan []<-[$$37, $$49] <- test.DBLP
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard_03.plan
index 6a14525..c281852 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard_03.plan
@@ -1,25 +1,50 @@
+distribute result [$$36]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$36] <- [{"arec": $$a, "brec": $$b}] project: [$$36]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$47, $$37))
           -- HYBRID_HASH_JOIN [$$47][$$37]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+              data-scan []<-[$$47, $$a] <- test.DBLP
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+              select (and(lt($$37, $$38), get-item(similarity-jaccard-check($$41, word-tokens($$b.getField(2)), 0.5), 0))) project: [$$b, $$37]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$37, $$41, $$38, $$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                    unnest-map [$$38, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$50, 1, $$50, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$50)
                         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.keyword_index)  |PARTITIONED|
+                            unnest-map [$$50] <- index-search("keyword_index", 4, "Default", "test", "DBLP", true, true, 1, 0.5, 21, false, 1, $$41)
+                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$41] <- [word-tokens($$49.getField(2))] project: [$$37, $$41]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                    data-scan []<-[$$37, $$49] <- test.DBLP
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard_04.plan
index 2616a99..d2484f3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard_04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/word-jaccard_04.plan
@@ -1,28 +1,56 @@
+distribute result [$$47]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$47] <- [{"arec": $$a, "brec": $$b, "jacc": get-item(similarity-jaccard-check(word-tokens($$55), $$52, 0.5), 1)}] project: [$$47]
     -- ASSIGN  |PARTITIONED|
+      project ([$$a, $$55, $$b, $$52])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$61, $$48))
           -- HYBRID_HASH_JOIN [$$61][$$48]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$61]  |PARTITIONED|
+              assign [$$55] <- [$$a.getField(2)]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                  data-scan []<-[$$61, $$a] <- test.DBLP
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+              select (and(get-item(similarity-jaccard-check($$51, $$52, 0.5), 0), lt($$48, $$49))) project: [$$b, $$52, $$48]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$52] <- [word-tokens($$b.getField(2))]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$48, $$51, $$49, $$b])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                      unnest-map [$$49, $$b] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$64, 1, $$64, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$64)
                           -- STABLE_SORT [$$64(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.keyword_index)  |PARTITIONED|
+                              unnest-map [$$64] <- index-search("keyword_index", 4, "Default", "test", "DBLP", true, true, 1, 0.5, 21, false, 1, $$51)
+                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                exchange
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  assign [$$51] <- [word-tokens($$63.getField(2))] project: [$$48, $$51]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                      data-scan []<-[$$48, $$63] <- test.DBLP
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch-2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch-2.plan
index cfa80ac..55497ff 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch-2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch-2.plan
@@ -1,25 +1,50 @@
+distribute result [$$64]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$64] <- [{"f": $$57, "b": $$b}] project: [$$64]
     -- ASSIGN  |PARTITIONED|
+      project ([$$b, $$57])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (lt($$67, $$68))
           -- NESTED_LOOP  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              assign [$$67] <- [$$b.getField("fee")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.Bar)  |PARTITIONED|
+                    data-scan []<-[$$66, $$b] <- test.Bar
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- BROADCAST_EXCHANGE  |PARTITIONED|
+              assign [$$68] <- [$$57.getField("avg")]
               -- ASSIGN  |UNPARTITIONED|
+                assign [$$57] <- [{"foo_avg": $$69}] project: [$$57]
                 -- ASSIGN  |UNPARTITIONED|
+                  aggregate [$$69] <- [agg-global-sql-avg($$71)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$71] <- [agg-local-sql-avg($$55)]
                       -- AGGREGATE  |PARTITIONED|
+                        assign [$$55] <- [$$f.getField("fee")] project: [$$55]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$f])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.Foo)  |PARTITIONED|
+                              data-scan []<-[$$65, $$f] <- test.Foo
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch-3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch-3.plan
index 561e6d5..ab2d8ee 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch-3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch-3.plan
@@ -1,19 +1,38 @@
+distribute result [$$64]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$64] <- [{"f": $$57, "b": $$b}] project: [$$64]
     -- ASSIGN  |PARTITIONED|
+      select (lt($$b.getField("fee"), $$69)) project: [$$57, $$b]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$57, $$69, $$b])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (test.Bar)  |PARTITIONED|
+            data-scan []<-[$$66, $$b] <- test.Bar
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                assign [$$69] <- [$$57.getField("avg")]
                 -- ASSIGN  |UNPARTITIONED|
+                  assign [$$57] <- [{"foo_avg": $$67}] project: [$$57]
                   -- ASSIGN  |UNPARTITIONED|
+                    aggregate [$$67] <- [agg-global-sql-avg($$71)]
                     -- AGGREGATE  |UNPARTITIONED|
+                      exchange
                       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                        aggregate [$$71] <- [agg-local-sql-avg($$55)]
                         -- AGGREGATE  |PARTITIONED|
+                          assign [$$55] <- [$$f.getField("fee")] project: [$$55]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$f])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.Foo)  |PARTITIONED|
+                                data-scan []<-[$$65, $$f] <- test.Foo
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch.plan
index 0c6cf9b..dc9bb54 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch.plan
@@ -1,25 +1,50 @@
+distribute result [$$52]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$52] <- [{"b": $$b}] project: [$$52]
     -- ASSIGN  |PARTITIONED|
+      project ([$$b])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (lt($$60, $$61))
           -- NESTED_LOOP  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              assign [$$60] <- [$$b.getField("fee")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$b])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.Bar)  |PARTITIONED|
+                    data-scan []<-[$$53, $$b] <- test.Bar
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- BROADCAST_EXCHANGE  |PARTITIONED|
+              assign [$$61] <- [get-item($$48, 0)] project: [$$61]
               -- ASSIGN  |UNPARTITIONED|
+                aggregate [$$48] <- [listify($$55)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  aggregate [$$55] <- [agg-global-sql-avg($$63)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$63] <- [agg-local-sql-avg($$45)]
                       -- AGGREGATE  |PARTITIONED|
+                        assign [$$45] <- [$$58.getField("fee")] project: [$$45]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$58])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.Foo)  |PARTITIONED|
+                              data-scan []<-[$$59, $$58] <- test.Foo
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-super-key_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-super-key_01.plan
index bafb0e3..4f94d49 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-super-key_01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-super-key_01.plan
@@ -1,19 +1,38 @@
+distribute result [$$37]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$37] <- [{"l_partkey": $$39}] project: [$$37]
     -- ASSIGN  |PARTITIONED|
+      project ([$$39])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (and(eq($$39, $$41), eq($$44, $$45), eq($$46, $$42)))
           -- HYBRID_HASH_JOIN [$$39, $$44, $$46][$$41, $$45, $$42]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$39, $$44, $$46]  |PARTITIONED|
+              assign [$$46, $$44] <- [$$li.getField(2), $$li.getField(5)] project: [$$39, $$44, $$46]
               -- ASSIGN  |PARTITIONED|
+                project ([$$39, $$li])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (`join-super-key_1`.LineItems)  |PARTITIONED|
+                    data-scan []<-[$$39, $$40, $$li] <- `join-super-key_1`.LineItems
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$41, $$45, $$42]  |PARTITIONED|
+              assign [$$45] <- [$$ps.getField(3)] project: [$$41, $$45, $$42]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (`join-super-key_1`.PartSupp)  |PARTITIONED|
+                  data-scan []<-[$$41, $$42, $$ps] <- `join-super-key_1`.PartSupp
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-super-key_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-super-key_02.plan
index cc2777f..97f59e8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-super-key_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-super-key_02.plan
@@ -1,19 +1,38 @@
+distribute result [$$37]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$37] <- [{"l_partkey": $$41}] project: [$$37]
     -- ASSIGN  |PARTITIONED|
+      project ([$$41])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (and(eq($$41, $$39), eq($$44, $$45), eq($$46, $$40)))
           -- HYBRID_HASH_JOIN [$$39, $$45, $$40][$$41, $$44, $$46]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$39, $$45, $$40]  |PARTITIONED|
+              assign [$$45] <- [$$ps.getField(3)] project: [$$39, $$45, $$40]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (`join-super-key_01`.PartSupp)  |PARTITIONED|
+                  data-scan []<-[$$39, $$40, $$ps] <- `join-super-key_01`.PartSupp
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$41, $$44, $$46]  |PARTITIONED|
+              assign [$$46, $$44] <- [$$li.getField(2), $$li.getField(5)] project: [$$41, $$44, $$46]
               -- ASSIGN  |PARTITIONED|
+                project ([$$41, $$li])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (`join-super-key_01`.LineItems)  |PARTITIONED|
+                    data-scan []<-[$$41, $$42, $$li] <- `join-super-key_01`.LineItems
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/fnds_join_ds.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/fnds_join_ds.plan
index 75fe2a1..a330052 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/fnds_join_ds.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/fnds_join_ds.plan
@@ -1,21 +1,42 @@
+distribute result [$$49]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$49] <- [{"$1": $$53}] project: [$$49]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$53] <- [agg-sql-sum($$54)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$54] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$51, $$52))
               -- HYBRID_HASH_JOIN [$$51][$$52]  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$51]  |PARTITIONED|
+                  assign [$$51] <- [$$tpcds.getField("ca_address_id")] project: [$$51]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (asterix.tpcds-datagen.customer_address.1.0)  |PARTITIONED|
+                      data-scan []<-[$$tpcds] <- asterix.tpcds-datagen.customer_address.1.0
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$52]  |PARTITIONED|
+                  assign [$$52] <- [$$t1.getField("aid")] project: [$$52]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$t1])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+                        data-scan []<-[$$50, $$t1] <- test.t1
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/inner_right_corr.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/inner_right_corr.plan
index 409f99b..db55da3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/inner_right_corr.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/inner_right_corr.plan
@@ -1,51 +1,96 @@
+distribute result [$$75]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$75] <- [{"a": $$73}] project: [$$75]
     -- ASSIGN  |PARTITIONED|
+      project ([$$73])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- PRE_CLUSTERED_GROUP_BY[$$76]  |PARTITIONED|
-                  {
+          group by ([$$94 := $$76]) decor ([]) {
+                    aggregate [$$73] <- [listify($$78)]
                     -- AGGREGATE  |LOCAL|
+                      aggregate [$$78] <- [agg-sql-count(1)]
                       -- AGGREGATE  |LOCAL|
+                        select (not(is-missing($$93)))
                         -- STREAM_SELECT  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- PRE_CLUSTERED_GROUP_BY[$$76]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$76)
               -- STABLE_SORT [$$76(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$93, $$76])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      left outer join (eq($$76, $$92))
                       -- HYBRID_HASH_JOIN [$$76][$$92]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$76]  |PARTITIONED|
+                          project ([$$76])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+                              data-scan []<-[$$76, $$t1] <- test.t1
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$92]  |PARTITIONED|
+                          assign [$$93] <- [true]
                           -- ASSIGN  |PARTITIONED|
+                            unnest $$82 <- scan-collection($$83) project: [$$92]
                             -- UNNEST  |PARTITIONED|
+                              project ([$$92, $$83])
                               -- STREAM_PROJECT  |PARTITIONED|
-                                -- SUBPLAN  |PARTITIONED|
-                                        {
+                                subplan {
+                                          aggregate [$$83] <- [listify($$85)]
                                           -- AGGREGATE  |LOCAL|
+                                            select (eq($$87, $$88))
                                             -- STREAM_SELECT  |LOCAL|
+                                              assign [$$88] <- [$$85.getField("b")]
                                               -- ASSIGN  |LOCAL|
+                                                unnest $$85 <- scan-collection($$90)
                                                 -- UNNEST  |LOCAL|
+                                                  nested tuple source
                                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- SUBPLAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (true)
                                     -- NESTED_LOOP  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$90] <- [$$91.getField("x")] project: [$$92, $$90]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+                                            data-scan []<-[$$92, $$91] <- test.t1
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        assign [$$87] <- [$$81.getField("y")] project: [$$87]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$81])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.t2)  |PARTITIONED|
+                                              data-scan []<-[$$84, $$81] <- test.t2
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/nested_query_with_bcast.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/nested_query_with_bcast.plan
index 1761df7..896daea 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/nested_query_with_bcast.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/nested_query_with_bcast.plan
@@ -1,34 +1,65 @@
+commit
 -- COMMIT  |PARTITIONED|
+  project ([$$37])
   -- STREAM_PROJECT  |PARTITIONED|
+    exchange
     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+      insert into test.targetDataset from record: $$39 partitioned by [$$37]
       -- INSERT_DELETE  |PARTITIONED|
+        exchange
         -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+          assign [$$37] <- [$$39.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            assign [$$39] <- [cast(check-unknown(put-autogenerated-key($$35, "tid")))] project: [$$39]
             -- ASSIGN  |PARTITIONED|
+              assign [$$35] <- [{"$1": object-merge($$x, {"full-country": $$34})}] project: [$$35]
               -- ASSIGN  |PARTITIONED|
+                project ([$$34, $$x])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$40]  |PARTITIONED|
-                            {
+                    group by ([$$45 := $$40]) decor ([$$x]) {
+                              aggregate [$$34] <- [listify($$33)]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$44)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$40]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$40)
                         -- STABLE_SORT [$$40(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$40]  |PARTITIONED|
+                            project ([$$x, $$33, $$44, $$40])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                left outer join (eq($$41, $$43))
                                 -- HYBRID_HASH_JOIN [$$43][$$41]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$43] <- [$$x.getField(1)]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.tweetDataset)  |PARTITIONED|
+                                        data-scan []<-[$$40, $$x] <- test.tweetDataset
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$44, $$33] <- [true, $$c.getField(1)] project: [$$33, $$44, $$41]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.countryDataset)  |PARTITIONED|
+                                        data-scan []<-[$$41, $$c] <- test.countryDataset
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/nlj_partitioning_property_1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/nlj_partitioning_property_1.plan
index 576f967..f430d5c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/nlj_partitioning_property_1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/nlj_partitioning_property_1.plan
@@ -1,28 +1,56 @@
+distribute result [$$75]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$75] <- [{"count": $$82}] project: [$$75]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$82] <- [agg-sql-sum($$84)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$84] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$76, $$78))
               -- HYBRID_HASH_JOIN [$$76][$$78]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$76])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (tpch.Supplier)  |PARTITIONED|
+                      data-scan []<-[$$76, $$s] <- tpch.Supplier
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  join (true)
                   -- NESTED_LOOP  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$78])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (tpch.Partsupp)  |PARTITIONED|
+                          data-scan []<-[$$77, $$78, $$ps] <- tpch.Partsupp
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                      project ([])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (tpch.Part)  |PARTITIONED|
+                          data-scan []<-[$$79, $$p] <- tpch.Part
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/nlj_partitioning_property_2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/nlj_partitioning_property_2.plan
index 7fa1d25..b120922 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/nlj_partitioning_property_2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/nlj_partitioning_property_2.plan
@@ -1,28 +1,56 @@
+distribute result [$$72]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$72] <- [{"count": $$77}] project: [$$72]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$77] <- [agg-sql-sum($$78)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$78] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (true)
               -- NESTED_LOOP  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (tpch.Supplier)  |PARTITIONED|
+                      data-scan []<-[$$73, $$s] <- tpch.Supplier
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  join (true)
                   -- NESTED_LOOP  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (tpch.Partsupp)  |PARTITIONED|
+                          data-scan []<-[$$74, $$75, $$ps] <- tpch.Partsupp
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                      project ([])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (tpch.Part)  |PARTITIONED|
+                          data-scan []<-[$$76, $$p] <- tpch.Part
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/query-ASTERIXDB-2986.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/query-ASTERIXDB-2986.plan
index 499b6f8..b45ba35 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/query-ASTERIXDB-2986.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/query-ASTERIXDB-2986.plan
@@ -1,35 +1,70 @@
+distribute result [$$70]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$70] <- [{"$1": $$80}] project: [$$70]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$80] <- [agg-sql-sum($$89)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$89] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$78, numeric-add($$86, $$71)))
               -- NESTED_LOOP  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  assign [$$78] <- [numeric-add($$o.getField("o_custkey"), $$71)] project: [$$71, $$78]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$o, $$71])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$81, $$82))
                         -- HYBRID_HASH_JOIN [$$82][$$81]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$82]  |PARTITIONED|
+                            assign [$$82] <- [$$o.getField("o_orderkey")]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$o])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test1.orders)  |PARTITIONED|
+                                  data-scan []<-[$$72, $$o, $$73] <- test1.orders
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$81]  |PARTITIONED|
+                            assign [$$81] <- [to-bigint($$71)]
                             -- ASSIGN  |PARTITIONED|
+                              assign [$$71] <- [$$l.getField("l_orderkey")] project: [$$71]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$l])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test1.lineitem)  |PARTITIONED|
+                                    data-scan []<-[$$74, $$l, $$75] <- test1.lineitem
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  assign [$$86] <- [$$c.getField("c_custkey")] project: [$$86]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$c])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test1.customer)  |PARTITIONED|
+                        data-scan []<-[$$76, $$c, $$77] <- test1.customer
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/leftouterjoin/loj-03-no-listify.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/leftouterjoin/loj-03-no-listify.plan
index bbf6c62..fc5403a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/leftouterjoin/loj-03-no-listify.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/leftouterjoin/loj-03-no-listify.plan
@@ -1,117 +1,210 @@
+distribute result [$$256]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$256] <- [{"taskId": $$taskId, "cnt_all": $$266, "cnt_x": $$283, "cnt_y": $$284, "cnt_z": $$243.getField(0)}] project: [$$256]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$taskId(ASC) ]  |PARTITIONED|
+        order (ASC, $$taskId)
         -- STABLE_SORT [$$taskId(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$taskId, $$266, $$283, $$284, $$243])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                left outer join (eq($$taskId, $$taskId))
                 -- HYBRID_HASH_JOIN [$$taskId][$$taskId]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$taskId, $$266, $$283, $$284])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        left outer join (eq($$taskId, $$taskId))
                         -- HYBRID_HASH_JOIN [$$taskId][$$taskId]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$taskId, $$266, $$283])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                left outer join (eq($$taskId, $$taskId))
                                 -- HYBRID_HASH_JOIN [$$taskId][$$taskId]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$taskId(ASC)] HASH:[$$taskId]  |PARTITIONED|
+                                    group by ([$$taskId := $$295]) decor ([]) {
+                                              aggregate [$$266] <- [agg-sql-sum($$294)]
+                                              -- AGGREGATE  |LOCAL|
+                                                nested tuple source
+                                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                           }
                                     -- SORT_GROUP_BY[$$295]  |PARTITIONED|
-                                            {
-                                              -- AGGREGATE  |LOCAL|
-                                                -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$295]  |PARTITIONED|
+                                        group by ([$$295 := $$258]) decor ([]) {
+                                                  aggregate [$$294] <- [agg-sql-count(1)]
+                                                  -- AGGREGATE  |LOCAL|
+                                                    nested tuple source
+                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                               }
                                         -- SORT_GROUP_BY[$$258]  |PARTITIONED|
-                                                {
-                                                  -- AGGREGATE  |LOCAL|
-                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$tasks, $$258] <- [$$tasks, $$259] project: [$$258]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$259] <- [$$tasks.getField("taskId")]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$tasks])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.tasks)  |PARTITIONED|
+                                                          data-scan []<-[$$263, $$tasks] <- test.tasks
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$283] <- [{"taskId": $$taskId, "cnt_x": $$274}.getField(0)] project: [$$283, $$taskId]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- SORT_GROUP_BY[$$297]  |PARTITIONED|
-                                                {
+                                        group by ([$$taskId := $$297]) decor ([]) {
+                                                  aggregate [$$274] <- [agg-sql-sum($$296)]
                                                   -- AGGREGATE  |LOCAL|
+                                                    nested tuple source
                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                               }
+                                        -- SORT_GROUP_BY[$$297]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$297]  |PARTITIONED|
-                                            -- SORT_GROUP_BY[$$259]  |PARTITIONED|
-                                                    {
+                                            group by ([$$297 := $$259]) decor ([]) {
+                                                      aggregate [$$296] <- [agg-sql-count(1)]
                                                       -- AGGREGATE  |LOCAL|
+                                                        nested tuple source
                                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                    }
+                                                   }
+                                            -- SORT_GROUP_BY[$$259]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                select (eq($$tasks.getField("status"), "x")) project: [$$259]
                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    replicate
                                                     -- REPLICATE  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        assign [$$259] <- [$$tasks.getField("taskId")]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          project ([$$tasks])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN (test.tasks)  |PARTITIONED|
+                                                              data-scan []<-[$$263, $$tasks] <- test.tasks
+                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$284] <- [{"taskId": $$taskId, "cnt_y": $$275}.getField(0)] project: [$$284, $$taskId]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- SORT_GROUP_BY[$$299]  |PARTITIONED|
-                                        {
+                                group by ([$$taskId := $$299]) decor ([]) {
+                                          aggregate [$$275] <- [agg-sql-sum($$298)]
                                           -- AGGREGATE  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- SORT_GROUP_BY[$$299]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$299]  |PARTITIONED|
-                                    -- SORT_GROUP_BY[$$260]  |PARTITIONED|
-                                            {
+                                    group by ([$$299 := $$260]) decor ([]) {
+                                              aggregate [$$298] <- [agg-sql-count(1)]
                                               -- AGGREGATE  |LOCAL|
+                                                nested tuple source
                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                           }
+                                    -- SORT_GROUP_BY[$$260]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        select (eq($$tasks.getField("status"), "y")) project: [$$260]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$tasks, $$260] <- [$$tasks, $$259] project: [$$tasks, $$260]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              replicate
                                               -- REPLICATE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  assign [$$259] <- [$$tasks.getField("taskId")]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    project ([$$tasks])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.tasks)  |PARTITIONED|
+                                                        data-scan []<-[$$263, $$tasks] <- test.tasks
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    assign [$$243] <- [{"taskId": $$taskId, "cnt_z": $$276}] project: [$$243, $$taskId]
                     -- ASSIGN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$301]  |PARTITIONED|
-                                {
+                        group by ([$$taskId := $$301]) decor ([]) {
+                                  aggregate [$$276] <- [agg-sql-sum($$300)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$301]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$301]  |PARTITIONED|
-                            -- SORT_GROUP_BY[$$261]  |PARTITIONED|
-                                    {
+                            group by ([$$301 := $$261]) decor ([]) {
+                                      aggregate [$$300] <- [agg-sql-count(1)]
                                       -- AGGREGATE  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- SORT_GROUP_BY[$$261]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (eq($$tasks.getField("status"), "z")) project: [$$261]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$tasks, $$261] <- [$$tasks, $$259] project: [$$tasks, $$261]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      replicate
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$259] <- [$$tasks.getField("taskId")]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$tasks])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.tasks)  |PARTITIONED|
+                                                data-scan []<-[$$263, $$tasks] <- test.tasks
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/leftouterjoin/query-ASTERIXDB-2857.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/leftouterjoin/query-ASTERIXDB-2857.plan
index 79d50d8..c5f1ca1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/leftouterjoin/query-ASTERIXDB-2857.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/leftouterjoin/query-ASTERIXDB-2857.plan
@@ -1,34 +1,68 @@
+distribute result [$$133]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$133] <- [{"t0_unique1": $$145, "t1_unique1": $$146, "t2_unique1": $#3}] project: [$$133]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$145(ASC), $$146(ASC), $#3(ASC) ]  |PARTITIONED|
+        order (ASC, $$145) (ASC, $$146) (ASC, $#3)
         -- STABLE_SORT [$$145(ASC), $$146(ASC), $#3(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$145, $$146, $#3])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                left outer join (eq(numeric-add($$136, $$138), $$143))
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    assign [$$143] <- [numeric-multiply(2, $$137)] project: [$$145, $$146, $$136, $$143]
                     -- ASSIGN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$136, $$137))
                         -- HYBRID_HASH_JOIN [$$136][$$137]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$136]  |PARTITIONED|
+                            assign [$$145] <- [$$tenk.getField(0)] project: [$$145, $$136]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                                unnest-map [$$136, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 0, 1, $$159, true, false, false)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$159] <- [2]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$137]  |PARTITIONED|
+                            assign [$$146] <- [$$tenk.getField(0)] project: [$$146, $$137]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                                unnest-map [$$137, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 0, 1, $$162, true, false, false)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$162] <- [4]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    assign [$#3] <- [{"unique1": $$tenk.getField(0), "unique2": $$138}.getField(0)] project: [$#3, $$138]
                     -- ASSIGN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                        unnest-map [$$138, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 0, 1, $$165, true, false, false)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$165] <- [6]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/leftouterjoin/query-ASTERIXDB-2988.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/leftouterjoin/query-ASTERIXDB-2988.plan
index 8faa38b..b146918 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/leftouterjoin/query-ASTERIXDB-2988.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/leftouterjoin/query-ASTERIXDB-2988.plan
@@ -1,19 +1,38 @@
+distribute result [$$32]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"r1": $$r1, "x": $$ds1.getField(0), "y": $$ds1.getField(1)}] project: [$$32]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$r1(ASC) ]  |PARTITIONED|
+        order (ASC, $$r1)
         -- STABLE_SORT [$$r1(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$r1, $$ds1])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                left outer join (eq($$r1, $$34))
                 -- HYBRID_HASH_JOIN [$$r1][$$34]  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$r1]  |PARTITIONED|
+                    unnest $$r1 <- range(0, 4)
                     -- UNNEST  |UNPARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
+                    assign [$$34] <- [$$ds1.getField(1)]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$ds1])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.ds1)  |PARTITIONED|
+                          data-scan []<-[$$33, $$ds1] <- test.ds1
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-core.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-core.plan
index a88c8e6..94e34ea 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-core.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-core.plan
@@ -1,22 +1,44 @@
+distribute result [$$43]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$43] <- [{"aid": $$45, "bid": $$b.getField(0)}] project: [$$43]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$45(ASC) ]  |PARTITIONED|
+        order (ASC, $$45)
         -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$45, $$b])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                left outer join (eq($$47, $$48))
                 -- HYBRID_HASH_JOIN [$$47][$$48]  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
+                    assign [$$47] <- [$$a.getField(3)] project: [$$45, $$47]
                     -- ASSIGN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                        data-scan []<-[$$45, $$a] <- test.DBLP
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+                    assign [$$48] <- [$$b.getField(3)]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$b])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                          data-scan []<-[$$46, $$b] <- test.CSX
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-core_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-core_ps.plan
index a846224..0310f5b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-core_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-core_ps.plan
@@ -1,50 +1,100 @@
+distribute result [$$43]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$43] <- [{"aid": $$45, "bid": $$b.getField(0)}] project: [$$43]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$45)
         -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$45(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$56
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$45, $$b])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        left outer join (eq($$47, $$48))
                         -- HYBRID_HASH_JOIN [$$47][$$48]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
+                            assign [$$47] <- [$$a.getField(3)] project: [$$45, $$47]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                data-scan []<-[$$45, $$a] <- test.DBLP
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+                            assign [$$48] <- [$$b.getField(3)]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$b])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                                  data-scan []<-[$$46, $$b] <- test.CSX
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$56] <- [agg-range-map($$54, $$55)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$54, $$55] <- [agg-local-sampling($$45), agg-null-writer($$45)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$45])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$45, $$b])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  left outer join (eq($$47, $$48))
                                   -- HYBRID_HASH_JOIN [$$47][$$48]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
+                                      assign [$$47] <- [$$a.getField(3)] project: [$$45, $$47]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                          data-scan []<-[$$45, $$a] <- test.DBLP
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+                                      assign [$$48] <- [$$b.getField(3)]
                                       -- ASSIGN  |PARTITIONED|
+                                        project ([$$b])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                                            data-scan []<-[$$46, $$b] <- test.CSX
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-sugar.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-sugar.plan
index f754844..a1b414a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-sugar.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-sugar.plan
@@ -1,22 +1,44 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"aid": $$35, "bid": $$b.getField(0)}] project: [$$33]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$35(ASC) ]  |PARTITIONED|
+        order (ASC, $$35)
         -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$35, $$b])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                left outer join (eq($$37, $$38))
                 -- HYBRID_HASH_JOIN [$$37][$$38]  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                    assign [$$37] <- [$$a.getField(3)] project: [$$35, $$37]
                     -- ASSIGN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                        data-scan []<-[$$35, $$a] <- test.DBLP
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+                    assign [$$38] <- [$$b.getField(3)]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$b])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                          data-scan []<-[$$36, $$b] <- test.CSX
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-sugar_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-sugar_ps.plan
index 8f5e3eb..abfe2cb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-sugar_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-sugar_ps.plan
@@ -1,50 +1,100 @@
+distribute result [$$33]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"aid": $$35, "bid": $$b.getField(0)}] project: [$$33]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$35)
         -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$35(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$46
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$35, $$b])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        left outer join (eq($$37, $$38))
                         -- HYBRID_HASH_JOIN [$$37][$$38]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                            assign [$$37] <- [$$a.getField(3)] project: [$$35, $$37]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                data-scan []<-[$$35, $$a] <- test.DBLP
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+                            assign [$$38] <- [$$b.getField(3)]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$b])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                                  data-scan []<-[$$36, $$b] <- test.CSX
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$46] <- [agg-range-map($$44, $$45)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$44, $$45] <- [agg-local-sampling($$35), agg-null-writer($$35)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$35])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$35, $$b])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  left outer join (eq($$37, $$38))
                                   -- HYBRID_HASH_JOIN [$$37][$$38]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                                      assign [$$37] <- [$$a.getField(3)] project: [$$35, $$37]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                          data-scan []<-[$$35, $$a] <- test.DBLP
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+                                      assign [$$38] <- [$$b.getField(3)]
                                       -- ASSIGN  |PARTITIONED|
+                                        project ([$$b])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                                            data-scan []<-[$$36, $$b] <- test.CSX
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-super-key_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-super-key_01.plan
index bbfc442..5446096 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-super-key_01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-super-key_01.plan
@@ -1,29 +1,55 @@
+distribute result [$$48]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$48] <- [{"li": $$li, "partsupp": $$46}] project: [$$48]
     -- ASSIGN  |PARTITIONED|
+      project ([$$46, $$li])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- PRE_CLUSTERED_GROUP_BY[$$49, $$50]  |PARTITIONED|
-                  {
+          group by ([$$60 := $$49; $$61 := $$50]) decor ([$$li]) {
+                    aggregate [$$46] <- [listify($$ps)]
                     -- AGGREGATE  |LOCAL|
+                      select (not(is-missing($$59)))
                       -- STREAM_SELECT  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- PRE_CLUSTERED_GROUP_BY[$$49, $$50]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$49) (ASC, $$50)
               -- STABLE_SORT [$$49(ASC), $$50(ASC)]  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$49, $$50]  |PARTITIONED|
+                  project ([$$li, $$ps, $$59, $$49, $$50])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      left outer join (and(eq($$53, $$54), eq($$49, $$51), eq($$57, $$52)))
                       -- HYBRID_HASH_JOIN [$$53, $$49, $$57][$$54, $$51, $$52]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$53, $$49, $$57]  |PARTITIONED|
+                          assign [$$57, $$53] <- [$$li.getField(2), $$li.getField(5)]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (`loj-super-key_01`.LineItems)  |PARTITIONED|
+                              data-scan []<-[$$49, $$50, $$li] <- `loj-super-key_01`.LineItems
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$54, $$51, $$52]  |PARTITIONED|
+                          assign [$$59, $$54] <- [true, $$ps.getField(3)]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (`loj-super-key_01`.PartSupp)  |PARTITIONED|
+                              data-scan []<-[$$51, $$52, $$ps] <- `loj-super-key_01`.PartSupp
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-super-key_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-super-key_02.plan
index f42c8aa..13d0338 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-super-key_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/loj-super-key_02.plan
@@ -1,30 +1,57 @@
+distribute result [$$48]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$48] <- [{"partsupp": $$ps, "li": $$46}] project: [$$48]
     -- ASSIGN  |PARTITIONED|
+      project ([$$46, $$ps])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- PRE_CLUSTERED_GROUP_BY[$$49, $$50]  |PARTITIONED|
-                  {
+          group by ([$$60 := $$49; $$61 := $$50]) decor ([$$ps]) {
+                    aggregate [$$46] <- [listify($$li)]
                     -- AGGREGATE  |LOCAL|
+                      select (not(is-missing($$59)))
                       -- STREAM_SELECT  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- PRE_CLUSTERED_GROUP_BY[$$49, $$50]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$49) (ASC, $$50)
               -- STABLE_SORT [$$49(ASC), $$50(ASC)]  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$49, $$50]  |PARTITIONED|
+                  project ([$$ps, $$li, $$59, $$49, $$50])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      left outer join (and(eq($$53, $$54), eq($$51, $$49), eq($$57, $$50)))
                       -- HYBRID_HASH_JOIN [$$54, $$49, $$50][$$53, $$51, $$57]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$54, $$49, $$50]  |PARTITIONED|
+                          assign [$$54] <- [$$ps.getField(3)]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (`loj-super-key_02`.PartSupp)  |PARTITIONED|
+                              data-scan []<-[$$49, $$50, $$ps] <- `loj-super-key_02`.PartSupp
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$53, $$51, $$57]  |PARTITIONED|
+                          assign [$$59, $$57, $$53] <- [true, $$li.getField(2), $$li.getField(5)]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$51, $$li])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (`loj-super-key_02`.LineItems)  |PARTITIONED|
+                                data-scan []<-[$$51, $$52, $$li] <- `loj-super-key_02`.LineItems
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_1.plan
index 849a139..41f719f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_1.plan
@@ -1,12 +1,24 @@
+distribute result [$$36]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$36] <- [{"$1": $$39}] project: [$$36]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$39] <- [agg-global-sql-max($$40)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$40] <- [agg-local-sql-max($$34)]
           -- AGGREGATE  |PARTITIONED|
+            assign [$$34] <- [$$38.getField(0)] project: [$$34]
             -- ASSIGN  |PARTITIONED|
+              project ([$$38])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds)  |PARTITIONED|
+                  data-scan []<-[$$37, $$ds, $$38] <- test.ds
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_2.plan
index b679b2c6..7fbd81e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_2.plan
@@ -1,10 +1,20 @@
+distribute result [$$36]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$36] <- [{"$1": $$39}] project: [$$36]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$39] <- [agg-sql-sum($$41)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$41] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- BTREE_SEARCH (test.ds.primary_idx_ds)  |PARTITIONED|
+              unnest-map [$$37] <- index-search("primary_idx_ds", 0, "Default", "test", "ds", false, false, 0, 0, true, true, false)
+              -- BTREE_SEARCH  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_3.plan
index b679b2c6..1b03e30 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_3.plan
@@ -1,10 +1,20 @@
+distribute result [$$36]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$36] <- [{"$1": $$39}] project: [$$36]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$39] <- [agg-sql-sum($$40)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$40] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- BTREE_SEARCH (test.ds.primary_idx_ds)  |PARTITIONED|
+              unnest-map [$$37] <- index-search("primary_idx_ds", 0, "Default", "test", "ds", false, false, 0, 0, true, true, false)
+              -- BTREE_SEARCH  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_4.plan
index 849a139..1818bf1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/field_access_with_data_and_meta_4.plan
@@ -1,12 +1,24 @@
+distribute result [$$36]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$36] <- [{"$1": $$39}] project: [$$36]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$39] <- [agg-global-sql-max($$41)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$41] <- [agg-local-sql-max($$34)]
           -- AGGREGATE  |PARTITIONED|
+            assign [$$34] <- [$$ds.getField(0)] project: [$$34]
             -- ASSIGN  |PARTITIONED|
+              project ([$$ds])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds)  |PARTITIONED|
+                  data-scan []<-[$$37, $$ds, $$38] <- test.ds
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_01.plan
index 9dbe5c2..7fafd68 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_01.plan
@@ -1,9 +1,18 @@
+distribute result [$$16]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$16] <- [{"DS1": $$DS1}] project: [$$16]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$DS1.getField(0), "2"))
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$DS1])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (test.DS1)  |PARTITIONED|
+            data-scan []<-[$$17, $$DS1, $$18] <- test.DS1
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_02.plan
index cb90155..dde3309 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_02.plan
@@ -1,9 +1,18 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"DS1": $$DS1}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      project ([$$DS1])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DS1.DS1)  |PARTITIONED|
+          unnest-map [$$18, $$DS1, $$19] <- index-search("DS1", 0, "Default", "test", "DS1", false, false, 1, $$21, 1, $$22, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              assign [$$21, $$22] <- ["5", "5"]
               -- ASSIGN  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_03.plan
index 6f90d10..c1e91fc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_03.plan
@@ -1,9 +1,18 @@
+distribute result [$$16]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$16] <- [{"DS2": $$DS2}] project: [$$16]
     -- ASSIGN  |PARTITIONED|
+      project ([$$DS2])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DS2.DS2)  |PARTITIONED|
+          unnest-map [$$17, $$DS2, $$18] <- index-search("DS2", 0, "Default", "test", "DS2", false, false, 1, $$20, 1, $$21, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              assign [$$20, $$21] <- ["2", "2"]
               -- ASSIGN  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_04.plan
index 41bac78..8ea412b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_04.plan
@@ -1,9 +1,18 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"DS2": $$DS2}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$19.getField(0), "5")) project: [$$DS2]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$DS2, $$19])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (test.DS2)  |PARTITIONED|
+            data-scan []<-[$$18, $$DS2, $$19] <- test.DS2
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_05.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_05.plan
index 8e5ac32..66813cd 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_05.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_05.plan
@@ -1,23 +1,46 @@
+distribute result [$$29]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"ds2": $$ds2, "ds1": $$ds1}] project: [$$29]
     -- ASSIGN  |PARTITIONED|
+      project ([$$ds2, $$ds1])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$31(ASC) ]  |PARTITIONED|
+          order (ASC, $$31)
           -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$ds2, $$ds1, $$31])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$31, $$36))
                   -- HYBRID_HASH_JOIN [$$31][$$36]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$31]  |PARTITIONED|
+                      project ([$$ds2, $$31])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.DS2)  |PARTITIONED|
+                          data-scan []<-[$$31, $$ds2, $$32] <- test.DS2
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                      assign [$$36] <- [$$ds1.getField(0)]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$ds1])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.DS1)  |PARTITIONED|
+                            data-scan []<-[$$33, $$ds1, $$34] <- test.DS1
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_06.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_06.plan
index 03dbd6a..8f674bd 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_06.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_06.plan
@@ -1,18 +1,36 @@
+distribute result [$$32]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"ds1_meta_id": $$37, "ds2": $$ds2, "ds1": $$ds1}] project: [$$32]
     -- ASSIGN  |PARTITIONED|
+      project ([$$ds2, $$37, $$ds1])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$35(ASC) ]  |PARTITIONED|
+          order (ASC, $$35)
           -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$35, $$ds2, $$37, $$ds1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.DS1.DS1)  |PARTITIONED|
+                  unnest-map [$$37, $$ds1, $$38] <- index-search("DS1", 0, "Default", "test", "DS1", true, true, 1, $$35, 1, $$35, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$35)
                       -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+                          project ([$$35, $$ds2])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.DS2)  |PARTITIONED|
+                              data-scan []<-[$$35, $$ds2, $$36] <- test.DS2
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_07.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_07.plan
index b78648b..7b3810e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_07.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_07.plan
@@ -1,19 +1,38 @@
+distribute result [$$29]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"ds1": $$ds1, "ds2": $$ds2}] project: [$$29]
     -- ASSIGN  |PARTITIONED|
+      project ([$$ds1, $$ds2])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$33(ASC) ]  |PARTITIONED|
+          order (ASC, $$33)
           -- STABLE_SORT [$$33(ASC)]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$ds1, $$ds2, $$33])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.DS2.DS2)  |PARTITIONED|
+                  unnest-map [$$33, $$ds2, $$34] <- index-search("DS2", 0, "Default", "test", "DS2", true, true, 1, $$35, 1, $$35, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$35)
                       -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+                          assign [$$35] <- [$$ds1.getField(0)]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$ds1])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.DS1)  |PARTITIONED|
+                                data-scan []<-[$$31, $$ds1, $$32] <- test.DS1
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_08.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_08.plan
index f591cc0..fb1e655 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_08.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_08.plan
@@ -1,16 +1,32 @@
+distribute result [$$16]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$16] <- [{"DS1": $$DS1}] project: [$$16]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$DS1.getField(0), "2"))
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$DS1])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.DS1.DS1)  |PARTITIONED|
+            unnest-map [$$17, $$DS1, $$18] <- index-search("DS1", 0, "Default", "test", "DS1", false, false, 1, $$23, 1, $$23, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$23)
                 -- STABLE_SORT [$$23(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$23])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.DS1.id_sec_idx)  |PARTITIONED|
+                        unnest-map [$$22, $$23] <- index-search("id_sec_idx", 0, "Default", "test", "DS1", false, false, 1, $$20, 1, $$21, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$20, $$21] <- ["2", "2"]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_09.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_09.plan
index cb90155..dde3309 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_09.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_09.plan
@@ -1,9 +1,18 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"DS1": $$DS1}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      project ([$$DS1])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DS1.DS1)  |PARTITIONED|
+          unnest-map [$$18, $$DS1, $$19] <- index-search("DS1", 0, "Default", "test", "DS1", false, false, 1, $$21, 1, $$22, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              assign [$$21, $$22] <- ["5", "5"]
               -- ASSIGN  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_10.plan
index 3caccff..5210897 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_10.plan
@@ -1,23 +1,46 @@
+distribute result [$$29]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"ds2": $$ds2, "ds1": $$ds1}] project: [$$29]
     -- ASSIGN  |PARTITIONED|
+      project ([$$ds2, $$ds1])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$31(ASC) ]  |PARTITIONED|
+          order (ASC, $$31)
           -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              select (eq($$31, $$ds1.getField(0)))
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$ds2, $$31, $$ds1])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.DS1.DS1)  |PARTITIONED|
+                    unnest-map [$$33, $$ds1, $$34] <- index-search("DS1", 0, "Default", "test", "DS1", true, false, 1, $$39, 1, $$39, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$39)
                         -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$ds2, $$31, $$39])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.DS1.id_sec_idx)  |PARTITIONED|
+                                unnest-map [$$38, $$39] <- index-search("id_sec_idx", 0, "Default", "test", "DS1", true, true, 1, $$31, 1, $$31, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    project ([$$31, $$ds2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.DS2)  |PARTITIONED|
+                                        data-scan []<-[$$31, $$ds2, $$32] <- test.DS2
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_11.plan
index 03dbd6a..8f674bd 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/indexes_on_dataset_with_meta_11.plan
@@ -1,18 +1,36 @@
+distribute result [$$32]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"ds1_meta_id": $$37, "ds2": $$ds2, "ds1": $$ds1}] project: [$$32]
     -- ASSIGN  |PARTITIONED|
+      project ([$$ds2, $$37, $$ds1])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$35(ASC) ]  |PARTITIONED|
+          order (ASC, $$35)
           -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$35, $$ds2, $$37, $$ds1])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.DS1.DS1)  |PARTITIONED|
+                  unnest-map [$$37, $$ds1, $$38] <- index-search("DS1", 0, "Default", "test", "DS1", true, true, 1, $$35, 1, $$35, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$35)
                       -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+                          project ([$$35, $$ds2])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.DS2)  |PARTITIONED|
+                              data-scan []<-[$$35, $$ds2, $$36] <- test.DS2
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/with_clause_meta.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/with_clause_meta.plan
index 2fcabd6..c8c4000 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/with_clause_meta.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/meta/with_clause_meta.plan
@@ -1,37 +1,71 @@
+distribute result [$$118]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 5
     -- STREAM_LIMIT  |UNPARTITIONED|
+      assign [$$118] <- [{"age": $$127, "aid": $#1, "total": $$124}] project: [$$118]
       -- ASSIGN  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$#1(ASC) ]  |PARTITIONED|
+          limit 5
           -- STREAM_LIMIT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (topK: 5) (ASC, $#1)
               -- STABLE_SORT [topK: 5] [$#1(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  assign [$$127, $#1] <- [$$120.getField("age"), $$120.getField(0)] project: [$$127, $#1, $$124]
                   -- ASSIGN  |PARTITIONED|
+                    assign [$$120] <- [$$t2.getField(0)] project: [$$124, $$120]
                     -- ASSIGN  |PARTITIONED|
+                      unnest $$t2 <- scan-collection($$110) project: [$$124, $$t2]
                       -- UNNEST  |PARTITIONED|
+                        project ([$$110, $$124])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- PRE_CLUSTERED_GROUP_BY[$$119]  |PARTITIONED|
-                                    {
+                            group by ([$$series := $$119]) decor ([]) {
+                                      aggregate [$$110, $$124] <- [listify($$108), agg-sql-count($$108)]
                                       -- AGGREGATE  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- PRE_CLUSTERED_GROUP_BY[$$119]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$119)
                                 -- STABLE_SORT [$$119(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$119]  |PARTITIONED|
+                                    assign [$$108, $$119] <- [{"raw_data": $$106}, $$106.getField("series")] project: [$$108, $$119]
                                     -- ASSIGN  |PARTITIONED|
+                                      assign [$$106] <- [{"aid": $$125, "age": $$126}] project: [$$106]
                                       -- ASSIGN  |PARTITIONED|
+                                        project ([$$125, $$126])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            join (eq($$123, $$100))
                                             -- HYBRID_HASH_JOIN [$$100][$$123]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                assign [$$126, $$125, $$100] <- [$$a.getField("age"), $$122.getField(0), $$a.getField("hobby")] project: [$$125, $$126, $$100]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  project ([$$a, $$122])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.ds)  |PARTITIONED|
+                                                      data-scan []<-[$$121, $$a, $$122] <- test.ds
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              exchange
                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                unnest $$123 <- scan-collection(array: [ "soccer", "reading", "hiking", "tennis" ])
                                                 -- UNNEST  |UNPARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/micro_external_sort/micro_external_sort.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/micro_external_sort/micro_external_sort.plan
index ecff808..cf93f82 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/micro_external_sort/micro_external_sort.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/micro_external_sort/micro_external_sort.plan
@@ -1,25 +1,44 @@
+distribute result [$$162]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$162] <- [{"group": $$group, "sum_per_group": $$161}] project: [$$162]
     -- ASSIGN  |LOCAL|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |LOCAL|
-        -- PRE_CLUSTERED_GROUP_BY[$$163]  |LOCAL|
-                {
+        group by ([$$group := $$163]) decor ([]) {
+                  aggregate [$$161] <- [listify({"group_num": $$group_num, "sum": $$167})]
                   -- AGGREGATE  |LOCAL|
+                    order (ASC, $$167)
                     -- MICRO_STABLE_SORT [$$167(ASC)]  |LOCAL|
-                      -- MICRO_PRE_CLUSTERED_GROUP_BY[$$164]  |LOCAL|
-                              {
+                      group by ([$$group_num := $$164]) decor ([]) {
+                                aggregate [$$167] <- [agg-global-sql-sum($$174)]
                                 -- AGGREGATE  |LOCAL|
+                                  aggregate [$$174] <- [agg-local-sql-sum($$157)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- MICRO_PRE_CLUSTERED_GROUP_BY[$$164]  |LOCAL|
+                        order (ASC, $$164)
                         -- MICRO_STABLE_SORT [$$164(ASC)]  |LOCAL|
+                          assign [$$157] <- [$$143.getField(3)]
                           -- ASSIGN  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$163]  |LOCAL|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+            order (ASC, $$163)
             -- STABLE_SORT [$$163(ASC)]  |LOCAL|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                assign [$$163, $$164, $$143] <- [switch-case(true, eq(0, $$175), "one", eq(1, $$175), "two", eq(2, $$175), "three", null), switch-case(true, eq(0, $$176), "SUM_1s", eq(1, $$176), "SUM_2s", eq(2, $$176), "SUM_3s", null), {"id": $$i, "a": switch-case(true, eq(0, $$175), "one", eq(1, $$175), "two", eq(2, $$175), "three", null), "b": switch-case(true, eq(0, $$176), "SUM_1s", eq(1, $$176), "SUM_2s", eq(2, $$176), "SUM_3s", null), "c": switch-case(true, eq(0, $$176), 1, eq(1, $$176), 2, eq(2, $$176), 3, null)}] project: [$$164, $$143, $$163]
                 -- ASSIGN  |UNPARTITIONED|
+                  assign [$$176, $$175] <- [numeric-mod(numeric-div($$i, 3), 3), numeric-mod($$i, 3)]
                   -- ASSIGN  |UNPARTITIONED|
+                    unnest $$i <- range(0, 89999)
                     -- UNNEST  |UNPARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/multipart-dataverse/index/index-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/multipart-dataverse/index/index-01.plan
index ddb70e2..67c4b6c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/multipart-dataverse/index/index-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/multipart-dataverse/index/index-01.plan
@@ -1,15 +1,30 @@
+distribute result [$$l]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(eq($$l.getField(1), "Julio"), eq($$l.getField(2), "Isa")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$l])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (x.y.employee.employee)  |PARTITIONED|
+          unnest-map [$$18, $$l] <- index-search("employee", 0, "Default", "x/y", "employee", false, false, 1, $$27, 1, $$27, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+              order (ASC, $$27)
+              -- STABLE_SORT [$$27(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$27])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (x.y.employee.idx_employee_f_l_name)  |PARTITIONED|
+                      unnest-map [$$25, $$26, $$27] <- index-search("idx_employee_f_l_name", 0, "Default", "x/y", "employee", false, false, 2, $$21, $$22, 2, $$23, $$24, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$21, $$22, $$23, $$24] <- ["Julio", "Isa", "Julio", "Isa"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/multipart-dataverse/index/index-02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/multipart-dataverse/index/index-02.plan
index ddb70e2..67c4b6c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/multipart-dataverse/index/index-02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/multipart-dataverse/index/index-02.plan
@@ -1,15 +1,30 @@
+distribute result [$$l]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(eq($$l.getField(1), "Julio"), eq($$l.getField(2), "Isa")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$l])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (x.y.employee.employee)  |PARTITIONED|
+          unnest-map [$$18, $$l] <- index-search("employee", 0, "Default", "x/y", "employee", false, false, 1, $$27, 1, $$27, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+              order (ASC, $$27)
+              -- STABLE_SORT [$$27(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$27])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (x.y.employee.idx_employee_f_l_name)  |PARTITIONED|
+                      unnest-map [$$25, $$26, $$27] <- index-search("idx_employee_f_l_name", 0, "Default", "x/y", "employee", false, false, 2, $$21, $$22, 2, $$23, $$24, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$21, $$22, $$23, $$24] <- ["Julio", "Isa", "Julio", "Isa"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/ASTERIXDB-2199.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/ASTERIXDB-2199.plan
index 9887b10..a7b0602 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/ASTERIXDB-2199.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/ASTERIXDB-2199.plan
@@ -1,14 +1,28 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"first": $$first, "second": $$second}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      project ([$$first, $$second])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$36, $$37))
           -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
-              -- DATASOURCE_SCAN (Facebook.Friendship)  |PARTITIONED|
+              data-scan []<-[$$36, $$first] <- Facebook.Friendship
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
-              -- DATASOURCE_SCAN (Facebook.Friendship)  |PARTITIONED|
+              data-scan []<-[$$37, $$second] <- Facebook.Friendship
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_ps.plan
index d41058b..6312b51 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_ps.plan
@@ -1,77 +1,148 @@
+distribute result [$$49]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$49] <- [{"tweetid1": $$52, "count1": $$58, "t2info": $$48}] project: [$$49]
     -- ASSIGN  |PARTITIONED|
+      project ([$$48, $$58, $$52])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$67)
           -- STABLE_SORT [$$67(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$67(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$75
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- PRE_CLUSTERED_GROUP_BY[$$54]  |PARTITIONED|
-                              {
+                      group by ([$$67 := $$54]) decor ([$$58; $$52]) {
+                                aggregate [$$48] <- [listify({"tweetid2": $$61, "count2": $$59})]
                                 -- AGGREGATE  |LOCAL|
+                                  select (not(is-missing($$55)))
                                   -- STREAM_SELECT  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- PRE_CLUSTERED_GROUP_BY[$$54]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$54) (ASC, $$55)
                           -- STABLE_SORT [$$54(ASC), $$55(ASC)]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$54]  |PARTITIONED|
+                              select (eq($$58, $$59)) retain-untrue ($$55 <- missing)
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$61, $$59] <- [$$57.getField(0), $$57.getField(7)] project: [$$52, $$58, $$54, $$55, $$61, $$59]
                                 -- ASSIGN  |PARTITIONED|
+                                  assign [$$57] <- [$$t2.getField(0)] project: [$$52, $$58, $$54, $$55, $$57]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$52, $$58, $$54, $$55, $$t2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                        left-outer-unnest-map [$$55, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$72, 1, $$72, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$72)
                                             -- STABLE_SORT [$$72(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$52, $$58, $$54, $$72])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                    left-outer-unnest-map [$$71, $$72] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$58, 1, $$58, true, true, true)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        assign [$$58, $$52] <- [$$65.getField(6), $$65.getField(0)] project: [$$54, $$58, $$52]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          assign [$$65] <- [$$t1.getField(0)] project: [$$54, $$65]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                              unnest-map [$$54, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$68, true, false, false)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$68] <- [10]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$75] <- [agg-range-map($$73, $$74)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$73, $$74] <- [agg-local-sampling($$67), agg-null-writer($$67)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$67])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- PRE_CLUSTERED_GROUP_BY[$$54]  |PARTITIONED|
-                                        {
+                                group by ([$$67 := $$54]) decor ([$$58; $$52]) {
+                                          aggregate [$$48] <- [listify({"tweetid2": $$61, "count2": $$59})]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$55)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- PRE_CLUSTERED_GROUP_BY[$$54]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$54) (ASC, $$55)
                                     -- STABLE_SORT [$$54(ASC), $$55(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$54]  |PARTITIONED|
+                                        select (eq($$58, $$59)) retain-untrue ($$55 <- missing)
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$61, $$59] <- [$$57.getField(0), $$57.getField(7)] project: [$$52, $$58, $$54, $$55, $$61, $$59]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$57] <- [$$t2.getField(0)] project: [$$52, $$58, $$54, $$55, $$57]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$52, $$58, $$54, $$55, $$t2])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                  left-outer-unnest-map [$$55, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$72, 1, $$72, true, true, true)
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      order (ASC, $$72)
                                                       -- STABLE_SORT [$$72(ASC)]  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          project ([$$52, $$58, $$54, $$72])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                              left-outer-unnest-map [$$71, $$72] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$58, 1, $$58, true, true, true)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$58, $$52] <- [$$65.getField(6), $$65.getField(0)] project: [$$54, $$58, $$52]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    assign [$$65] <- [$$t1.getField(0)] project: [$$54, $$65]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                        unnest-map [$$54, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$68, true, false, false)
+                                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            assign [$$68] <- [10]
                                                                             -- ASSIGN  |PARTITIONED|
+                                                                              empty-tuple-source
                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_ps.plan
index 1c961a8..3e0aecd 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_ps.plan
@@ -1,77 +1,148 @@
+distribute result [$$55]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$55] <- [{"tweetid1": $$67, "count1": $$73, "t2info": $$54}] project: [$$55]
     -- ASSIGN  |PARTITIONED|
+      project ([$$54, $$73, $$67])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$75)
           -- STABLE_SORT [$$75(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$75(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$83
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- PRE_CLUSTERED_GROUP_BY[$$60]  |PARTITIONED|
-                              {
+                      group by ([$$75 := $$60]) decor ([$$73; $$67]) {
+                                aggregate [$$54] <- [listify({"tweetid2": $$68, "count2": $$66})]
                                 -- AGGREGATE  |LOCAL|
+                                  select (not(is-missing($$61)))
                                   -- STREAM_SELECT  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- PRE_CLUSTERED_GROUP_BY[$$60]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$60) (ASC, $$61)
                           -- STABLE_SORT [$$60(ASC), $$61(ASC)]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$60]  |PARTITIONED|
+                              select (and(eq($$73, $$66), neq($$67, $$68))) retain-untrue ($$61 <- missing)
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$68, $$66] <- [$$64.getField(0), $$64.getField(7)] project: [$$67, $$73, $$60, $$61, $$68, $$66]
                                 -- ASSIGN  |PARTITIONED|
+                                  assign [$$64] <- [$$t2.getField(0)] project: [$$67, $$73, $$60, $$61, $$64]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$67, $$73, $$60, $$61, $$t2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                        left-outer-unnest-map [$$61, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$80, 1, $$80, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$80)
                                             -- STABLE_SORT [$$80(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$67, $$73, $$60, $$80])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                    left-outer-unnest-map [$$79, $$80] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$73, 1, $$73, true, true, true)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        assign [$$73, $$67] <- [$$62.getField(6), $$62.getField(0)] project: [$$60, $$73, $$67]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          assign [$$62] <- [$$t1.getField(0)] project: [$$60, $$62]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                              unnest-map [$$60, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$76, true, false, false)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$76] <- [10]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$83] <- [agg-range-map($$81, $$82)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$81, $$82] <- [agg-local-sampling($$75), agg-null-writer($$75)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$75])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- PRE_CLUSTERED_GROUP_BY[$$60]  |PARTITIONED|
-                                        {
+                                group by ([$$75 := $$60]) decor ([$$73; $$67]) {
+                                          aggregate [$$54] <- [listify({"tweetid2": $$68, "count2": $$66})]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$61)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- PRE_CLUSTERED_GROUP_BY[$$60]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$60) (ASC, $$61)
                                     -- STABLE_SORT [$$60(ASC), $$61(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$60]  |PARTITIONED|
+                                        select (and(eq($$73, $$66), neq($$67, $$68))) retain-untrue ($$61 <- missing)
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$68, $$66] <- [$$64.getField(0), $$64.getField(7)] project: [$$67, $$73, $$60, $$61, $$68, $$66]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$64] <- [$$t2.getField(0)] project: [$$67, $$73, $$60, $$61, $$64]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$67, $$73, $$60, $$61, $$t2])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                  left-outer-unnest-map [$$61, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$80, 1, $$80, true, true, true)
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      order (ASC, $$80)
                                                       -- STABLE_SORT [$$80(ASC)]  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          project ([$$67, $$73, $$60, $$80])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                              left-outer-unnest-map [$$79, $$80] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$73, 1, $$73, true, true, true)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$73, $$67] <- [$$62.getField(6), $$62.getField(0)] project: [$$60, $$73, $$67]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    assign [$$62] <- [$$t1.getField(0)] project: [$$60, $$62]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                        unnest-map [$$60, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$76, true, false, false)
+                                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            assign [$$76] <- [10]
                                                                             -- ASSIGN  |PARTITIONED|
+                                                                              empty-tuple-source
                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/ngram-contains-panic_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/ngram-contains-panic_ps.plan
index 5a051c1..fd8b566 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/ngram-contains-panic_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/ngram-contains-panic_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$17)
         -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$17(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$23
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField(0).getField(2), "Mu"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                        data-scan []<-[$$17, $$o] <- test.DBLP
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$23] <- [agg-range-map($$21, $$22)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$21, $$22] <- [agg-local-sampling($$17), agg-null-writer($$17)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$17])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField(0).getField(2), "Mu"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                  data-scan []<-[$$17, $$o] <- test.DBLP
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/ngram-contains_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/ngram-contains_ps.plan
index e0dd2e4..de8b7a3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/ngram-contains_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/ngram-contains_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
-          -- RANGE_PARTITION_EXCHANGE [$$17(ASC)]  |PARTITIONED|
+        order (ASC, $$18)
+        -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+          exchange
+          -- RANGE_PARTITION_EXCHANGE [$$18(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$26
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField(0).getField(2), "Multimedia"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                        unnest-map [$$18, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$23, 1, $$23, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                            order (ASC, $$23)
+                            -- STABLE_SORT [$$23(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                unnest-map [$$23] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 0, missing, 12, false, 1, $$22)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$22] <- ["Multimedia"]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$26] <- [agg-range-map($$24, $$25)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$24, $$25] <- [agg-local-sampling($$18), agg-null-writer($$18)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$18])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField(0).getField(2), "Multimedia"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                                  unnest-map [$$18, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$23, 1, $$23, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                                      order (ASC, $$23)
+                                      -- STABLE_SORT [$$23(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                          unnest-map [$$23] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 0, missing, 12, false, 1, $$22)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$22] <- ["Multimedia"]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-edit-distance-check-panic_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-edit-distance-check-panic_ps.plan
index bd53553..9caa4be 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-edit-distance-check-panic_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-edit-distance-check-panic_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$19)
         -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$19(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$25
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 3), 0))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                        data-scan []<-[$$19, $$c] <- test.Customers
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$25] <- [agg-range-map($$23, $$24)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$23, $$24] <- [agg-local-sampling($$19), agg-null-writer($$19)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$19])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 3), 0))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                  data-scan []<-[$$19, $$c] <- test.Customers
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-edit-distance-check_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-edit-distance-check_ps.plan
index 6e8c23d..9ac83dd 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-edit-distance-check_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-edit-distance-check_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
-          -- RANGE_PARTITION_EXCHANGE [$$19(ASC)]  |PARTITIONED|
+        order (ASC, $$20)
+        -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+          exchange
+          -- RANGE_PARTITION_EXCHANGE [$$20(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$28
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$20, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$25, 1, $$25, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                            order (ASC, $$25)
+                            -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$25] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$24)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$24] <- [array: [ "computers", "wine", "walking" ]]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$28] <- [agg-range-map($$26, $$27)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$26, $$27] <- [agg-local-sampling($$20), agg-null-writer($$20)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$20])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                                  unnest-map [$$20, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$25, 1, $$25, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                                      order (ASC, $$25)
+                                      -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                          unnest-map [$$25] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$24)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$24] <- [array: [ "computers", "wine", "walking" ]]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-edit-distance-panic_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-edit-distance-panic_ps.plan
index bd53553..9caa4be 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-edit-distance-panic_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-edit-distance-panic_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$19)
         -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$19(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$25
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 3), 0))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                        data-scan []<-[$$19, $$c] <- test.Customers
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$25] <- [agg-range-map($$23, $$24)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$23, $$24] <- [agg-local-sampling($$19), agg-null-writer($$19)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$19])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 3), 0))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                  data-scan []<-[$$19, $$c] <- test.Customers
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-edit-distance_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-edit-distance_ps.plan
index 6e8c23d..9ac83dd 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-edit-distance_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-edit-distance_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
-          -- RANGE_PARTITION_EXCHANGE [$$19(ASC)]  |PARTITIONED|
+        order (ASC, $$20)
+        -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+          exchange
+          -- RANGE_PARTITION_EXCHANGE [$$20(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$28
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$20, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$25, 1, $$25, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                            order (ASC, $$25)
+                            -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$25] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$24)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$24] <- [array: [ "computers", "wine", "walking" ]]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$28] <- [agg-range-map($$26, $$27)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$26, $$27] <- [agg-local-sampling($$20), agg-null-writer($$20)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$20])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                                  unnest-map [$$20, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$25, 1, $$25, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                                      order (ASC, $$25)
+                                      -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                          unnest-map [$$25] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$24)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$24] <- [array: [ "computers", "wine", "walking" ]]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-fuzzyeq-edit-distance_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-fuzzyeq-edit-distance_ps.plan
index d2b7dc5..e0f6d88 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-fuzzyeq-edit-distance_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/olist-fuzzyeq-edit-distance_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
-          -- RANGE_PARTITION_EXCHANGE [$$18(ASC)]  |PARTITIONED|
+        order (ASC, $$19)
+        -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+          exchange
+          -- RANGE_PARTITION_EXCHANGE [$$19(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$27
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$19, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$24, 1, $$24, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- STABLE_SORT [$$23(ASC)]  |PARTITIONED|
+                            order (ASC, $$24)
+                            -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$24] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$23)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$23] <- [array: [ "computers", "wine", "walking" ]]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$27] <- [agg-range-map($$25, $$26)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$25, $$26] <- [agg-local-sampling($$19), agg-null-writer($$19)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$19])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                                  unnest-map [$$19, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$24, 1, $$24, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$23(ASC)]  |PARTITIONED|
+                                      order (ASC, $$24)
+                                      -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                          unnest-map [$$24] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$23)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$23] <- [array: [ "computers", "wine", "walking" ]]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/word-contains_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/word-contains_ps.plan
index 5a051c1..06cbf5e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/word-contains_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-basic/word-contains_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$17)
         -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$17(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$23
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField(0).getField(2), "Multimedia"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                        data-scan []<-[$$17, $$o] <- test.DBLP
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$23] <- [agg-range-map($$21, $$22)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$21, $$22] <- [agg-local-sampling($$17), agg-null-writer($$17)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$17])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField(0).getField(2), "Multimedia"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                  data-scan []<-[$$17, $$o] <- test.DBLP
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-complex/olist-edit-distance-check-let-panic_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-complex/olist-edit-distance-check-let-panic_ps.plan
index b45a5fcb..0d125d8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-complex/olist-edit-distance-check-let-panic_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-complex/olist-edit-distance-check-let-panic_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$29)
         -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$29(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$35
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 3), 0))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                        data-scan []<-[$$29, $$c] <- test.Customers
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$35] <- [agg-range-map($$33, $$34)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$33, $$34] <- [agg-local-sampling($$29), agg-null-writer($$29)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$29])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 3), 0))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                  data-scan []<-[$$29, $$c] <- test.Customers
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-complex/olist-edit-distance-check-let_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-complex/olist-edit-distance-check-let_ps.plan
index 4dfcd7a..f176cf7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-complex/olist-edit-distance-check-let_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-complex/olist-edit-distance-check-let_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
-          -- RANGE_PARTITION_EXCHANGE [$$29(ASC)]  |PARTITIONED|
+        order (ASC, $$31)
+        -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+          exchange
+          -- RANGE_PARTITION_EXCHANGE [$$31(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$39
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$31, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$36, 1, $$36, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
+                            order (ASC, $$36)
+                            -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$36] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$35)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$35] <- [array: [ "computers", "wine", "walking" ]]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$39] <- [agg-range-map($$37, $$38)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$37, $$38] <- [agg-local-sampling($$31), agg-null-writer($$31)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$31])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 1), 0))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                                  unnest-map [$$31, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$36, 1, $$36, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
+                                      order (ASC, $$36)
+                                      -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                          unnest-map [$$36] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$35)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$35] <- [array: [ "computers", "wine", "walking" ]]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01_ps.plan
index 3920a9f..50b646a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01_ps.plan
@@ -1,167 +1,328 @@
+distribute result [$$69]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$69] <- [{"tweet": {"id": $$80, "topics": $$87}, "similar-tweets": $$68}] project: [$$69]
     -- ASSIGN  |PARTITIONED|
+      project ([$$68, $$80, $$87])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$89)
           -- STABLE_SORT [$$89(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$89(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$110
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- PRE_CLUSTERED_GROUP_BY[$$74]  |PARTITIONED|
-                              {
+                      group by ([$$89 := $$74]) decor ([$$80; $$87]) {
+                                aggregate [$$68] <- [listify({"id": $$79, "topics": $$82})]
                                 -- AGGREGATE  |LOCAL|
+                                  select (not(is-missing($$75)))
                                   -- STREAM_SELECT  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- PRE_CLUSTERED_GROUP_BY[$$74]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$74) (ASC, $$75)
                           -- STABLE_SORT [$$74(ASC), $$75(ASC)]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$74]  |PARTITIONED|
+                              project ([$$80, $$87, $$79, $$82, $$75, $$74])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  join (eq($$95, $$74))
                                   -- HYBRID_HASH_JOIN [$$95][$$74]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$95]  |PARTITIONED|
+                                      assign [$$80] <- [$$t1.getField(0).getField(0)] project: [$$80, $$95]
                                       -- ASSIGN  |PARTITIONED|
+                                        assign [$$95, $$t1] <- [$$74, $$98] project: [$$95, $$t1]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            replicate
                                             -- REPLICATE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                unnest-map [$$74, $$98] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$99, 0, false, true, false)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$99] <- [240]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$74]  |PARTITIONED|
+                                      union ($$75, $$106, $$75) ($$82, $$102, $$82) ($$79, $$103, $$79) ($$74, $$74, $$74) ($$87, $$87, $$87)
                                       -- UNION_ALL  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          select (and(neq($$79, $$96), get-item(edit-distance-check($$87, $$82, 7), 0))) retain-untrue ($$75 <- missing) project: [$$75, $$82, $$79, $$74, $$87]
                                           -- STREAM_SELECT  |PARTITIONED|
+                                            assign [$$82, $$79] <- [$$77.getField(5), $$77.getField(0)] project: [$$74, $$87, $$96, $$75, $$82, $$79]
                                             -- ASSIGN  |PARTITIONED|
+                                              assign [$$77] <- [$$t2.getField(0)] project: [$$74, $$87, $$96, $$75, $$77]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$74, $$87, $$96, $$75, $$t2])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                    left-outer-unnest-map [$$75, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$107, 1, $$107, true, true, true)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        order (ASC, $$107)
                                                         -- STABLE_SORT [$$107(ASC)]  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.TweetMessages.msgNgramIx)  |PARTITIONED|
+                                                            left-outer-unnest-map [$$107] <- index-search("msgNgramIx", 5, "Default", "test", "TweetMessages", true, true, 2, 7, 12, false, 1, $$87)
+                                                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                              exchange
                                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                select (edit-distance-string-is-filterable($$87, 7, 3, true))
                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    replicate
                                                                     -- REPLICATE  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        assign [$$87, $$96] <- [$$97.getField(5), $$97.getField(0)] project: [$$74, $$87, $$96]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          assign [$$97] <- [$$98.getField(0)] project: [$$74, $$97]
                                                                           -- ASSIGN  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              replicate
                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                                  unnest-map [$$74, $$98] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$99, 0, false, true, false)
+                                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      assign [$$99] <- [240]
                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                        empty-tuple-source
                                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$106, $$102, $$103, $$74, $$87])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              left outer join (and(neq($$103, $$96), get-item(edit-distance-check($$87, $$102, 7), 0)))
                                               -- NESTED_LOOP  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  assign [$$102, $$103] <- [$$104.getField(5), $$104.getField(0)] project: [$$106, $$102, $$103]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    assign [$$104] <- [$$105.getField(0)] project: [$$106, $$104]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.TweetMessages)  |PARTITIONED|
+                                                        data-scan []<-[$$106, $$105] <- test.TweetMessages
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                exchange
                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                  select (not(edit-distance-string-is-filterable($$87, 7, 3, true)))
                                                   -- STREAM_SELECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          assign [$$87, $$96] <- [$$97.getField(5), $$97.getField(0)] project: [$$74, $$87, $$96]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            assign [$$97] <- [$$98.getField(0)] project: [$$74, $$97]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                replicate
                                                                 -- REPLICATE  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                    unnest-map [$$74, $$98] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$99, 0, false, true, false)
+                                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        assign [$$99] <- [240]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$110] <- [agg-range-map($$108, $$109)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$108, $$109] <- [agg-local-sampling($$89), agg-null-writer($$89)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$89])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- PRE_CLUSTERED_GROUP_BY[$$74]  |PARTITIONED|
-                                        {
+                                group by ([$$89 := $$74]) decor ([$$80; $$87]) {
+                                          aggregate [$$68] <- [listify({"id": $$79, "topics": $$82})]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$75)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- PRE_CLUSTERED_GROUP_BY[$$74]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$74) (ASC, $$75)
                                     -- STABLE_SORT [$$74(ASC), $$75(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$74]  |PARTITIONED|
+                                        project ([$$80, $$87, $$79, $$82, $$75, $$74])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            join (eq($$95, $$74))
                                             -- HYBRID_HASH_JOIN [$$95][$$74]  |PARTITIONED|
+                                              exchange
                                               -- HASH_PARTITION_EXCHANGE [$$95]  |PARTITIONED|
+                                                assign [$$80] <- [$$t1.getField(0).getField(0)] project: [$$80, $$95]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  assign [$$95, $$t1] <- [$$74, $$98] project: [$$95, $$t1]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                          unnest-map [$$74, $$98] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$99, 0, false, true, false)
+                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              assign [$$99] <- [240]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              exchange
                                               -- HASH_PARTITION_EXCHANGE [$$74]  |PARTITIONED|
+                                                union ($$75, $$106, $$75) ($$82, $$102, $$82) ($$79, $$103, $$79) ($$74, $$74, $$74) ($$87, $$87, $$87)
                                                 -- UNION_ALL  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    select (and(neq($$79, $$96), get-item(edit-distance-check($$87, $$82, 7), 0))) retain-untrue ($$75 <- missing) project: [$$75, $$82, $$79, $$74, $$87]
                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                      assign [$$82, $$79] <- [$$77.getField(5), $$77.getField(0)] project: [$$74, $$87, $$96, $$75, $$82, $$79]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        assign [$$77] <- [$$t2.getField(0)] project: [$$74, $$87, $$96, $$75, $$77]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          project ([$$74, $$87, $$96, $$75, $$t2])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                              left-outer-unnest-map [$$75, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$107, 1, $$107, true, true, true)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  order (ASC, $$107)
                                                                   -- STABLE_SORT [$$107(ASC)]  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.TweetMessages.msgNgramIx)  |PARTITIONED|
+                                                                      left-outer-unnest-map [$$107] <- index-search("msgNgramIx", 5, "Default", "test", "TweetMessages", true, true, 2, 7, 12, false, 1, $$87)
+                                                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                                        exchange
                                                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                          select (edit-distance-string-is-filterable($$87, 7, 3, true))
                                                                           -- STREAM_SELECT  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              replicate
                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  assign [$$87, $$96] <- [$$97.getField(5), $$97.getField(0)] project: [$$74, $$87, $$96]
                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                    assign [$$97] <- [$$98.getField(0)] project: [$$74, $$97]
                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        replicate
                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                                            unnest-map [$$74, $$98] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$99, 0, false, true, false)
+                                                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                assign [$$99] <- [240]
                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                  empty-tuple-source
                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    project ([$$106, $$102, $$103, $$74, $$87])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        left outer join (and(neq($$103, $$96), get-item(edit-distance-check($$87, $$102, 7), 0)))
                                                         -- NESTED_LOOP  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            assign [$$102, $$103] <- [$$104.getField(5), $$104.getField(0)] project: [$$106, $$102, $$103]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              assign [$$104] <- [$$105.getField(0)] project: [$$106, $$104]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- DATASOURCE_SCAN (test.TweetMessages)  |PARTITIONED|
+                                                                  data-scan []<-[$$106, $$105] <- test.TweetMessages
+                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                          exchange
                                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                            select (not(edit-distance-string-is-filterable($$87, 7, 3, true)))
                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                replicate
                                                                 -- REPLICATE  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    assign [$$87, $$96] <- [$$97.getField(5), $$97.getField(0)] project: [$$74, $$87, $$96]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      assign [$$97] <- [$$98.getField(0)] project: [$$74, $$97]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          replicate
                                                                           -- REPLICATE  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                              unnest-map [$$74, $$98] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$99, 0, false, true, false)
+                                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  assign [$$99] <- [240]
                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                    empty-tuple-source
                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01_ps.plan
index 2ca13b1..d57acf2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01_ps.plan
@@ -1,105 +1,204 @@
+distribute result [$$69]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$69] <- [{"tweet": {"id": $$80, "topics": $$87}, "similar-tweets": $$68}] project: [$$69]
     -- ASSIGN  |PARTITIONED|
+      project ([$$68, $$80, $$87])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$89)
           -- STABLE_SORT [$$89(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$89(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$104
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- PRE_CLUSTERED_GROUP_BY[$$74]  |PARTITIONED|
-                              {
+                      group by ([$$89 := $$74]) decor ([$$80; $$87]) {
+                                aggregate [$$68] <- [listify({"id": $$79, "topics": $$82})]
                                 -- AGGREGATE  |LOCAL|
+                                  select (not(is-missing($$75)))
                                   -- STREAM_SELECT  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- PRE_CLUSTERED_GROUP_BY[$$74]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$74) (ASC, $$75)
                           -- STABLE_SORT [$$74(ASC), $$75(ASC)]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$74]  |PARTITIONED|
+                              project ([$$80, $$87, $$79, $$82, $$75, $$74])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  join (eq($$95, $$74))
                                   -- HYBRID_HASH_JOIN [$$95][$$74]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$95]  |PARTITIONED|
+                                      assign [$$80] <- [$$t1.getField(0).getField(0)] project: [$$80, $$95]
                                       -- ASSIGN  |PARTITIONED|
+                                        assign [$$95, $$t1] <- [$$74, $$98] project: [$$95, $$t1]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            replicate
                                             -- REPLICATE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                unnest-map [$$74, $$98] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$99, 0, false, true, false)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$99] <- [240]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$74]  |PARTITIONED|
+                                      select (and(neq($$79, $$96), get-item(similarity-jaccard-check($$87, $$82, 0.5), 0))) retain-untrue ($$75 <- missing) project: [$$87, $$79, $$82, $$75, $$74]
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        assign [$$82, $$79] <- [$$77.getField(4), $$77.getField(0)] project: [$$74, $$87, $$96, $$75, $$82, $$79]
                                         -- ASSIGN  |PARTITIONED|
+                                          assign [$$77] <- [$$t2.getField(0)] project: [$$74, $$87, $$96, $$75, $$77]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$74, $$87, $$96, $$75, $$t2])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                left-outer-unnest-map [$$75, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$101, 1, $$101, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    order (ASC, $$101)
                                                     -- STABLE_SORT [$$101(ASC)]  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.TweetMessages.topicKeywordIx)  |PARTITIONED|
+                                                        left-outer-unnest-map [$$101] <- index-search("topicKeywordIx", 4, "Default", "test", "TweetMessages", true, true, 1, 0.5, 22, false, 1, $$87)
+                                                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                          exchange
                                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                            assign [$$87, $$96] <- [$$97.getField(4), $$97.getField(0)] project: [$$74, $$87, $$96]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              assign [$$97] <- [$$98.getField(0)] project: [$$74, $$97]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  replicate
                                                                   -- REPLICATE  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                      unnest-map [$$74, $$98] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$99, 0, false, true, false)
+                                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          assign [$$99] <- [240]
                                                                           -- ASSIGN  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$104] <- [agg-range-map($$102, $$103)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$102, $$103] <- [agg-local-sampling($$89), agg-null-writer($$89)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$89])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- PRE_CLUSTERED_GROUP_BY[$$74]  |PARTITIONED|
-                                        {
+                                group by ([$$89 := $$74]) decor ([$$80; $$87]) {
+                                          aggregate [$$68] <- [listify({"id": $$79, "topics": $$82})]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$75)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- PRE_CLUSTERED_GROUP_BY[$$74]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$74) (ASC, $$75)
                                     -- STABLE_SORT [$$74(ASC), $$75(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$74]  |PARTITIONED|
+                                        project ([$$80, $$87, $$79, $$82, $$75, $$74])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            join (eq($$95, $$74))
                                             -- HYBRID_HASH_JOIN [$$95][$$74]  |PARTITIONED|
+                                              exchange
                                               -- HASH_PARTITION_EXCHANGE [$$95]  |PARTITIONED|
+                                                assign [$$80] <- [$$t1.getField(0).getField(0)] project: [$$80, $$95]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  assign [$$95, $$t1] <- [$$74, $$98] project: [$$95, $$t1]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                          unnest-map [$$74, $$98] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$99, 0, false, true, false)
+                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              assign [$$99] <- [240]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              exchange
                                               -- HASH_PARTITION_EXCHANGE [$$74]  |PARTITIONED|
+                                                select (and(neq($$79, $$96), get-item(similarity-jaccard-check($$87, $$82, 0.5), 0))) retain-untrue ($$75 <- missing) project: [$$87, $$79, $$82, $$75, $$74]
                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                  assign [$$82, $$79] <- [$$77.getField(4), $$77.getField(0)] project: [$$74, $$87, $$96, $$75, $$82, $$79]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    assign [$$77] <- [$$t2.getField(0)] project: [$$74, $$87, $$96, $$75, $$77]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$74, $$87, $$96, $$75, $$t2])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                          left-outer-unnest-map [$$75, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$101, 1, $$101, true, true, true)
+                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              order (ASC, $$101)
                                                               -- STABLE_SORT [$$101(ASC)]  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.TweetMessages.topicKeywordIx)  |PARTITIONED|
+                                                                  left-outer-unnest-map [$$101] <- index-search("topicKeywordIx", 4, "Default", "test", "TweetMessages", true, true, 1, 0.5, 22, false, 1, $$87)
+                                                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                                    exchange
                                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                      assign [$$87, $$96] <- [$$97.getField(4), $$97.getField(0)] project: [$$74, $$87, $$96]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        assign [$$97] <- [$$98.getField(0)] project: [$$74, $$97]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            replicate
                                                                             -- REPLICATE  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                                unnest-map [$$74, $$98] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$99, 0, false, true, false)
+                                                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    assign [$$99] <- [240]
                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                      empty-tuple-source
                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01_ps.plan
index 4a08ca9..19ab548 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01_ps.plan
@@ -1,81 +1,156 @@
+distribute result [$$60]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$60] <- [{"tweetid1": $$68, "loc1": $$69, "nearby-message": $$59}] project: [$$60]
     -- ASSIGN  |PARTITIONED|
+      project ([$$59, $$68, $$69])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$77)
           -- STABLE_SORT [$$77(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$77(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$92
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- PRE_CLUSTERED_GROUP_BY[$$64]  |PARTITIONED|
-                              {
+                      group by ([$$77 := $$64]) decor ([$$68; $$69]) {
+                                aggregate [$$59] <- [listify({"tweetid2": $$71, "loc2": $$67})]
                                 -- AGGREGATE  |LOCAL|
+                                  select (not(is-missing($$65)))
                                   -- STREAM_SELECT  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- PRE_CLUSTERED_GROUP_BY[$$64]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$64) (ASC, $$70)
                           -- STABLE_SORT [$$64(ASC), $$70(ASC)]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$64]  |PARTITIONED|
+                              select (spatial-intersect($$67, $$n)) retain-untrue ($$65 <- missing) project: [$$68, $$69, $$71, $$67, $$70, $$65, $$64]
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$71, $$67] <- [$$66.getField(0), $$66.getField(2)] project: [$$68, $$69, $$64, $$n, $$65, $$70, $$71, $$67]
                                 -- ASSIGN  |PARTITIONED|
+                                  assign [$$66, $$70] <- [$$t2.getField(0), $$t2.getField("tweetid")] project: [$$68, $$69, $$64, $$n, $$65, $$66, $$70]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$68, $$69, $$64, $$n, $$65, $$t2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                        left-outer-unnest-map [$$65, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$89, 1, $$89, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$89)
                                             -- STABLE_SORT [$$89(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$68, $$69, $$64, $$n, $$89])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                    left-outer-unnest-map [$$85, $$86, $$87, $$88, $$89] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$81, $$82, $$83, $$84)
+                                                    -- RTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        assign [$$81, $$82, $$83, $$84] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          assign [$$n] <- [create-circle($$69, 0.5)]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            assign [$$69, $$68] <- [$$63.getField(2), $$63.getField(0)] project: [$$64, $$69, $$68]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              assign [$$63] <- [$$t1.getField(0)] project: [$$64, $$63]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                  unnest-map [$$64, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$78, true, false, false)
+                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      assign [$$78] <- [10]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$92] <- [agg-range-map($$90, $$91)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$90, $$91] <- [agg-local-sampling($$77), agg-null-writer($$77)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$77])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- PRE_CLUSTERED_GROUP_BY[$$64]  |PARTITIONED|
-                                        {
+                                group by ([$$77 := $$64]) decor ([$$68; $$69]) {
+                                          aggregate [$$59] <- [listify({"tweetid2": $$71, "loc2": $$67})]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$65)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- PRE_CLUSTERED_GROUP_BY[$$64]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$64) (ASC, $$70)
                                     -- STABLE_SORT [$$64(ASC), $$70(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$64]  |PARTITIONED|
+                                        select (spatial-intersect($$67, $$n)) retain-untrue ($$65 <- missing) project: [$$68, $$69, $$71, $$67, $$70, $$65, $$64]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$71, $$67] <- [$$66.getField(0), $$66.getField(2)] project: [$$68, $$69, $$64, $$n, $$65, $$70, $$71, $$67]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$66, $$70] <- [$$t2.getField(0), $$t2.getField("tweetid")] project: [$$68, $$69, $$64, $$n, $$65, $$66, $$70]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$68, $$69, $$64, $$n, $$65, $$t2])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                  left-outer-unnest-map [$$65, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$89, 1, $$89, true, true, true)
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      order (ASC, $$89)
                                                       -- STABLE_SORT [$$89(ASC)]  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          project ([$$68, $$69, $$64, $$n, $$89])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                              left-outer-unnest-map [$$85, $$86, $$87, $$88, $$89] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$81, $$82, $$83, $$84)
+                                                              -- RTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$81, $$82, $$83, $$84] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    assign [$$n] <- [create-circle($$69, 0.5)]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      assign [$$69, $$68] <- [$$63.getField(2), $$63.getField(0)] project: [$$64, $$69, $$68]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        assign [$$63] <- [$$t1.getField(0)] project: [$$64, $$63]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                            unnest-map [$$64, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$78, true, false, false)
+                                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                assign [$$78] <- [10]
                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                  empty-tuple-source
                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02_ps.plan
index 977e29e..b2eb0ab 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02_ps.plan
@@ -1,81 +1,156 @@
+distribute result [$$67]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$67] <- [{"tweetid1": $$77, "loc1": $$78, "nearby-message": $$66}] project: [$$67]
     -- ASSIGN  |PARTITIONED|
+      project ([$$66, $$77, $$78])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$86)
           -- STABLE_SORT [$$86(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$86(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$101
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- PRE_CLUSTERED_GROUP_BY[$$71]  |PARTITIONED|
-                              {
+                      group by ([$$86 := $$71]) decor ([$$77; $$78]) {
+                                aggregate [$$66] <- [listify({"tweetid2": $$76, "loc2": $$74})]
                                 -- AGGREGATE  |LOCAL|
+                                  select (not(is-missing($$72)))
                                   -- STREAM_SELECT  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- PRE_CLUSTERED_GROUP_BY[$$71]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$71) (ASC, $$72)
                           -- STABLE_SORT [$$71(ASC), $$72(ASC)]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$71]  |PARTITIONED|
+                              select (and(spatial-intersect($$74, $$n), neq($$71, $$76))) retain-untrue ($$72 <- missing) project: [$$77, $$78, $$76, $$74, $$72, $$71]
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$76, $$74] <- [$$73.getField(0), $$73.getField(2)] project: [$$77, $$78, $$71, $$n, $$72, $$76, $$74]
                                 -- ASSIGN  |PARTITIONED|
+                                  assign [$$73] <- [$$t2.getField(0)] project: [$$77, $$78, $$71, $$n, $$72, $$73]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$77, $$78, $$71, $$n, $$72, $$t2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                        left-outer-unnest-map [$$72, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$98, 1, $$98, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$98)
                                             -- STABLE_SORT [$$98(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$77, $$78, $$71, $$n, $$98])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                    left-outer-unnest-map [$$94, $$95, $$96, $$97, $$98] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$90, $$91, $$92, $$93)
+                                                    -- RTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        assign [$$90, $$91, $$92, $$93] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          assign [$$n] <- [create-circle($$78, 0.5)]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            assign [$$78, $$77] <- [$$70.getField(2), $$70.getField(0)] project: [$$71, $$78, $$77]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              assign [$$70] <- [$$t1.getField(0)] project: [$$71, $$70]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                  unnest-map [$$71, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$87, true, false, false)
+                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      assign [$$87] <- [10]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$101] <- [agg-range-map($$99, $$100)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$99, $$100] <- [agg-local-sampling($$86), agg-null-writer($$86)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$86])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- PRE_CLUSTERED_GROUP_BY[$$71]  |PARTITIONED|
-                                        {
+                                group by ([$$86 := $$71]) decor ([$$77; $$78]) {
+                                          aggregate [$$66] <- [listify({"tweetid2": $$76, "loc2": $$74})]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$72)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- PRE_CLUSTERED_GROUP_BY[$$71]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$71) (ASC, $$72)
                                     -- STABLE_SORT [$$71(ASC), $$72(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$71]  |PARTITIONED|
+                                        select (and(spatial-intersect($$74, $$n), neq($$71, $$76))) retain-untrue ($$72 <- missing) project: [$$77, $$78, $$76, $$74, $$72, $$71]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$76, $$74] <- [$$73.getField(0), $$73.getField(2)] project: [$$77, $$78, $$71, $$n, $$72, $$76, $$74]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$73] <- [$$t2.getField(0)] project: [$$77, $$78, $$71, $$n, $$72, $$73]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$77, $$78, $$71, $$n, $$72, $$t2])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                  left-outer-unnest-map [$$72, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$98, 1, $$98, true, true, true)
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      order (ASC, $$98)
                                                       -- STABLE_SORT [$$98(ASC)]  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          project ([$$77, $$78, $$71, $$n, $$98])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                              left-outer-unnest-map [$$94, $$95, $$96, $$97, $$98] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$90, $$91, $$92, $$93)
+                                                              -- RTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$90, $$91, $$92, $$93] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    assign [$$n] <- [create-circle($$78, 0.5)]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      assign [$$78, $$77] <- [$$70.getField(2), $$70.getField(0)] project: [$$71, $$78, $$77]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        assign [$$70] <- [$$t1.getField(0)] project: [$$71, $$70]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                            unnest-map [$$71, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$87, true, false, false)
+                                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                assign [$$87] <- [10]
                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                  empty-tuple-source
                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_1_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_1_ps.plan
index d41058b..77b58c2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_1_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_1_ps.plan
@@ -1,77 +1,148 @@
+distribute result [$$49]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$49] <- [{"tweetid1": $$52, "count1": $$58, "t2info": $$48}] project: [$$49]
     -- ASSIGN  |PARTITIONED|
+      project ([$$48, $$58, $$52])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$67)
           -- STABLE_SORT [$$67(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$67(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$75
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- PRE_CLUSTERED_GROUP_BY[$$54]  |PARTITIONED|
-                              {
+                      group by ([$$67 := $$54]) decor ([$$58; $$52]) {
+                                aggregate [$$48] <- [listify({"tweetid2": $$61, "count2": $$59})]
                                 -- AGGREGATE  |LOCAL|
+                                  select (not(is-missing($$55)))
                                   -- STREAM_SELECT  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- PRE_CLUSTERED_GROUP_BY[$$54]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$54) (ASC, $$55)
                           -- STABLE_SORT [$$54(ASC), $$55(ASC)]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$54]  |PARTITIONED|
+                              select (eq($$58, $$59)) retain-untrue ($$55 <- missing)
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$61, $$59] <- [$$57.getField(0), $$57.getField("countB")] project: [$$52, $$58, $$54, $$55, $$61, $$59]
                                 -- ASSIGN  |PARTITIONED|
+                                  assign [$$57] <- [$$t2.getField(0)] project: [$$52, $$58, $$54, $$55, $$57]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$52, $$58, $$54, $$55, $$t2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                        left-outer-unnest-map [$$55, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$72, 1, $$72, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$72)
                                             -- STABLE_SORT [$$72(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$52, $$58, $$54, $$72])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                    left-outer-unnest-map [$$71, $$72] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$58, 1, $$58, true, true, true)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        assign [$$58, $$52] <- [$$65.getField(6), $$65.getField(0)] project: [$$54, $$58, $$52]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          assign [$$65] <- [$$t1.getField(0)] project: [$$54, $$65]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                              unnest-map [$$54, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$68, true, false, false)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$68] <- [10]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$75] <- [agg-range-map($$73, $$74)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$73, $$74] <- [agg-local-sampling($$67), agg-null-writer($$67)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$67])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- PRE_CLUSTERED_GROUP_BY[$$54]  |PARTITIONED|
-                                        {
+                                group by ([$$67 := $$54]) decor ([$$58; $$52]) {
+                                          aggregate [$$48] <- [listify({"tweetid2": $$61, "count2": $$59})]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$55)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- PRE_CLUSTERED_GROUP_BY[$$54]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$54) (ASC, $$55)
                                     -- STABLE_SORT [$$54(ASC), $$55(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$54]  |PARTITIONED|
+                                        select (eq($$58, $$59)) retain-untrue ($$55 <- missing)
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$61, $$59] <- [$$57.getField(0), $$57.getField("countB")] project: [$$52, $$58, $$54, $$55, $$61, $$59]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$57] <- [$$t2.getField(0)] project: [$$52, $$58, $$54, $$55, $$57]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$52, $$58, $$54, $$55, $$t2])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                  left-outer-unnest-map [$$55, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$72, 1, $$72, true, true, true)
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      order (ASC, $$72)
                                                       -- STABLE_SORT [$$72(ASC)]  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          project ([$$52, $$58, $$54, $$72])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                              left-outer-unnest-map [$$71, $$72] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$58, 1, $$58, true, true, true)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$58, $$52] <- [$$65.getField(6), $$65.getField(0)] project: [$$54, $$58, $$52]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    assign [$$65] <- [$$t1.getField(0)] project: [$$54, $$65]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                        unnest-map [$$54, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$68, true, false, false)
+                                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            assign [$$68] <- [10]
                                                                             -- ASSIGN  |PARTITIONED|
+                                                                              empty-tuple-source
                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_2_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_2_ps.plan
index d41058b..a9fa16e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_2_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_2_ps.plan
@@ -1,77 +1,148 @@
+distribute result [$$49]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$49] <- [{"tweetid1": $$52, "count1": $$58, "t2info": $$48}] project: [$$49]
     -- ASSIGN  |PARTITIONED|
+      project ([$$48, $$58, $$52])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$67)
           -- STABLE_SORT [$$67(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$67(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$75
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- PRE_CLUSTERED_GROUP_BY[$$54]  |PARTITIONED|
-                              {
+                      group by ([$$67 := $$54]) decor ([$$58; $$52]) {
+                                aggregate [$$48] <- [listify({"tweetid2": $$61, "count2": $$59})]
                                 -- AGGREGATE  |LOCAL|
+                                  select (not(is-missing($$55)))
                                   -- STREAM_SELECT  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- PRE_CLUSTERED_GROUP_BY[$$54]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$54) (ASC, $$55)
                           -- STABLE_SORT [$$54(ASC), $$55(ASC)]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$54]  |PARTITIONED|
+                              select (eq($$58, $$59)) retain-untrue ($$55 <- missing)
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$61, $$59] <- [$$57.getField(0), $$57.getField("countB")] project: [$$52, $$58, $$54, $$55, $$61, $$59]
                                 -- ASSIGN  |PARTITIONED|
+                                  assign [$$57] <- [$$t2.getField(0)] project: [$$52, $$58, $$54, $$55, $$57]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$52, $$58, $$54, $$55, $$t2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                        left-outer-unnest-map [$$55, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$72, 1, $$72, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$72)
                                             -- STABLE_SORT [$$72(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$52, $$58, $$54, $$72])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                    left-outer-unnest-map [$$71, $$72] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$58, 1, $$58, true, true, true)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        assign [$$58, $$52] <- [$$65.getField("countA"), $$65.getField(0)] project: [$$54, $$58, $$52]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          assign [$$65] <- [$$t1.getField(0)] project: [$$54, $$65]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                              unnest-map [$$54, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$68, true, false, false)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$68] <- [10]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$75] <- [agg-range-map($$73, $$74)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$73, $$74] <- [agg-local-sampling($$67), agg-null-writer($$67)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$67])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- PRE_CLUSTERED_GROUP_BY[$$54]  |PARTITIONED|
-                                        {
+                                group by ([$$67 := $$54]) decor ([$$58; $$52]) {
+                                          aggregate [$$48] <- [listify({"tweetid2": $$61, "count2": $$59})]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$55)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- PRE_CLUSTERED_GROUP_BY[$$54]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$54) (ASC, $$55)
                                     -- STABLE_SORT [$$54(ASC), $$55(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$54]  |PARTITIONED|
+                                        select (eq($$58, $$59)) retain-untrue ($$55 <- missing)
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$61, $$59] <- [$$57.getField(0), $$57.getField("countB")] project: [$$52, $$58, $$54, $$55, $$61, $$59]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$57] <- [$$t2.getField(0)] project: [$$52, $$58, $$54, $$55, $$57]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$52, $$58, $$54, $$55, $$t2])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                  left-outer-unnest-map [$$55, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$72, 1, $$72, true, true, true)
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      order (ASC, $$72)
                                                       -- STABLE_SORT [$$72(ASC)]  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          project ([$$52, $$58, $$54, $$72])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                              left-outer-unnest-map [$$71, $$72] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$58, 1, $$58, true, true, true)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$58, $$52] <- [$$65.getField("countA"), $$65.getField(0)] project: [$$54, $$58, $$52]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    assign [$$65] <- [$$t1.getField(0)] project: [$$54, $$65]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                        unnest-map [$$54, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$68, true, false, false)
+                                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            assign [$$68] <- [10]
                                                                             -- ASSIGN  |PARTITIONED|
+                                                                              empty-tuple-source
                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_1_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_1_ps.plan
index 1c961a8..2965279 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_1_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_1_ps.plan
@@ -1,77 +1,148 @@
+distribute result [$$55]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$55] <- [{"tweetid1": $$67, "count1": $$73, "t2info": $$54}] project: [$$55]
     -- ASSIGN  |PARTITIONED|
+      project ([$$54, $$73, $$67])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$75)
           -- STABLE_SORT [$$75(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$75(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$83
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- PRE_CLUSTERED_GROUP_BY[$$60]  |PARTITIONED|
-                              {
+                      group by ([$$75 := $$60]) decor ([$$73; $$67]) {
+                                aggregate [$$54] <- [listify({"tweetid2": $$68, "count2": $$66})]
                                 -- AGGREGATE  |LOCAL|
+                                  select (not(is-missing($$61)))
                                   -- STREAM_SELECT  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- PRE_CLUSTERED_GROUP_BY[$$60]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$60) (ASC, $$61)
                           -- STABLE_SORT [$$60(ASC), $$61(ASC)]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$60]  |PARTITIONED|
+                              select (and(eq($$73, $$66), neq($$67, $$68))) retain-untrue ($$61 <- missing)
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$68, $$66] <- [$$64.getField(0), $$64.getField("countB")] project: [$$67, $$73, $$60, $$61, $$68, $$66]
                                 -- ASSIGN  |PARTITIONED|
+                                  assign [$$64] <- [$$t2.getField(0)] project: [$$67, $$73, $$60, $$61, $$64]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$67, $$73, $$60, $$61, $$t2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                        left-outer-unnest-map [$$61, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$80, 1, $$80, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$80)
                                             -- STABLE_SORT [$$80(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$67, $$73, $$60, $$80])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                    left-outer-unnest-map [$$79, $$80] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$73, 1, $$73, true, true, true)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        assign [$$73, $$67] <- [$$62.getField(6), $$62.getField(0)] project: [$$60, $$73, $$67]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          assign [$$62] <- [$$t1.getField(0)] project: [$$60, $$62]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                              unnest-map [$$60, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$76, true, false, false)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$76] <- [10]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$83] <- [agg-range-map($$81, $$82)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$81, $$82] <- [agg-local-sampling($$75), agg-null-writer($$75)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$75])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- PRE_CLUSTERED_GROUP_BY[$$60]  |PARTITIONED|
-                                        {
+                                group by ([$$75 := $$60]) decor ([$$73; $$67]) {
+                                          aggregate [$$54] <- [listify({"tweetid2": $$68, "count2": $$66})]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$61)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- PRE_CLUSTERED_GROUP_BY[$$60]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$60) (ASC, $$61)
                                     -- STABLE_SORT [$$60(ASC), $$61(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$60]  |PARTITIONED|
+                                        select (and(eq($$73, $$66), neq($$67, $$68))) retain-untrue ($$61 <- missing)
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$68, $$66] <- [$$64.getField(0), $$64.getField("countB")] project: [$$67, $$73, $$60, $$61, $$68, $$66]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$64] <- [$$t2.getField(0)] project: [$$67, $$73, $$60, $$61, $$64]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$67, $$73, $$60, $$61, $$t2])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                  left-outer-unnest-map [$$61, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$80, 1, $$80, true, true, true)
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      order (ASC, $$80)
                                                       -- STABLE_SORT [$$80(ASC)]  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          project ([$$67, $$73, $$60, $$80])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                              left-outer-unnest-map [$$79, $$80] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$73, 1, $$73, true, true, true)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$73, $$67] <- [$$62.getField(6), $$62.getField(0)] project: [$$60, $$73, $$67]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    assign [$$62] <- [$$t1.getField(0)] project: [$$60, $$62]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                        unnest-map [$$60, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$76, true, false, false)
+                                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            assign [$$76] <- [10]
                                                                             -- ASSIGN  |PARTITIONED|
+                                                                              empty-tuple-source
                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_2_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_2_ps.plan
index 1c961a8..4abfab0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_2_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_2_ps.plan
@@ -1,77 +1,148 @@
+distribute result [$$55]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$55] <- [{"tweetid1": $$67, "count1": $$73, "t2info": $$54}] project: [$$55]
     -- ASSIGN  |PARTITIONED|
+      project ([$$54, $$73, $$67])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$75)
           -- STABLE_SORT [$$75(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$75(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$83
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- PRE_CLUSTERED_GROUP_BY[$$60]  |PARTITIONED|
-                              {
+                      group by ([$$75 := $$60]) decor ([$$73; $$67]) {
+                                aggregate [$$54] <- [listify({"tweetid2": $$68, "count2": $$66})]
                                 -- AGGREGATE  |LOCAL|
+                                  select (not(is-missing($$61)))
                                   -- STREAM_SELECT  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- PRE_CLUSTERED_GROUP_BY[$$60]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$60) (ASC, $$61)
                           -- STABLE_SORT [$$60(ASC), $$61(ASC)]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$60]  |PARTITIONED|
+                              select (and(eq($$73, $$66), neq($$67, $$68))) retain-untrue ($$61 <- missing)
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$68, $$66] <- [$$64.getField(0), $$64.getField("countB")] project: [$$67, $$73, $$60, $$61, $$68, $$66]
                                 -- ASSIGN  |PARTITIONED|
+                                  assign [$$64] <- [$$t2.getField(0)] project: [$$67, $$73, $$60, $$61, $$64]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$67, $$73, $$60, $$61, $$t2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                        left-outer-unnest-map [$$61, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$80, 1, $$80, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$80)
                                             -- STABLE_SORT [$$80(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$67, $$73, $$60, $$80])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                    left-outer-unnest-map [$$79, $$80] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$73, 1, $$73, true, true, true)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        assign [$$73, $$67] <- [$$62.getField("countA"), $$62.getField(0)] project: [$$60, $$73, $$67]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          assign [$$62] <- [$$t1.getField(0)] project: [$$60, $$62]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                              unnest-map [$$60, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$76, true, false, false)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$76] <- [10]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$83] <- [agg-range-map($$81, $$82)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$81, $$82] <- [agg-local-sampling($$75), agg-null-writer($$75)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$75])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- PRE_CLUSTERED_GROUP_BY[$$60]  |PARTITIONED|
-                                        {
+                                group by ([$$75 := $$60]) decor ([$$73; $$67]) {
+                                          aggregate [$$54] <- [listify({"tweetid2": $$68, "count2": $$66})]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$61)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- PRE_CLUSTERED_GROUP_BY[$$60]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$60) (ASC, $$61)
                                     -- STABLE_SORT [$$60(ASC), $$61(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$60]  |PARTITIONED|
+                                        select (and(eq($$73, $$66), neq($$67, $$68))) retain-untrue ($$61 <- missing)
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$68, $$66] <- [$$64.getField(0), $$64.getField("countB")] project: [$$67, $$73, $$60, $$61, $$68, $$66]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$64] <- [$$t2.getField(0)] project: [$$67, $$73, $$60, $$61, $$64]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$67, $$73, $$60, $$61, $$t2])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                  left-outer-unnest-map [$$61, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$80, 1, $$80, true, true, true)
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      order (ASC, $$80)
                                                       -- STABLE_SORT [$$80(ASC)]  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          project ([$$67, $$73, $$60, $$80])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                              left-outer-unnest-map [$$79, $$80] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$73, 1, $$73, true, true, true)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$73, $$67] <- [$$62.getField("countA"), $$62.getField(0)] project: [$$60, $$73, $$67]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    assign [$$62] <- [$$t1.getField(0)] project: [$$60, $$62]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                        unnest-map [$$60, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$76, true, false, false)
+                                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            assign [$$76] <- [10]
                                                                             -- ASSIGN  |PARTITIONED|
+                                                                              empty-tuple-source
                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/01.plan
index ac9b3d4..a7b6f22 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/01.plan
@@ -1,20 +1,40 @@
+distribute result [$$32]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"a": $$a, "b": $$b}] project: [$$32]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$35, $$b.getField("nested").getField("fname"))) project: [$$a, $$b]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$a, $$35, $$b])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.ds2.ds2)  |PARTITIONED|
+            unnest-map [$$34, $$b] <- index-search("ds2", 0, "Default", "test", "ds2", true, false, 1, $$42, 1, $$42, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$42)
                 -- STABLE_SORT [$$42(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$a, $$35, $$42])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.ds2.idx)  |PARTITIONED|
+                        unnest-map [$$40, $$41, $$42] <- index-search("idx", 0, "Default", "test", "ds2", true, true, 1, $$35, 1, $$35, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$35] <- [to-string($$a.getField("nested").getField("fname"))]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$a])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.ds1)  |PARTITIONED|
+                                  data-scan []<-[$$33, $$a] <- test.ds1
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/02.plan
index 152d7c0..5f4157c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/02.plan
@@ -1,20 +1,40 @@
+distribute result [$$32]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"a": $$a, "b": $$b}] project: [$$32]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$35, $$b.getField("nested").getField("fname"))) project: [$$a, $$b]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$a, $$35, $$b])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.ds2.ds2)  |PARTITIONED|
+            unnest-map [$$34, $$b] <- index-search("ds2", 0, "Default", "test", "ds2", true, false, 1, $$43, 1, $$43, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$43)
                 -- STABLE_SORT [$$43(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$a, $$35, $$43])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.ds2.idx)  |PARTITIONED|
+                        unnest-map [$$40, $$41, $$42, $$43] <- index-search("idx", 0, "Default", "test", "ds2", true, true, 1, $$35, 1, $$35, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$35] <- [to-string($$a.getField("nested").getField("fname"))]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$a])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.ds1)  |PARTITIONED|
+                                  data-scan []<-[$$33, $$a] <- test.ds1
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/03.plan
index 6a72dfe..e4b01f1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/03.plan
@@ -1,25 +1,50 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"c1": $$46, "c2": $$47}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$46(ASC), $$47(ASC) ]  |PARTITIONED|
+        order (ASC, $$46) (ASC, $$47)
         -- STABLE_SORT [$$46(ASC), $$47(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$46, $$47])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (eq($$44, $$45))
                 -- HYBRID_HASH_JOIN [$$44][$$45]  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$44]  |PARTITIONED|
+                    assign [$$46, $$44] <- [$$50.getField("c_x"), $$50.getField("c_s")] project: [$$46, $$44]
                     -- ASSIGN  |PARTITIONED|
+                      assign [$$50] <- [$$t1.getField("nested")] project: [$$50]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t1])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                            data-scan []<-[$$42, $$t1] <- test.TestOpen1
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$45]  |PARTITIONED|
+                    assign [$$47, $$45] <- [$$51.getField("c_x"), $$51.getField("c_s")] project: [$$47, $$45]
                     -- ASSIGN  |PARTITIONED|
+                      assign [$$51] <- [$$t2.getField("nested")] project: [$$51]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t2])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen2)  |PARTITIONED|
+                            data-scan []<-[$$43, $$t2] <- test.TestOpen2
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/04.plan
index 6a72dfe..e4b01f1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/04.plan
@@ -1,25 +1,50 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"c1": $$46, "c2": $$47}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$46(ASC), $$47(ASC) ]  |PARTITIONED|
+        order (ASC, $$46) (ASC, $$47)
         -- STABLE_SORT [$$46(ASC), $$47(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$46, $$47])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (eq($$44, $$45))
                 -- HYBRID_HASH_JOIN [$$44][$$45]  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$44]  |PARTITIONED|
+                    assign [$$46, $$44] <- [$$50.getField("c_x"), $$50.getField("c_s")] project: [$$46, $$44]
                     -- ASSIGN  |PARTITIONED|
+                      assign [$$50] <- [$$t1.getField("nested")] project: [$$50]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t1])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                            data-scan []<-[$$42, $$t1] <- test.TestOpen1
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$45]  |PARTITIONED|
+                    assign [$$47, $$45] <- [$$51.getField("c_x"), $$51.getField("c_s")] project: [$$47, $$45]
                     -- ASSIGN  |PARTITIONED|
+                      assign [$$51] <- [$$t2.getField("nested")] project: [$$51]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t2])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen2)  |PARTITIONED|
+                            data-scan []<-[$$43, $$t2] <- test.TestOpen2
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/05.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/05.plan
index 6af09d7..292edfc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/05.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/05.plan
@@ -1,25 +1,50 @@
+distribute result [$$36]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$36] <- [{"c1": $$48, "c2": $$49}] project: [$$36]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$48(ASC), $$49(ASC) ]  |PARTITIONED|
+        order (ASC, $$48) (ASC, $$49)
         -- STABLE_SORT [$$48(ASC), $$49(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$48, $$49])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (eq($$45, $$46))
                 -- HYBRID_HASH_JOIN [$$45][$$46]  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$45]  |PARTITIONED|
+                    assign [$$45, $$48] <- [to-string($$52.getField("c_s")), $$52.getField("c_x")] project: [$$48, $$45]
                     -- ASSIGN  |PARTITIONED|
+                      assign [$$52] <- [$$t1.getField("nested")] project: [$$52]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t1])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                            data-scan []<-[$$43, $$t1] <- test.TestOpen1
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$46]  |PARTITIONED|
+                    assign [$$49, $$46] <- [$$53.getField("c_x"), $$53.getField("c_s")] project: [$$49, $$46]
                     -- ASSIGN  |PARTITIONED|
+                      assign [$$53] <- [$$t2.getField("nested")] project: [$$53]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t2])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen2)  |PARTITIONED|
+                            data-scan []<-[$$44, $$t2] <- test.TestOpen2
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/06.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/06.plan
index 5fccabc..37f63b0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/06.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/06.plan
@@ -1,26 +1,52 @@
+distribute result [$$36]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$36] <- [{"c1": $$48, "c2": $$49}] project: [$$36]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$48(ASC), $$49(ASC) ]  |PARTITIONED|
+        order (ASC, $$48) (ASC, $$49)
         -- STABLE_SORT [$$48(ASC), $$49(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$45, $$53.getField("c_s"))) project: [$$48, $$49]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$49] <- [$$53.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                assign [$$53] <- [$$t2.getField("nested")] project: [$$48, $$45, $$53]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$48, $$45, $$t2])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TestOpen2.TestOpen2)  |PARTITIONED|
+                      unnest-map [$$44, $$t2] <- index-search("TestOpen2", 0, "Default", "test", "TestOpen2", true, false, 1, $$56, 1, $$56, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$56)
                           -- STABLE_SORT [$$56(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$48, $$45, $$56])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.TestOpen2.idx_t2_s)  |PARTITIONED|
+                                  unnest-map [$$54, $$55, $$56] <- index-search("idx_t2_s", 0, "Default", "test", "TestOpen2", true, true, 1, $$45, 1, $$45, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                      assign [$$45, $$48] <- [to-string($$52.getField("c_s")), $$52.getField("c_x")] project: [$$45, $$48]
                                       -- ASSIGN  |PARTITIONED|
+                                        assign [$$52] <- [$$t1.getField("nested")] project: [$$52]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$t1])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                                              data-scan []<-[$$43, $$t1] <- test.TestOpen1
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/07.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/07.plan
index 875f64e..e4fe2dd 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/07.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/07.plan
@@ -1,26 +1,52 @@
+distribute result [$$36]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$36] <- [{"c1": $$48, "c2": $$49}] project: [$$36]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$48(ASC), $$49(ASC) ]  |PARTITIONED|
+        order (ASC, $$48) (ASC, $$49)
         -- STABLE_SORT [$$48(ASC), $$49(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$45, $$53.getField("c_i64"))) project: [$$48, $$49]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$49] <- [$$53.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                assign [$$53] <- [$$t2.getField("nested")] project: [$$48, $$45, $$53]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$48, $$45, $$t2])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TestOpen2.TestOpen2)  |PARTITIONED|
+                      unnest-map [$$44, $$t2] <- index-search("TestOpen2", 0, "Default", "test", "TestOpen2", true, false, 1, $$56, 1, $$56, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$56)
                           -- STABLE_SORT [$$56(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$48, $$45, $$56])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.TestOpen2.idx_t2_i64)  |PARTITIONED|
+                                  unnest-map [$$54, $$55, $$56] <- index-search("idx_t2_i64", 0, "Default", "test", "TestOpen2", true, true, 1, $$45, 1, $$45, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                      assign [$$45, $$48] <- [to-bigint($$52.getField("c_i64")), $$52.getField("c_x")] project: [$$45, $$48]
                                       -- ASSIGN  |PARTITIONED|
+                                        assign [$$52] <- [$$t1.getField("nested")] project: [$$52]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$t1])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                                              data-scan []<-[$$43, $$t1] <- test.TestOpen1
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/01.plan
index 2ac8171..19e300e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/01.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (gt($$emp.getField("nested").getField("fname"), "Roger"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$16, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$22, 1, $$22, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+              order (ASC, $$22)
+              -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$22])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$20, $$21, $$22] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 1, $$19, 0, false, true, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$19] <- ["Roger"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/02.plan
index 0746bd8..cca1aaa 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/02.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (gt($$emp.getField("nested").getField("address").getField("zip"), "97777"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+          unnest-map [$$17, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$25, 1, $$25, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+              order (ASC, $$25)
+              -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$25])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                      unnest-map [$$22, $$23, $$24, $$25] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 1, $$21, 0, false, true, false)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$21] <- ["97777"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/03.plan
index 4554197..3f8e0bc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/03.plan
@@ -1,20 +1,40 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$18] <- [{"res": $$22}] project: [$$18]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$22(ASC) ]  |PARTITIONED|
+        order (ASC, $$22)
         -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$t.getField("nested").getField("c_i64"), 2)) project: [$$22]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$22] <- [$$t.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                    unnest-map [$$20, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$29, 1, $$29, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$29)
                         -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$29])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.TestOpen.idx_i64)  |PARTITIONED|
+                                unnest-map [$$27, $$28, $$29] <- index-search("idx_i64", 0, "Default", "test", "TestOpen", false, false, 1, $$25, 1, $$26, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$25, $$26] <- [2, 2]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/04.plan
index 2e37bd6..77d38a6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/04.plan
@@ -1,21 +1,42 @@
+distribute result [$$19]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"res": $$25}] project: [$$19]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+        order (ASC, $$25)
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$27.getField("c_s"), "world")) project: [$$25]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25] <- [$$27.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                assign [$$27] <- [$$t.getField("nested")] project: [$$27]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                      unnest-map [$$23, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$32, 1, $$32, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$32)
                           -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$32])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.TestOpen.idx_s)  |PARTITIONED|
+                                  unnest-map [$$30, $$31, $$32] <- index-search("idx_s", 0, "Default", "test", "TestOpen", false, false, 1, $$28, 1, $$29, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$28, $$29] <- ["world", "world"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/05.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/05.plan
index 8fced14..180c77f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/05.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/05.plan
@@ -1,21 +1,42 @@
+distribute result [$$19]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"res": $$25}] project: [$$19]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+        order (ASC, $$25)
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$27.getField("c_i64"), 2)) project: [$$25]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25] <- [$$27.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                assign [$$27] <- [$$t.getField("nested")] project: [$$27]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                      unnest-map [$$23, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$32, 1, $$32, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$32)
                           -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$32])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.TestOpen.idx_i64)  |PARTITIONED|
+                                  unnest-map [$$30, $$31, $$32] <- index-search("idx_i64", 0, "Default", "test", "TestOpen", false, false, 1, $$28, 1, $$29, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$28, $$29] <- [2, 2]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/06.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/06.plan
index b5717df..050c0ed 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/06.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/06.plan
@@ -1,21 +1,42 @@
+distribute result [$$19]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"res": $$25}] project: [$$19]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+        order (ASC, $$25)
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$27.getField("c_i64"), 2)) project: [$$25]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25] <- [$$27.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                assign [$$27] <- [$$t.getField("nested")] project: [$$27]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                      unnest-map [$$23, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$31, 1, $$31, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$31)
                           -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$31])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.TestOpen.idx_i64)  |PARTITIONED|
+                                  unnest-map [$$29, $$30, $$31] <- index-search("idx_i64", 0, "Default", "test", "TestOpen", false, false, 1, $$28, 0, true, true, false)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$28] <- [2]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/07.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/07.plan
index b5717df..dbc012a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/07.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/07.plan
@@ -1,21 +1,42 @@
+distribute result [$$19]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"res": $$25}] project: [$$19]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+        order (ASC, $$25)
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$27.getField("c_i64"), 2.0)) project: [$$25]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25] <- [$$27.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                assign [$$27] <- [$$t.getField("nested")] project: [$$27]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                      unnest-map [$$23, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$31, 1, $$31, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$31)
                           -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$31])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.TestOpen.idx_i64)  |PARTITIONED|
+                                  unnest-map [$$29, $$30, $$31] <- index-search("idx_i64", 0, "Default", "test", "TestOpen", false, false, 1, $$28, 0, true, true, false)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$28] <- [2]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/08.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/08.plan
index 6b3856e..627180a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/08.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/08.plan
@@ -1,21 +1,42 @@
+distribute result [$$19]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"res": $$25}] project: [$$19]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+        order (ASC, $$25)
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$27.getField("c_i8"), 2)) project: [$$25]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25] <- [$$27.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                assign [$$27] <- [$$t.getField("nested")] project: [$$27]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                      unnest-map [$$23, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$31, 1, $$31, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$31)
                           -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$31])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.TestOpen.idx_i8)  |PARTITIONED|
+                                  unnest-map [$$29, $$30, $$31] <- index-search("idx_i8", 0, "Default", "test", "TestOpen", false, false, 1, $$28, 0, true, true, false)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$28] <- [2]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/09.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/09.plan
index 6b3856e..056d2c5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/09.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/09.plan
@@ -1,21 +1,42 @@
+distribute result [$$19]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"res": $$25}] project: [$$19]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+        order (ASC, $$25)
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$27.getField("c_i8"), 2.5)) project: [$$25]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25] <- [$$27.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                assign [$$27] <- [$$t.getField("nested")] project: [$$27]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                      unnest-map [$$23, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$31, 1, $$31, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$31)
                           -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$31])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.TestOpen.idx_i8)  |PARTITIONED|
+                                  unnest-map [$$29, $$30, $$31] <- index-search("idx_i8", 0, "Default", "test", "TestOpen", false, false, 1, $$28, 0, true, true, false)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$28] <- [2]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/10.plan
index 23a0c32..cf2d33f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/10.plan
@@ -1,21 +1,42 @@
+distribute result [$$19]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"res": $$25}] project: [$$19]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+        order (ASC, $$25)
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (ge($$27.getField("c_d"), 3.25)) project: [$$25]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25] <- [$$27.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                assign [$$27] <- [$$t.getField("nested")] project: [$$27]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                      unnest-map [$$23, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$31, 1, $$31, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$31)
                           -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$31])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.TestOpen.idx_d)  |PARTITIONED|
+                                  unnest-map [$$29, $$30, $$31] <- index-search("idx_d", 0, "Default", "test", "TestOpen", false, false, 1, $$28, 0, true, true, false)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$28] <- [3.25]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/11.plan
index 7498d85..3d7126e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/11.plan
@@ -1,21 +1,42 @@
+distribute result [$$23]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$23] <- [{"res": $$30}] project: [$$23]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$30(ASC) ]  |PARTITIONED|
+        order (ASC, $$30)
         -- STABLE_SORT [$$30(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$26, 499), lt($$26, 99999))) project: [$$30]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$30, $$26] <- [$$32.getField("c_x"), $$32.getField("c_i8")] project: [$$30, $$26]
               -- ASSIGN  |PARTITIONED|
+                assign [$$32] <- [$$t.getField("nested")] project: [$$32]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                      unnest-map [$$28, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$37, 1, $$37, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$37)
                           -- STABLE_SORT [$$37(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$37])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.TestOpen.idx_i8)  |PARTITIONED|
+                                  unnest-map [$$35, $$36, $$37] <- index-search("idx_i8", 0, "Default", "test", "TestOpen", false, false, 1, $$33, 1, $$34, true, true, false)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$33, $$34] <- [127, 127]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/12.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/12.plan
index df41877..295ce09 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/12.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index/non-enforced-composite-key/12.plan
@@ -1,32 +1,64 @@
+distribute result [$$23]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$23] <- [{"res": $$30}] project: [$$23]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$30(ASC) ]  |PARTITIONED|
+        order (ASC, $$30)
         -- STABLE_SORT [$$30(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$32.getField("c_i8"), 2), lt($$32.getField("c_i64"), 3))) project: [$$30]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$30] <- [$$32.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                assign [$$32] <- [$$t.getField("nested")] project: [$$32]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                      unnest-map [$$27, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$41, 1, $$41, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          intersect [$$41] <- [[$$36], [$$40]]
                           -- INTERSECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$36)
                               -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$36])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.TestOpen.idx_3)  |PARTITIONED|
+                                      unnest-map [$$34, $$35, $$36] <- index-search("idx_3", 0, "Default", "test", "TestOpen", false, false, 0, 1, $$33, true, true, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$33] <- [3]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$40)
                               -- STABLE_SORT [$$40(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$40])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.TestOpen.idx_4)  |PARTITIONED|
+                                      unnest-map [$$38, $$39, $$40] <- index-search("idx_4", 0, "Default", "test", "TestOpen", false, false, 1, $$37, 0, true, true, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$37] <- [2]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-basic/ngram-contains-panic_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-basic/ngram-contains-panic_ps.plan
index 5a051c1..94594ff 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-basic/ngram-contains-panic_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-basic/ngram-contains-panic_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$17)
         -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$17(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$23
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField(0).getField("title"), "Mu"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                        data-scan []<-[$$17, $$o] <- test.DBLP
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$23] <- [agg-range-map($$21, $$22)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$21, $$22] <- [agg-local-sampling($$17), agg-null-writer($$17)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$17])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField(0).getField("title"), "Mu"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                  data-scan []<-[$$17, $$o] <- test.DBLP
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-basic/ngram-contains_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-basic/ngram-contains_ps.plan
index e0dd2e4..22383d5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-basic/ngram-contains_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-basic/ngram-contains_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
-          -- RANGE_PARTITION_EXCHANGE [$$17(ASC)]  |PARTITIONED|
+        order (ASC, $$18)
+        -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+          exchange
+          -- RANGE_PARTITION_EXCHANGE [$$18(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$26
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField(0).getField("title"), "Multimedia"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                        unnest-map [$$18, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$23, 1, $$23, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                            order (ASC, $$23)
+                            -- STABLE_SORT [$$23(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                unnest-map [$$23] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 0, missing, 12, false, 1, $$22)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$22] <- ["Multimedia"]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$26] <- [agg-range-map($$24, $$25)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$24, $$25] <- [agg-local-sampling($$18), agg-null-writer($$18)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$18])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField(0).getField("title"), "Multimedia"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                                  unnest-map [$$18, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$23, 1, $$23, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                                      order (ASC, $$23)
+                                      -- STABLE_SORT [$$23(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                          unnest-map [$$23] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 0, missing, 12, false, 1, $$22)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$22] <- ["Multimedia"]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-basic/word-contains_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-basic/word-contains_ps.plan
index 5a051c1..36c0dff 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-basic/word-contains_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-basic/word-contains_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$17)
         -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$17(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$23
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField(0).getField("title"), "Multimedia"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                        data-scan []<-[$$17, $$o] <- test.DBLP
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$23] <- [agg-range-map($$21, $$22)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$21, $$22] <- [agg-local-sampling($$17), agg-null-writer($$17)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$17])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField(0).getField("title"), "Multimedia"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                  data-scan []<-[$$17, $$o] <- test.DBLP
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01_ps.plan
index 3920a9f..16819c3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01_ps.plan
@@ -1,167 +1,328 @@
+distribute result [$$69]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$69] <- [{"tweet": {"id": $$80, "topics": $$87}, "similar-tweets": $$68}] project: [$$69]
     -- ASSIGN  |PARTITIONED|
+      project ([$$68, $$80, $$87])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$89)
           -- STABLE_SORT [$$89(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$89(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$110
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- PRE_CLUSTERED_GROUP_BY[$$74]  |PARTITIONED|
-                              {
+                      group by ([$$89 := $$74]) decor ([$$80; $$87]) {
+                                aggregate [$$68] <- [listify({"id": $$79, "topics": $$82})]
                                 -- AGGREGATE  |LOCAL|
+                                  select (not(is-missing($$75)))
                                   -- STREAM_SELECT  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- PRE_CLUSTERED_GROUP_BY[$$74]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$74) (ASC, $$75)
                           -- STABLE_SORT [$$74(ASC), $$75(ASC)]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$74]  |PARTITIONED|
+                              project ([$$80, $$87, $$79, $$82, $$75, $$74])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  join (eq($$95, $$74))
                                   -- HYBRID_HASH_JOIN [$$95][$$74]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$95]  |PARTITIONED|
+                                      assign [$$80] <- [$$t1.getField(0).getField(0)] project: [$$80, $$95]
                                       -- ASSIGN  |PARTITIONED|
+                                        assign [$$95, $$t1] <- [$$74, $$98] project: [$$95, $$t1]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            replicate
                                             -- REPLICATE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                unnest-map [$$74, $$98] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$99, 0, false, true, false)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$99] <- [240]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$74]  |PARTITIONED|
+                                      union ($$75, $$106, $$75) ($$82, $$102, $$82) ($$79, $$103, $$79) ($$74, $$74, $$74) ($$87, $$87, $$87)
                                       -- UNION_ALL  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          select (and(neq($$79, $$96), get-item(edit-distance-check($$87, $$82, 7), 0))) retain-untrue ($$75 <- missing) project: [$$75, $$82, $$79, $$74, $$87]
                                           -- STREAM_SELECT  |PARTITIONED|
+                                            assign [$$82, $$79] <- [$$77.getField("message-text"), $$77.getField(0)] project: [$$74, $$87, $$96, $$75, $$82, $$79]
                                             -- ASSIGN  |PARTITIONED|
+                                              assign [$$77] <- [$$t2.getField(0)] project: [$$74, $$87, $$96, $$75, $$77]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$74, $$87, $$96, $$75, $$t2])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                    left-outer-unnest-map [$$75, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$107, 1, $$107, true, true, true)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        order (ASC, $$107)
                                                         -- STABLE_SORT [$$107(ASC)]  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.TweetMessages.msgNgramIx)  |PARTITIONED|
+                                                            left-outer-unnest-map [$$107] <- index-search("msgNgramIx", 5, "Default", "test", "TweetMessages", true, true, 2, 7, 12, false, 1, $$87)
+                                                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                              exchange
                                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                select (edit-distance-string-is-filterable($$87, 7, 3, true))
                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    replicate
                                                                     -- REPLICATE  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        assign [$$87, $$96] <- [$$97.getField("message-text"), $$97.getField(0)] project: [$$74, $$87, $$96]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          assign [$$97] <- [$$98.getField(0)] project: [$$74, $$97]
                                                                           -- ASSIGN  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              replicate
                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                                  unnest-map [$$74, $$98] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$99, 0, false, true, false)
+                                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      assign [$$99] <- [240]
                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                        empty-tuple-source
                                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$106, $$102, $$103, $$74, $$87])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              left outer join (and(neq($$103, $$96), get-item(edit-distance-check($$87, $$102, 7), 0)))
                                               -- NESTED_LOOP  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  assign [$$102, $$103] <- [$$104.getField("message-text"), $$104.getField(0)] project: [$$106, $$102, $$103]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    assign [$$104] <- [$$105.getField(0)] project: [$$106, $$104]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.TweetMessages)  |PARTITIONED|
+                                                        data-scan []<-[$$106, $$105] <- test.TweetMessages
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                exchange
                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                  select (not(edit-distance-string-is-filterable($$87, 7, 3, true)))
                                                   -- STREAM_SELECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          assign [$$87, $$96] <- [$$97.getField("message-text"), $$97.getField(0)] project: [$$74, $$87, $$96]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            assign [$$97] <- [$$98.getField(0)] project: [$$74, $$97]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                replicate
                                                                 -- REPLICATE  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                    unnest-map [$$74, $$98] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$99, 0, false, true, false)
+                                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        assign [$$99] <- [240]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$110] <- [agg-range-map($$108, $$109)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$108, $$109] <- [agg-local-sampling($$89), agg-null-writer($$89)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$89])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- PRE_CLUSTERED_GROUP_BY[$$74]  |PARTITIONED|
-                                        {
+                                group by ([$$89 := $$74]) decor ([$$80; $$87]) {
+                                          aggregate [$$68] <- [listify({"id": $$79, "topics": $$82})]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$75)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- PRE_CLUSTERED_GROUP_BY[$$74]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$74) (ASC, $$75)
                                     -- STABLE_SORT [$$74(ASC), $$75(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$74]  |PARTITIONED|
+                                        project ([$$80, $$87, $$79, $$82, $$75, $$74])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            join (eq($$95, $$74))
                                             -- HYBRID_HASH_JOIN [$$95][$$74]  |PARTITIONED|
+                                              exchange
                                               -- HASH_PARTITION_EXCHANGE [$$95]  |PARTITIONED|
+                                                assign [$$80] <- [$$t1.getField(0).getField(0)] project: [$$80, $$95]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  assign [$$95, $$t1] <- [$$74, $$98] project: [$$95, $$t1]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                          unnest-map [$$74, $$98] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$99, 0, false, true, false)
+                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              assign [$$99] <- [240]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              exchange
                                               -- HASH_PARTITION_EXCHANGE [$$74]  |PARTITIONED|
+                                                union ($$75, $$106, $$75) ($$82, $$102, $$82) ($$79, $$103, $$79) ($$74, $$74, $$74) ($$87, $$87, $$87)
                                                 -- UNION_ALL  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    select (and(neq($$79, $$96), get-item(edit-distance-check($$87, $$82, 7), 0))) retain-untrue ($$75 <- missing) project: [$$75, $$82, $$79, $$74, $$87]
                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                      assign [$$82, $$79] <- [$$77.getField("message-text"), $$77.getField(0)] project: [$$74, $$87, $$96, $$75, $$82, $$79]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        assign [$$77] <- [$$t2.getField(0)] project: [$$74, $$87, $$96, $$75, $$77]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          project ([$$74, $$87, $$96, $$75, $$t2])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                              left-outer-unnest-map [$$75, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$107, 1, $$107, true, true, true)
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  order (ASC, $$107)
                                                                   -- STABLE_SORT [$$107(ASC)]  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.TweetMessages.msgNgramIx)  |PARTITIONED|
+                                                                      left-outer-unnest-map [$$107] <- index-search("msgNgramIx", 5, "Default", "test", "TweetMessages", true, true, 2, 7, 12, false, 1, $$87)
+                                                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                                        exchange
                                                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                          select (edit-distance-string-is-filterable($$87, 7, 3, true))
                                                                           -- STREAM_SELECT  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              replicate
                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  assign [$$87, $$96] <- [$$97.getField("message-text"), $$97.getField(0)] project: [$$74, $$87, $$96]
                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                    assign [$$97] <- [$$98.getField(0)] project: [$$74, $$97]
                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        replicate
                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                                            unnest-map [$$74, $$98] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$99, 0, false, true, false)
+                                                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                assign [$$99] <- [240]
                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                  empty-tuple-source
                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    project ([$$106, $$102, $$103, $$74, $$87])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        left outer join (and(neq($$103, $$96), get-item(edit-distance-check($$87, $$102, 7), 0)))
                                                         -- NESTED_LOOP  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            assign [$$102, $$103] <- [$$104.getField("message-text"), $$104.getField(0)] project: [$$106, $$102, $$103]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              assign [$$104] <- [$$105.getField(0)] project: [$$106, $$104]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- DATASOURCE_SCAN (test.TweetMessages)  |PARTITIONED|
+                                                                  data-scan []<-[$$106, $$105] <- test.TweetMessages
+                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                          exchange
                                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                            select (not(edit-distance-string-is-filterable($$87, 7, 3, true)))
                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                replicate
                                                                 -- REPLICATE  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    assign [$$87, $$96] <- [$$97.getField("message-text"), $$97.getField(0)] project: [$$74, $$87, $$96]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      assign [$$97] <- [$$98.getField(0)] project: [$$74, $$97]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          replicate
                                                                           -- REPLICATE  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                              unnest-map [$$74, $$98] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$99, 0, false, true, false)
+                                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  assign [$$99] <- [240]
                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                    empty-tuple-source
                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/ngram-contains_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/ngram-contains_01_ps.plan
index df1938d..b70b6cf 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/ngram-contains_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/ngram-contains_01_ps.plan
@@ -1,45 +1,90 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"title1": $$38, "title2": $$39}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      project ([$$38, $$39])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$40) (ASC, $$41)
           -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$49
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (and(contains($$38, $$39), lt($$40, $$41)))
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$38] <- [$$o1.getField("title")] project: [$$38, $$40]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                              data-scan []<-[$$40, $$o1] <- test.DBLP
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          assign [$$39] <- [$$o2.getField(2)] project: [$$39, $$41]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                              data-scan []<-[$$41, $$o2] <- test.CSX
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$49] <- [agg-range-map($$46, $$47, $$48)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$46, $$47, $$48] <- [agg-local-sampling($$40, $$41), agg-null-writer($$40), agg-null-writer($$41)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$40, $$41])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (and(contains($$38, $$39), lt($$40, $$41)))
                                 -- NESTED_LOOP  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$38] <- [$$o1.getField("title")] project: [$$38, $$40]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                        data-scan []<-[$$40, $$o1] <- test.DBLP
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$39] <- [$$o2.getField(2)] project: [$$39, $$41]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                                        data-scan []<-[$$41, $$o2] <- test.CSX
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/ngram-contains_02_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/ngram-contains_02_ps.plan
index d107a60..2e303c2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/ngram-contains_02_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/ngram-contains_02_ps.plan
@@ -1,45 +1,90 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"title1": $$38, "title2": $$39}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      project ([$$38, $$39])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$40) (ASC, $$41)
           -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$49
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (and(contains($$38, $$39), lt($$40, $$41)))
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$38] <- [$$o1.getField("title")] project: [$$38, $$40]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                              data-scan []<-[$$40, $$o1] <- test.CSX
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          assign [$$39] <- [$$o2.getField(2)] project: [$$39, $$41]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                              data-scan []<-[$$41, $$o2] <- test.DBLP
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$49] <- [agg-range-map($$46, $$47, $$48)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$46, $$47, $$48] <- [agg-local-sampling($$40, $$41), agg-null-writer($$40), agg-null-writer($$41)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$40, $$41])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (and(contains($$38, $$39), lt($$40, $$41)))
                                 -- NESTED_LOOP  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$38] <- [$$o1.getField("title")] project: [$$38, $$40]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                                        data-scan []<-[$$40, $$o1] <- test.CSX
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$39] <- [$$o2.getField(2)] project: [$$39, $$41]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                        data-scan []<-[$$41, $$o2] <- test.DBLP
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/ngram-contains_03_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/ngram-contains_03_ps.plan
index 903f710..8822925 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/ngram-contains_03_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/ngram-contains_03_ps.plan
@@ -1,49 +1,98 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"title1": $$38, "title2": $$39}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      project ([$$38, $$39])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$40) (ASC, $$41)
           -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$54
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (and(contains($$38, $$39), lt($$40, $$41)))
                       -- STREAM_SELECT  |PARTITIONED|
+                        assign [$$39] <- [$$o2.getField("title")] project: [$$40, $$38, $$41, $$39]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$40, $$38, $$41, $$o2])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                              unnest-map [$$41, $$o2] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$50, 1, $$50, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$50)
                                   -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                      unnest-map [$$50] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 0, missing, 12, false, 1, $$38)
+                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          assign [$$38] <- [$$49.getField("title")] project: [$$40, $$38]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                              data-scan []<-[$$40, $$49] <- test.DBLP
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$54] <- [agg-range-map($$51, $$52, $$53)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$51, $$52, $$53] <- [agg-local-sampling($$40, $$41), agg-null-writer($$40), agg-null-writer($$41)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$40, $$41])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (and(contains($$38, $$39), lt($$40, $$41)))
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$39] <- [$$o2.getField("title")] project: [$$40, $$38, $$41, $$39]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$40, $$38, $$41, $$o2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                                        unnest-map [$$41, $$o2] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$50, 1, $$50, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$50)
                                             -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                                unnest-map [$$50] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 0, missing, 12, false, 1, $$38)
+                                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$38] <- [$$49.getField("title")] project: [$$40, $$38]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                                        data-scan []<-[$$40, $$49] <- test.DBLP
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/ngram-contains_04_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/ngram-contains_04_ps.plan
index 1fcf054..b75d364 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/ngram-contains_04_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/ngram-contains_04_ps.plan
@@ -1,49 +1,98 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"title1": $$38, "title2": $$39}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      project ([$$38, $$39])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$40) (ASC, $$41)
           -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$54
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (and(contains($$38, $$39), lt($$40, $$41)))
                       -- STREAM_SELECT  |PARTITIONED|
+                        assign [$$39] <- [$$o2.getField("title")] project: [$$40, $$38, $$41, $$39]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$40, $$38, $$41, $$o2])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                              unnest-map [$$41, $$o2] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$50, 1, $$50, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$50)
                                   -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.CSX.ngram_index_CSX)  |PARTITIONED|
+                                      unnest-map [$$50] <- index-search("ngram_index_CSX", 5, "Default", "test", "CSX", true, true, 0, missing, 12, false, 1, $$38)
+                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          assign [$$38] <- [$$49.getField("title")] project: [$$40, $$38]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                              data-scan []<-[$$40, $$49] <- test.DBLP
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$54] <- [agg-range-map($$51, $$52, $$53)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$51, $$52, $$53] <- [agg-local-sampling($$40, $$41), agg-null-writer($$40), agg-null-writer($$41)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$40, $$41])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (and(contains($$38, $$39), lt($$40, $$41)))
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$39] <- [$$o2.getField("title")] project: [$$40, $$38, $$41, $$39]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$40, $$38, $$41, $$o2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                                        unnest-map [$$41, $$o2] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$50, 1, $$50, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$50)
                                             -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.CSX.ngram_index_CSX)  |PARTITIONED|
+                                                unnest-map [$$50] <- index-search("ngram_index_CSX", 5, "Default", "test", "CSX", true, true, 0, missing, 12, false, 1, $$38)
+                                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$38] <- [$$49.getField("title")] project: [$$40, $$38]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                                        data-scan []<-[$$40, $$49] <- test.DBLP
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01_ps.plan
index 4a08ca9..6f10b5d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01_ps.plan
@@ -1,81 +1,156 @@
+distribute result [$$60]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$60] <- [{"tweetid1": $$68, "loc1": $$69, "nearby-message": $$59}] project: [$$60]
     -- ASSIGN  |PARTITIONED|
+      project ([$$59, $$68, $$69])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$77)
           -- STABLE_SORT [$$77(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$77(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$92
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- PRE_CLUSTERED_GROUP_BY[$$64]  |PARTITIONED|
-                              {
+                      group by ([$$77 := $$64]) decor ([$$68; $$69]) {
+                                aggregate [$$59] <- [listify({"tweetid2": $$71, "loc2": $$67})]
                                 -- AGGREGATE  |LOCAL|
+                                  select (not(is-missing($$65)))
                                   -- STREAM_SELECT  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- PRE_CLUSTERED_GROUP_BY[$$64]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$64) (ASC, $$70)
                           -- STABLE_SORT [$$64(ASC), $$70(ASC)]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$64]  |PARTITIONED|
+                              select (spatial-intersect($$67, $$n)) retain-untrue ($$65 <- missing) project: [$$68, $$69, $$71, $$67, $$70, $$65, $$64]
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$71, $$67] <- [$$66.getField(0), $$66.getField("sender-location")] project: [$$68, $$69, $$64, $$n, $$65, $$70, $$71, $$67]
                                 -- ASSIGN  |PARTITIONED|
+                                  assign [$$66, $$70] <- [$$t2.getField(0), $$t2.getField("tweetid")] project: [$$68, $$69, $$64, $$n, $$65, $$66, $$70]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$68, $$69, $$64, $$n, $$65, $$t2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                        left-outer-unnest-map [$$65, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$89, 1, $$89, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$89)
                                             -- STABLE_SORT [$$89(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$68, $$69, $$64, $$n, $$89])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                    left-outer-unnest-map [$$85, $$86, $$87, $$88, $$89] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$81, $$82, $$83, $$84)
+                                                    -- RTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        assign [$$81, $$82, $$83, $$84] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          assign [$$n] <- [create-circle($$69, 0.5)]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            assign [$$69, $$68] <- [$$63.getField("sender-location"), $$63.getField(0)] project: [$$64, $$69, $$68]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              assign [$$63] <- [$$t1.getField(0)] project: [$$64, $$63]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                  unnest-map [$$64, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$78, true, false, false)
+                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      assign [$$78] <- [10]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$92] <- [agg-range-map($$90, $$91)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$90, $$91] <- [agg-local-sampling($$77), agg-null-writer($$77)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$77])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- PRE_CLUSTERED_GROUP_BY[$$64]  |PARTITIONED|
-                                        {
+                                group by ([$$77 := $$64]) decor ([$$68; $$69]) {
+                                          aggregate [$$59] <- [listify({"tweetid2": $$71, "loc2": $$67})]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$65)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- PRE_CLUSTERED_GROUP_BY[$$64]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$64) (ASC, $$70)
                                     -- STABLE_SORT [$$64(ASC), $$70(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$64]  |PARTITIONED|
+                                        select (spatial-intersect($$67, $$n)) retain-untrue ($$65 <- missing) project: [$$68, $$69, $$71, $$67, $$70, $$65, $$64]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$71, $$67] <- [$$66.getField(0), $$66.getField("sender-location")] project: [$$68, $$69, $$64, $$n, $$65, $$70, $$71, $$67]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$66, $$70] <- [$$t2.getField(0), $$t2.getField("tweetid")] project: [$$68, $$69, $$64, $$n, $$65, $$66, $$70]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$68, $$69, $$64, $$n, $$65, $$t2])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                  left-outer-unnest-map [$$65, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$89, 1, $$89, true, true, true)
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      order (ASC, $$89)
                                                       -- STABLE_SORT [$$89(ASC)]  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          project ([$$68, $$69, $$64, $$n, $$89])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                              left-outer-unnest-map [$$85, $$86, $$87, $$88, $$89] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$81, $$82, $$83, $$84)
+                                                              -- RTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$81, $$82, $$83, $$84] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    assign [$$n] <- [create-circle($$69, 0.5)]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      assign [$$69, $$68] <- [$$63.getField("sender-location"), $$63.getField(0)] project: [$$64, $$69, $$68]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        assign [$$63] <- [$$t1.getField(0)] project: [$$64, $$63]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                            unnest-map [$$64, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$78, true, false, false)
+                                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                assign [$$78] <- [10]
                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                  empty-tuple-source
                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02_ps.plan
index 977e29e..c0220b5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested-open-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02_ps.plan
@@ -1,81 +1,156 @@
+distribute result [$$67]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$67] <- [{"tweetid1": $$77, "loc1": $$78, "nearby-message": $$66}] project: [$$67]
     -- ASSIGN  |PARTITIONED|
+      project ([$$66, $$77, $$78])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$86)
           -- STABLE_SORT [$$86(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$86(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$101
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- PRE_CLUSTERED_GROUP_BY[$$71]  |PARTITIONED|
-                              {
+                      group by ([$$86 := $$71]) decor ([$$77; $$78]) {
+                                aggregate [$$66] <- [listify({"tweetid2": $$76, "loc2": $$74})]
                                 -- AGGREGATE  |LOCAL|
+                                  select (not(is-missing($$72)))
                                   -- STREAM_SELECT  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- PRE_CLUSTERED_GROUP_BY[$$71]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$71) (ASC, $$72)
                           -- STABLE_SORT [$$71(ASC), $$72(ASC)]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$71]  |PARTITIONED|
+                              select (and(spatial-intersect($$74, $$n), neq($$71, $$76))) retain-untrue ($$72 <- missing) project: [$$77, $$78, $$76, $$74, $$72, $$71]
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$76, $$74] <- [$$73.getField(0), $$73.getField("sender-location")] project: [$$77, $$78, $$71, $$n, $$72, $$76, $$74]
                                 -- ASSIGN  |PARTITIONED|
+                                  assign [$$73] <- [$$t2.getField(0)] project: [$$77, $$78, $$71, $$n, $$72, $$73]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$77, $$78, $$71, $$n, $$72, $$t2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                        left-outer-unnest-map [$$72, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$98, 1, $$98, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$98)
                                             -- STABLE_SORT [$$98(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$77, $$78, $$71, $$n, $$98])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                    left-outer-unnest-map [$$94, $$95, $$96, $$97, $$98] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$90, $$91, $$92, $$93)
+                                                    -- RTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        assign [$$90, $$91, $$92, $$93] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          assign [$$n] <- [create-circle($$78, 0.5)]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            assign [$$78, $$77] <- [$$70.getField("sender-location"), $$70.getField(0)] project: [$$71, $$78, $$77]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              assign [$$70] <- [$$t1.getField(0)] project: [$$71, $$70]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                  unnest-map [$$71, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$87, true, false, false)
+                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      assign [$$87] <- [10]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$101] <- [agg-range-map($$99, $$100)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$99, $$100] <- [agg-local-sampling($$86), agg-null-writer($$86)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$86])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- PRE_CLUSTERED_GROUP_BY[$$71]  |PARTITIONED|
-                                        {
+                                group by ([$$86 := $$71]) decor ([$$77; $$78]) {
+                                          aggregate [$$66] <- [listify({"tweetid2": $$76, "loc2": $$74})]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$72)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- PRE_CLUSTERED_GROUP_BY[$$71]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$71) (ASC, $$72)
                                     -- STABLE_SORT [$$71(ASC), $$72(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$71]  |PARTITIONED|
+                                        select (and(spatial-intersect($$74, $$n), neq($$71, $$76))) retain-untrue ($$72 <- missing) project: [$$77, $$78, $$76, $$74, $$72, $$71]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$76, $$74] <- [$$73.getField(0), $$73.getField("sender-location")] project: [$$77, $$78, $$71, $$n, $$72, $$76, $$74]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$73] <- [$$t2.getField(0)] project: [$$77, $$78, $$71, $$n, $$72, $$73]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$77, $$78, $$71, $$n, $$72, $$t2])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                  left-outer-unnest-map [$$72, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$98, 1, $$98, true, true, true)
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      order (ASC, $$98)
                                                       -- STABLE_SORT [$$98(ASC)]  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          project ([$$77, $$78, $$71, $$n, $$98])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                              left-outer-unnest-map [$$94, $$95, $$96, $$97, $$98] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$90, $$91, $$92, $$93)
+                                                              -- RTREE_SEARCH  |PARTITIONED|
+                                                                exchange
                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$90, $$91, $$92, $$93] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    assign [$$n] <- [create-circle($$78, 0.5)]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      assign [$$78, $$77] <- [$$70.getField("sender-location"), $$70.getField(0)] project: [$$71, $$78, $$77]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        assign [$$70] <- [$$t1.getField(0)] project: [$$71, $$70]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                            unnest-map [$$71, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$87, true, false, false)
+                                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                assign [$$87] <- [10]
                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                  empty-tuple-source
                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested_loj2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested_loj2.plan
index cc2f91a..bebe54d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested_loj2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nested_loj2.plan
@@ -1,42 +1,78 @@
+distribute result [$$70]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$70] <- [{"cust": $$c, "orders": $$68}] project: [$$70]
     -- ASSIGN  |PARTITIONED|
+      project ([$$68, $$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- PRE_CLUSTERED_GROUP_BY[$$71]  |PARTITIONED|
-                  {
+          group by ([$$82 := $$71]) decor ([$$c]) {
+                    aggregate [$$68] <- [listify({"order": $$o, "items": $$62})]
                     -- AGGREGATE  |LOCAL|
-                      -- MICRO_PRE_CLUSTERED_GROUP_BY[$$72]  |LOCAL|
-                              {
+                      group by ([$$80 := $$72]) decor ([$$c; $$o; $$71; $$75]) {
+                                aggregate [$$62] <- [listify($$l)]
                                 -- AGGREGATE  |LOCAL|
+                                  select (not(is-missing($$79)))
                                   -- STREAM_SELECT  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- MICRO_PRE_CLUSTERED_GROUP_BY[$$72]  |LOCAL|
+                        select (not(is-missing($$81)))
                         -- STREAM_SELECT  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- PRE_CLUSTERED_GROUP_BY[$$71]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$71) (ASC, $$72)
               -- STABLE_SORT [$$71(ASC), $$72(ASC)]  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$71]  |PARTITIONED|
+                  project ([$$c, $$o, $$l, $$79, $$72, $$71, $$75, $$81])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      left outer join (eq($$73, $$72))
                       -- HYBRID_HASH_JOIN [$$72][$$73]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$72]  |PARTITIONED|
+                          left outer join (eq($$75, $$71))
                           -- HYBRID_HASH_JOIN [$$71][$$75]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$71]  |PARTITIONED|
-                              -- DATASOURCE_SCAN (tpch.Customers)  |PARTITIONED|
+                              data-scan []<-[$$71, $$c] <- tpch.Customers
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$75]  |PARTITIONED|
+                              assign [$$81, $$75] <- [true, $$o.getField(1)]
                               -- ASSIGN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                  data-scan []<-[$$72, $$o] <- tpch.Orders
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$73]  |PARTITIONED|
+                          assign [$$79] <- [true]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$73, $$l])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (tpch.LineItems)  |PARTITIONED|
+                                data-scan []<-[$$73, $$74, $$l] <- tpch.LineItems
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_1_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_1_ps.plan
index d7f9bcf..2889a3f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_1_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_1_ps.plan
@@ -1,72 +1,138 @@
+distribute result [$$41]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$41] <- [{"tweetid1": $$53, "count1": $$47, "t2info": $$40}] project: [$$41]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$53)
         -- STABLE_SORT [$$53(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$53(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$61
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$44]  |PARTITIONED|
-                            {
+                    group by ([$$53 := $$44]) decor ([$$47]) {
+                              aggregate [$$40] <- [listify({"tweetid2": $$45, "count2": $$46})]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$45)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$44]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$44) (ASC, $$45)
                         -- STABLE_SORT [$$44(ASC), $$45(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$44]  |PARTITIONED|
+                            select (eq($$47, $$46)) retain-untrue ($$45 <- missing)
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$46] <- [$$t2.getField("countB")] project: [$$47, $$44, $$45, $$46]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$47, $$44, $$45, $$t2])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                    left-outer-unnest-map [$$45, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$58, 1, $$58, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$58)
                                         -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$47, $$44, $$58])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                left-outer-unnest-map [$$57, $$58] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$47, 1, $$47, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$47] <- [$$t1.getField(6)] project: [$$44, $$47]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                        unnest-map [$$44, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$54, true, false, false)
+                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            assign [$$54] <- [10]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$61] <- [agg-range-map($$59, $$60)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$59, $$60] <- [agg-local-sampling($$53), agg-null-writer($$53)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$53])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$44]  |PARTITIONED|
-                                      {
+                              group by ([$$53 := $$44]) decor ([$$47]) {
+                                        aggregate [$$40] <- [listify({"tweetid2": $$45, "count2": $$46})]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$45)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$44]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$44) (ASC, $$45)
                                   -- STABLE_SORT [$$44(ASC), $$45(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$44]  |PARTITIONED|
+                                      select (eq($$47, $$46)) retain-untrue ($$45 <- missing)
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        assign [$$46] <- [$$t2.getField("countB")] project: [$$47, $$44, $$45, $$46]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$47, $$44, $$45, $$t2])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                              left-outer-unnest-map [$$45, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$58, 1, $$58, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  order (ASC, $$58)
                                                   -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      project ([$$47, $$44, $$58])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                          left-outer-unnest-map [$$57, $$58] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$47, 1, $$47, true, true, true)
+                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                              assign [$$47] <- [$$t1.getField(6)] project: [$$44, $$47]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                  unnest-map [$$44, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$54, true, false, false)
+                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      assign [$$54] <- [10]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_2_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_2_ps.plan
index d7f9bcf..e3b654f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_2_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_2_ps.plan
@@ -1,72 +1,138 @@
+distribute result [$$41]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$41] <- [{"tweetid1": $$53, "count1": $$47, "t2info": $$40}] project: [$$41]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$53)
         -- STABLE_SORT [$$53(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$53(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$61
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$44]  |PARTITIONED|
-                            {
+                    group by ([$$53 := $$44]) decor ([$$47]) {
+                              aggregate [$$40] <- [listify({"tweetid2": $$45, "count2": $$46})]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$45)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$44]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$44) (ASC, $$45)
                         -- STABLE_SORT [$$44(ASC), $$45(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$44]  |PARTITIONED|
+                            select (eq($$47, $$46)) retain-untrue ($$45 <- missing)
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$46] <- [$$t2.getField("countB")] project: [$$47, $$44, $$45, $$46]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$47, $$44, $$45, $$t2])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                    left-outer-unnest-map [$$45, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$58, 1, $$58, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$58)
                                         -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$47, $$44, $$58])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                left-outer-unnest-map [$$57, $$58] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$47, 1, $$47, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$47] <- [$$t1.getField("countA")] project: [$$44, $$47]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                        unnest-map [$$44, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$54, true, false, false)
+                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            assign [$$54] <- [10]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$61] <- [agg-range-map($$59, $$60)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$59, $$60] <- [agg-local-sampling($$53), agg-null-writer($$53)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$53])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$44]  |PARTITIONED|
-                                      {
+                              group by ([$$53 := $$44]) decor ([$$47]) {
+                                        aggregate [$$40] <- [listify({"tweetid2": $$45, "count2": $$46})]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$45)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$44]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$44) (ASC, $$45)
                                   -- STABLE_SORT [$$44(ASC), $$45(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$44]  |PARTITIONED|
+                                      select (eq($$47, $$46)) retain-untrue ($$45 <- missing)
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        assign [$$46] <- [$$t2.getField("countB")] project: [$$47, $$44, $$45, $$46]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$47, $$44, $$45, $$t2])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                              left-outer-unnest-map [$$45, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$58, 1, $$58, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  order (ASC, $$58)
                                                   -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      project ([$$47, $$44, $$58])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                          left-outer-unnest-map [$$57, $$58] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$47, 1, $$47, true, true, true)
+                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                              assign [$$47] <- [$$t1.getField("countA")] project: [$$44, $$47]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                  unnest-map [$$44, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$54, true, false, false)
+                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      assign [$$54] <- [10]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_1_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_1_ps.plan
index 65e8723..5ce84a7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_1_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_1_ps.plan
@@ -1,72 +1,138 @@
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"tweetid1": $$58, "count1": $$52, "t2info": $$44}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$58)
         -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$58(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$66
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
-                            {
+                    group by ([$$58 := $$48]) decor ([$$52]) {
+                              aggregate [$$44] <- [listify({"tweetid2": $$49, "count2": $$51})]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$49)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$48) (ASC, $$49)
                         -- STABLE_SORT [$$48(ASC), $$49(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+                            select (and(eq($$52, $$51), neq($$48, $$49))) retain-untrue ($$49 <- missing)
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$51] <- [$$t2.getField("countB")] project: [$$52, $$48, $$49, $$51]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$52, $$48, $$49, $$t2])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                    left-outer-unnest-map [$$49, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$63, 1, $$63, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$63)
                                         -- STABLE_SORT [$$63(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$52, $$48, $$63])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                left-outer-unnest-map [$$62, $$63] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$52, 1, $$52, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$52] <- [$$t1.getField(6)] project: [$$48, $$52]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                        unnest-map [$$48, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$59, true, false, false)
+                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            assign [$$59] <- [10]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$66] <- [agg-range-map($$64, $$65)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$64, $$65] <- [agg-local-sampling($$58), agg-null-writer($$58)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$58])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
-                                      {
+                              group by ([$$58 := $$48]) decor ([$$52]) {
+                                        aggregate [$$44] <- [listify({"tweetid2": $$49, "count2": $$51})]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$49)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$48) (ASC, $$49)
                                   -- STABLE_SORT [$$48(ASC), $$49(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+                                      select (and(eq($$52, $$51), neq($$48, $$49))) retain-untrue ($$49 <- missing)
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        assign [$$51] <- [$$t2.getField("countB")] project: [$$52, $$48, $$49, $$51]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$52, $$48, $$49, $$t2])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                              left-outer-unnest-map [$$49, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$63, 1, $$63, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  order (ASC, $$63)
                                                   -- STABLE_SORT [$$63(ASC)]  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      project ([$$52, $$48, $$63])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                          left-outer-unnest-map [$$62, $$63] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$52, 1, $$52, true, true, true)
+                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                              assign [$$52] <- [$$t1.getField(6)] project: [$$48, $$52]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                  unnest-map [$$48, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$59, true, false, false)
+                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      assign [$$59] <- [10]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_2_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_2_ps.plan
index 65e8723..e8e8bf4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_2_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_2_ps.plan
@@ -1,72 +1,138 @@
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"tweetid1": $$58, "count1": $$52, "t2info": $$44}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$58)
         -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$58(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$66
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
-                            {
+                    group by ([$$58 := $$48]) decor ([$$52]) {
+                              aggregate [$$44] <- [listify({"tweetid2": $$49, "count2": $$51})]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$49)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$48) (ASC, $$49)
                         -- STABLE_SORT [$$48(ASC), $$49(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+                            select (and(eq($$52, $$51), neq($$48, $$49))) retain-untrue ($$49 <- missing)
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$51] <- [$$t2.getField("countB")] project: [$$52, $$48, $$49, $$51]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$52, $$48, $$49, $$t2])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                    left-outer-unnest-map [$$49, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$63, 1, $$63, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$63)
                                         -- STABLE_SORT [$$63(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$52, $$48, $$63])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                left-outer-unnest-map [$$62, $$63] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$52, 1, $$52, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$52] <- [$$t1.getField("countA")] project: [$$48, $$52]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                        unnest-map [$$48, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$59, true, false, false)
+                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            assign [$$59] <- [10]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$66] <- [agg-range-map($$64, $$65)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$64, $$65] <- [agg-local-sampling($$58), agg-null-writer($$58)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$58])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
-                                      {
+                              group by ([$$58 := $$48]) decor ([$$52]) {
+                                        aggregate [$$44] <- [listify({"tweetid2": $$49, "count2": $$51})]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$49)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$48) (ASC, $$49)
                                   -- STABLE_SORT [$$48(ASC), $$49(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+                                      select (and(eq($$52, $$51), neq($$48, $$49))) retain-untrue ($$49 <- missing)
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        assign [$$51] <- [$$t2.getField("countB")] project: [$$52, $$48, $$49, $$51]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$52, $$48, $$49, $$t2])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                              left-outer-unnest-map [$$49, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$63, 1, $$63, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  order (ASC, $$63)
                                                   -- STABLE_SORT [$$63(ASC)]  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      project ([$$52, $$48, $$63])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- BTREE_SEARCH (test.TweetMessages.msgCountBIx)  |PARTITIONED|
+                                                          left-outer-unnest-map [$$62, $$63] <- index-search("msgCountBIx", 0, "Default", "test", "TweetMessages", true, true, 1, $$52, 1, $$52, true, true, true)
+                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                              assign [$$52] <- [$$t1.getField("countA")] project: [$$48, $$52]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                  unnest-map [$$48, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$59, true, false, false)
+                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      assign [$$59] <- [10]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-basic/ngram-contains-panic_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-basic/ngram-contains-panic_ps.plan
index 93ca5bd..d10bcbe 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-basic/ngram-contains-panic_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-basic/ngram-contains-panic_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$15)
         -- STABLE_SORT [$$15(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$15(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$20
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField("title"), "Mu"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                        data-scan []<-[$$15, $$o] <- test.DBLP
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$20] <- [agg-range-map($$18, $$19)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$18, $$19] <- [agg-local-sampling($$15), agg-null-writer($$15)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$15])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField("title"), "Mu"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                  data-scan []<-[$$15, $$o] <- test.DBLP
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-basic/ngram-contains_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-basic/ngram-contains_ps.plan
index ed6a9c5..5c91b2b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-basic/ngram-contains_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-basic/ngram-contains_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- STABLE_SORT [$$15(ASC)]  |PARTITIONED|
-          -- RANGE_PARTITION_EXCHANGE [$$15(ASC)]  |PARTITIONED|
+        order (ASC, $$16)
+        -- STABLE_SORT [$$16(ASC)]  |PARTITIONED|
+          exchange
+          -- RANGE_PARTITION_EXCHANGE [$$16(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$23
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField("title"), "Multimedia"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                        unnest-map [$$16, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$20, 1, $$20, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+                            order (ASC, $$20)
+                            -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                unnest-map [$$20] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 0, missing, 12, false, 1, $$19)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$19] <- ["Multimedia"]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$23] <- [agg-range-map($$21, $$22)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$21, $$22] <- [agg-local-sampling($$16), agg-null-writer($$16)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$16])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField("title"), "Multimedia"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                                  unnest-map [$$16, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$20, 1, $$20, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+                                      order (ASC, $$20)
+                                      -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                          unnest-map [$$20] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 0, missing, 12, false, 1, $$19)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$19] <- ["Multimedia"]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-basic/word-contains_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-basic/word-contains_ps.plan
index 93ca5bd..f138fa5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-basic/word-contains_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-basic/word-contains_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$15)
         -- STABLE_SORT [$$15(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$15(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$20
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField("title"), "Multimedia"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                        data-scan []<-[$$15, $$o] <- test.DBLP
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$20] <- [agg-range-map($$18, $$19)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$18, $$19] <- [agg-local-sampling($$15), agg-null-writer($$15)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$15])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField("title"), "Multimedia"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                  data-scan []<-[$$15, $$o] <- test.DBLP
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01_ps.plan
index ddafba9..52654f2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01_ps.plan
@@ -1,152 +1,298 @@
+distribute result [$$59]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$59] <- [{"tweet": {"id": $$72, "topics": $$67}, "similar-tweets": $$58}] project: [$$59]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$72)
         -- STABLE_SORT [$$72(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$72(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$89
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
-                            {
+                    group by ([$$72 := $$62]) decor ([$$67]) {
+                              aggregate [$$58] <- [listify({"id": $$63, "topics": $$65})]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$63)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$62) (ASC, $$63)
                         -- STABLE_SORT [$$62(ASC), $$63(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                            project ([$$67, $$63, $$65, $$62])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$78, $$62))
                                 -- HYBRID_HASH_JOIN [$$78][$$62]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$78]  |PARTITIONED|
+                                    assign [$$78, $$t1] <- [$$62, $$79] project: [$$78]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                            unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                            -- BTREE_SEARCH  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                assign [$$80] <- [240]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                                    union ($$63, $$85, $$63) ($$65, $$83, $$65) ($$62, $$62, $$62) ($$67, $$67, $$67)
                                     -- UNION_ALL  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        select (and(neq($$63, $$62), get-item(edit-distance-check($$67, $$65, 7), 0))) retain-untrue ($$63 <- missing) project: [$$63, $$65, $$62, $$67]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$65] <- [$$t2.getField("message-text")] project: [$$62, $$67, $$63, $$65]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$62, $$67, $$63, $$t2])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                left-outer-unnest-map [$$63, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$86, 1, $$86, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    order (ASC, $$86)
                                                     -- STABLE_SORT [$$86(ASC)]  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.TweetMessages.msgNgramIx)  |PARTITIONED|
+                                                        left-outer-unnest-map [$$86] <- index-search("msgNgramIx", 5, "Default", "test", "TweetMessages", true, true, 2, 7, 12, false, 1, $$67)
+                                                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                          exchange
                                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                            select (edit-distance-string-is-filterable($$67, 7, 3, true))
                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                replicate
                                                                 -- REPLICATE  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    assign [$$67] <- [$$79.getField("message-text")] project: [$$62, $$67]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        replicate
                                                                         -- REPLICATE  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                            unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                assign [$$80] <- [240]
                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                  empty-tuple-source
                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        left outer join (and(neq($$85, $$62), get-item(edit-distance-check($$67, $$83, 7), 0)))
                                         -- NESTED_LOOP  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$83] <- [$$84.getField("message-text")] project: [$$85, $$83]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.TweetMessages)  |PARTITIONED|
+                                                data-scan []<-[$$85, $$84] <- test.TweetMessages
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            select (not(edit-distance-string-is-filterable($$67, 7, 3, true)))
                                             -- STREAM_SELECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$67] <- [$$79.getField("message-text")] project: [$$62, $$67]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        replicate
                                                         -- REPLICATE  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                            unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                assign [$$80] <- [240]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$89] <- [agg-range-map($$87, $$88)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$87, $$88] <- [agg-local-sampling($$72), agg-null-writer($$72)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$72])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
-                                      {
+                              group by ([$$72 := $$62]) decor ([$$67]) {
+                                        aggregate [$$58] <- [listify({"id": $$63, "topics": $$65})]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$63)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$62) (ASC, $$63)
                                   -- STABLE_SORT [$$62(ASC), $$63(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                                      project ([$$67, $$63, $$65, $$62])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          join (eq($$78, $$62))
                                           -- HYBRID_HASH_JOIN [$$78][$$62]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$78]  |PARTITIONED|
+                                              assign [$$78, $$t1] <- [$$62, $$79] project: [$$78]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  replicate
                                                   -- REPLICATE  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                      unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          assign [$$80] <- [240]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                                              union ($$63, $$85, $$63) ($$65, $$83, $$65) ($$62, $$62, $$62) ($$67, $$67, $$67)
                                               -- UNION_ALL  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  select (and(neq($$63, $$62), get-item(edit-distance-check($$67, $$65, 7), 0))) retain-untrue ($$63 <- missing) project: [$$63, $$65, $$62, $$67]
                                                   -- STREAM_SELECT  |PARTITIONED|
+                                                    assign [$$65] <- [$$t2.getField("message-text")] project: [$$62, $$67, $$63, $$65]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$62, $$67, $$63, $$t2])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                          left-outer-unnest-map [$$63, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$86, 1, $$86, true, true, true)
+                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              order (ASC, $$86)
                                                               -- STABLE_SORT [$$86(ASC)]  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.TweetMessages.msgNgramIx)  |PARTITIONED|
+                                                                  left-outer-unnest-map [$$86] <- index-search("msgNgramIx", 5, "Default", "test", "TweetMessages", true, true, 2, 7, 12, false, 1, $$67)
+                                                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                                    exchange
                                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                      select (edit-distance-string-is-filterable($$67, 7, 3, true))
                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          replicate
                                                                           -- REPLICATE  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              assign [$$67] <- [$$79.getField("message-text")] project: [$$62, $$67]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  replicate
                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                      -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                                      unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                          assign [$$80] <- [240]
                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                            empty-tuple-source
                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  left outer join (and(neq($$85, $$62), get-item(edit-distance-check($$67, $$83, 7), 0)))
                                                   -- NESTED_LOOP  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      assign [$$83] <- [$$84.getField("message-text")] project: [$$85, $$83]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.TweetMessages)  |PARTITIONED|
+                                                          data-scan []<-[$$85, $$84] <- test.TweetMessages
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                      select (not(edit-distance-string-is-filterable($$67, 7, 3, true)))
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          replicate
                                                           -- REPLICATE  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              assign [$$67] <- [$$79.getField("message-text")] project: [$$62, $$67]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  replicate
                                                                   -- REPLICATE  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                      unnest-map [$$62, $$79] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 1, $$80, 0, false, true, false)
+                                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          assign [$$80] <- [240]
                                                                           -- ASSIGN  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/ngram-contains_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/ngram-contains_01_ps.plan
index df1938d..b70b6cf 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/ngram-contains_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/ngram-contains_01_ps.plan
@@ -1,45 +1,90 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"title1": $$38, "title2": $$39}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      project ([$$38, $$39])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$40) (ASC, $$41)
           -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$49
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (and(contains($$38, $$39), lt($$40, $$41)))
                       -- NESTED_LOOP  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$38] <- [$$o1.getField("title")] project: [$$38, $$40]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                              data-scan []<-[$$40, $$o1] <- test.DBLP
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          assign [$$39] <- [$$o2.getField(2)] project: [$$39, $$41]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                              data-scan []<-[$$41, $$o2] <- test.CSX
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$49] <- [agg-range-map($$46, $$47, $$48)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$46, $$47, $$48] <- [agg-local-sampling($$40, $$41), agg-null-writer($$40), agg-null-writer($$41)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$40, $$41])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (and(contains($$38, $$39), lt($$40, $$41)))
                                 -- NESTED_LOOP  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$38] <- [$$o1.getField("title")] project: [$$38, $$40]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                        data-scan []<-[$$40, $$o1] <- test.DBLP
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$39] <- [$$o2.getField(2)] project: [$$39, $$41]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                                        data-scan []<-[$$41, $$o2] <- test.CSX
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/ngram-contains_02_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/ngram-contains_02_ps.plan
index 29b3560a..84dec7d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/ngram-contains_02_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/ngram-contains_02_ps.plan
@@ -1,49 +1,98 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"title1": $$38, "title2": $$39}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      project ([$$38, $$39])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$40) (ASC, $$41)
           -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$54
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (and(contains($$38, $$39), lt($$40, $$41)))
                       -- STREAM_SELECT  |PARTITIONED|
+                        assign [$$39] <- [$$o2.getField("title")] project: [$$40, $$38, $$41, $$39]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$40, $$38, $$41, $$o2])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                              unnest-map [$$41, $$o2] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$50, 1, $$50, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$50)
                                   -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.CSX.ngram_index)  |PARTITIONED|
+                                      unnest-map [$$50] <- index-search("ngram_index", 5, "Default", "test", "CSX", true, true, 0, missing, 12, false, 1, $$38)
+                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          assign [$$38] <- [$$49.getField(2)] project: [$$40, $$38]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                              data-scan []<-[$$40, $$49] <- test.DBLP
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$54] <- [agg-range-map($$51, $$52, $$53)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$51, $$52, $$53] <- [agg-local-sampling($$40, $$41), agg-null-writer($$40), agg-null-writer($$41)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$40, $$41])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (and(contains($$38, $$39), lt($$40, $$41)))
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$39] <- [$$o2.getField("title")] project: [$$40, $$38, $$41, $$39]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$40, $$38, $$41, $$o2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                                        unnest-map [$$41, $$o2] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$50, 1, $$50, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$50)
                                             -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.CSX.ngram_index)  |PARTITIONED|
+                                                unnest-map [$$50] <- index-search("ngram_index", 5, "Default", "test", "CSX", true, true, 0, missing, 12, false, 1, $$38)
+                                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$38] <- [$$49.getField(2)] project: [$$40, $$38]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                                        data-scan []<-[$$40, $$49] <- test.DBLP
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/ngram-contains_03_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/ngram-contains_03_ps.plan
index 903f710..8822925 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/ngram-contains_03_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/ngram-contains_03_ps.plan
@@ -1,49 +1,98 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"title1": $$38, "title2": $$39}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      project ([$$38, $$39])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$40) (ASC, $$41)
           -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$54
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (and(contains($$38, $$39), lt($$40, $$41)))
                       -- STREAM_SELECT  |PARTITIONED|
+                        assign [$$39] <- [$$o2.getField("title")] project: [$$40, $$38, $$41, $$39]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$40, $$38, $$41, $$o2])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                              unnest-map [$$41, $$o2] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$50, 1, $$50, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$50)
                                   -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                      unnest-map [$$50] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 0, missing, 12, false, 1, $$38)
+                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          assign [$$38] <- [$$49.getField("title")] project: [$$40, $$38]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                              data-scan []<-[$$40, $$49] <- test.DBLP
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$54] <- [agg-range-map($$51, $$52, $$53)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$51, $$52, $$53] <- [agg-local-sampling($$40, $$41), agg-null-writer($$40), agg-null-writer($$41)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$40, $$41])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (and(contains($$38, $$39), lt($$40, $$41)))
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$39] <- [$$o2.getField("title")] project: [$$40, $$38, $$41, $$39]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$40, $$38, $$41, $$o2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                                        unnest-map [$$41, $$o2] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, false, 1, $$50, 1, $$50, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$50)
                                             -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                                                unnest-map [$$50] <- index-search("ngram_index", 5, "Default", "test", "DBLP", true, true, 0, missing, 12, false, 1, $$38)
+                                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$38] <- [$$49.getField("title")] project: [$$40, $$38]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                                        data-scan []<-[$$40, $$49] <- test.DBLP
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/ngram-contains_04_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/ngram-contains_04_ps.plan
index 1fcf054..b75d364 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/ngram-contains_04_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/ngram-contains_04_ps.plan
@@ -1,49 +1,98 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"title1": $$38, "title2": $$39}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      project ([$$38, $$39])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$40) (ASC, $$41)
           -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$54
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (and(contains($$38, $$39), lt($$40, $$41)))
                       -- STREAM_SELECT  |PARTITIONED|
+                        assign [$$39] <- [$$o2.getField("title")] project: [$$40, $$38, $$41, $$39]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$40, $$38, $$41, $$o2])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                              unnest-map [$$41, $$o2] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$50, 1, $$50, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$50)
                                   -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.CSX.ngram_index_CSX)  |PARTITIONED|
+                                      unnest-map [$$50] <- index-search("ngram_index_CSX", 5, "Default", "test", "CSX", true, true, 0, missing, 12, false, 1, $$38)
+                                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          assign [$$38] <- [$$49.getField("title")] project: [$$40, $$38]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                              data-scan []<-[$$40, $$49] <- test.DBLP
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$54] <- [agg-range-map($$51, $$52, $$53)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$51, $$52, $$53] <- [agg-local-sampling($$40, $$41), agg-null-writer($$40), agg-null-writer($$41)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$40, $$41])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (and(contains($$38, $$39), lt($$40, $$41)))
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$39] <- [$$o2.getField("title")] project: [$$40, $$38, $$41, $$39]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$40, $$38, $$41, $$o2])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                                        unnest-map [$$41, $$o2] <- index-search("CSX", 0, "Default", "test", "CSX", true, false, 1, $$50, 1, $$50, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$50)
                                             -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.CSX.ngram_index_CSX)  |PARTITIONED|
+                                                unnest-map [$$50] <- index-search("ngram_index_CSX", 5, "Default", "test", "CSX", true, true, 0, missing, 12, false, 1, $$38)
+                                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$38] <- [$$49.getField("title")] project: [$$40, $$38]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                                        data-scan []<-[$$40, $$49] <- test.DBLP
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01_ps.plan
index 58f231f..0a28910 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01_ps.plan
@@ -1,76 +1,146 @@
+distribute result [$$53]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$53] <- [{"tweetid1": $$64, "loc1": $$56, "nearby-message": $$52}] project: [$$53]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$64)
         -- STABLE_SORT [$$64(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$64(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$79
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$57]  |PARTITIONED|
-                            {
+                    group by ([$$64 := $$57]) decor ([$$56]) {
+                              aggregate [$$52] <- [listify({"tweetid2": $$58, "loc2": $$59})]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$58)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$57]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$57) (ASC, $$58)
                         -- STABLE_SORT [$$57(ASC), $$58(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
+                            select (spatial-intersect($$59, $$n)) retain-untrue ($$58 <- missing) project: [$$56, $$58, $$59, $$57]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$59] <- [$$t2.getField("sender-location")] project: [$$56, $$57, $$n, $$58, $$59]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$56, $$57, $$n, $$58, $$t2])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                    left-outer-unnest-map [$$58, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$76, 1, $$76, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$76)
                                         -- STABLE_SORT [$$76(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$56, $$57, $$n, $$76])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                left-outer-unnest-map [$$72, $$73, $$74, $$75, $$76] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$68, $$69, $$70, $$71)
+                                                -- RTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$68, $$69, $$70, $$71] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      assign [$$n] <- [create-circle($$56, 0.5)]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        assign [$$56] <- [$$t1.getField("sender-location")] project: [$$57, $$56]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                            unnest-map [$$57, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$65, true, false, false)
+                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                assign [$$65] <- [10]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$79] <- [agg-range-map($$77, $$78)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$77, $$78] <- [agg-local-sampling($$64), agg-null-writer($$64)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$64])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$57]  |PARTITIONED|
-                                      {
+                              group by ([$$64 := $$57]) decor ([$$56]) {
+                                        aggregate [$$52] <- [listify({"tweetid2": $$58, "loc2": $$59})]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$58)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$57]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$57) (ASC, $$58)
                                   -- STABLE_SORT [$$57(ASC), $$58(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
+                                      select (spatial-intersect($$59, $$n)) retain-untrue ($$58 <- missing) project: [$$56, $$58, $$59, $$57]
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        assign [$$59] <- [$$t2.getField("sender-location")] project: [$$56, $$57, $$n, $$58, $$59]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$56, $$57, $$n, $$58, $$t2])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                              left-outer-unnest-map [$$58, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$76, 1, $$76, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  order (ASC, $$76)
                                                   -- STABLE_SORT [$$76(ASC)]  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      project ([$$56, $$57, $$n, $$76])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                          left-outer-unnest-map [$$72, $$73, $$74, $$75, $$76] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$68, $$69, $$70, $$71)
+                                                          -- RTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                              assign [$$68, $$69, $$70, $$71] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                assign [$$n] <- [create-circle($$56, 0.5)]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  assign [$$56] <- [$$t1.getField("sender-location")] project: [$$57, $$56]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                      unnest-map [$$57, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$65, true, false, false)
+                                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          assign [$$65] <- [10]
                                                                           -- ASSIGN  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02_ps.plan
index 4b2546a..6c9a0c3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02_ps.plan
@@ -1,76 +1,146 @@
+distribute result [$$57]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$57] <- [{"tweetid1": $$69, "loc1": $$60, "nearby-message": $$56}] project: [$$57]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$69)
         -- STABLE_SORT [$$69(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$69(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$84
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$61]  |PARTITIONED|
-                            {
+                    group by ([$$69 := $$61]) decor ([$$60]) {
+                              aggregate [$$56] <- [listify({"tweetid2": $$62, "loc2": $$64})]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$62)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$61]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$61) (ASC, $$62)
                         -- STABLE_SORT [$$61(ASC), $$62(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$61]  |PARTITIONED|
+                            select (and(spatial-intersect($$64, $$n), neq($$61, $$62))) retain-untrue ($$62 <- missing) project: [$$60, $$62, $$64, $$61]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$64] <- [$$t2.getField("sender-location")] project: [$$60, $$61, $$n, $$62, $$64]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$60, $$61, $$n, $$62, $$t2])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                    left-outer-unnest-map [$$62, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$81, 1, $$81, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$81)
                                         -- STABLE_SORT [$$81(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$60, $$61, $$n, $$81])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                left-outer-unnest-map [$$77, $$78, $$79, $$80, $$81] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$73, $$74, $$75, $$76)
+                                                -- RTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$73, $$74, $$75, $$76] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      assign [$$n] <- [create-circle($$60, 0.5)]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        assign [$$60] <- [$$t1.getField("sender-location")] project: [$$61, $$60]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                            unnest-map [$$61, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$70, true, false, false)
+                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                assign [$$70] <- [10]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$84] <- [agg-range-map($$82, $$83)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$82, $$83] <- [agg-local-sampling($$69), agg-null-writer($$69)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$69])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$61]  |PARTITIONED|
-                                      {
+                              group by ([$$69 := $$61]) decor ([$$60]) {
+                                        aggregate [$$56] <- [listify({"tweetid2": $$62, "loc2": $$64})]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$62)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$61]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$61) (ASC, $$62)
                                   -- STABLE_SORT [$$61(ASC), $$62(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$61]  |PARTITIONED|
+                                      select (and(spatial-intersect($$64, $$n), neq($$61, $$62))) retain-untrue ($$62 <- missing) project: [$$60, $$62, $$64, $$61]
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        assign [$$64] <- [$$t2.getField("sender-location")] project: [$$60, $$61, $$n, $$62, $$64]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$60, $$61, $$n, $$62, $$t2])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                              left-outer-unnest-map [$$62, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$81, 1, $$81, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  order (ASC, $$81)
                                                   -- STABLE_SORT [$$81(ASC)]  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      project ([$$60, $$61, $$n, $$81])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                          left-outer-unnest-map [$$77, $$78, $$79, $$80, $$81] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$73, $$74, $$75, $$76)
+                                                          -- RTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                              assign [$$73, $$74, $$75, $$76] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                assign [$$n] <- [create-circle($$60, 0.5)]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  assign [$$60] <- [$$t1.getField("sender-location")] project: [$$61, $$60]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                      unnest-map [$$61, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$70, true, false, false)
+                                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          assign [$$70] <- [10]
                                                                           -- ASSIGN  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-03.plan
index 093ddc0..000b228 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-03.plan
@@ -1,16 +1,32 @@
+distribute result [$$19]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(eq($$t.getField("c_x"), "x2"), eq($$t.getField("c_z"), "z2"))) project: [$$19]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$19] <- [$$t.getField("c_value")]
       -- ASSIGN  |PARTITIONED|
+        project ([$$t])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+            unnest-map [$$20, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$28, 1, $$28, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$28)
                 -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$28])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.TestOpen.idx_xyz)  |PARTITIONED|
+                        unnest-map [$$25, $$26, $$27, $$28] <- index-search("idx_xyz", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 1, $$24, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$23, $$24] <- ["x2", "x2"]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-04.plan
index 741828de..186a818 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-04.plan
@@ -1,16 +1,32 @@
+distribute result [$$21]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(eq($$t.getField("c_x"), "x2"), gt($$t.getField("c_y"), 1), eq($$t.getField("c_z"), "z2"))) project: [$$21]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$21] <- [$$t.getField("c_value")]
       -- ASSIGN  |PARTITIONED|
+        project ([$$t])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+            unnest-map [$$22, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$31, 1, $$31, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$31)
                 -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$31])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.TestOpen.idx_xyz)  |PARTITIONED|
+                        unnest-map [$$28, $$29, $$30, $$31] <- index-search("idx_xyz", 0, "Default", "test", "TestOpen", false, false, 1, $$26, 1, $$27, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$26, $$27] <- ["x2", "x2"]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-05.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-05.plan
index 0732795..5b93756 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-05.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-05.plan
@@ -1,23 +1,46 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"c1": $$38, "c2": $$39}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$38(ASC), $$39(ASC) ]  |PARTITIONED|
+        order (ASC, $$38) (ASC, $$39)
         -- STABLE_SORT [$$38(ASC), $$39(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$38, $$39])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (eq($$36, $$37))
                 -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                    assign [$$38, $$36] <- [$$t1.getField("c_x"), $$t1.getField("c_s")] project: [$$38, $$36]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$t1])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                          data-scan []<-[$$34, $$t1] <- test.TestOpen1
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                    assign [$$39, $$37] <- [$$t2.getField("c_x"), $$t2.getField("c_s")] project: [$$39, $$37]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$t2])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.TestOpen2)  |PARTITIONED|
+                          data-scan []<-[$$35, $$t2] <- test.TestOpen2
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-05_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-05_ps.plan
index eb4e601..b9cb950 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-05_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-05_ps.plan
@@ -1,51 +1,102 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"c1": $$38, "c2": $$39}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$38) (ASC, $$39)
         -- STABLE_SORT [$$38(ASC), $$39(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$38(ASC), $$39(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$45
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$38, $$39])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$36, $$37))
                         -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                            assign [$$38, $$36] <- [$$t1.getField("c_x"), $$t1.getField("c_s")] project: [$$38, $$36]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$t1])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                                  data-scan []<-[$$34, $$t1] <- test.TestOpen1
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                            assign [$$39, $$37] <- [$$t2.getField("c_x"), $$t2.getField("c_s")] project: [$$39, $$37]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$t2])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.TestOpen2)  |PARTITIONED|
+                                  data-scan []<-[$$35, $$t2] <- test.TestOpen2
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$45] <- [agg-range-map($$42, $$43, $$44)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$42, $$43, $$44] <- [agg-local-sampling($$38, $$39), agg-null-writer($$38), agg-null-writer($$39)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$38, $$39])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$36, $$37))
                                 -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                                    assign [$$38, $$36] <- [$$t1.getField("c_x"), $$t1.getField("c_s")] project: [$$38, $$36]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$t1])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                                          data-scan []<-[$$34, $$t1] <- test.TestOpen1
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                                    assign [$$39, $$37] <- [$$t2.getField("c_x"), $$t2.getField("c_s")] project: [$$39, $$37]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$t2])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.TestOpen2)  |PARTITIONED|
+                                          data-scan []<-[$$35, $$t2] <- test.TestOpen2
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-06.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-06.plan
index 0732795..5b93756 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-06.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-06.plan
@@ -1,23 +1,46 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"c1": $$38, "c2": $$39}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$38(ASC), $$39(ASC) ]  |PARTITIONED|
+        order (ASC, $$38) (ASC, $$39)
         -- STABLE_SORT [$$38(ASC), $$39(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$38, $$39])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (eq($$36, $$37))
                 -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                    assign [$$38, $$36] <- [$$t1.getField("c_x"), $$t1.getField("c_s")] project: [$$38, $$36]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$t1])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                          data-scan []<-[$$34, $$t1] <- test.TestOpen1
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                    assign [$$39, $$37] <- [$$t2.getField("c_x"), $$t2.getField("c_s")] project: [$$39, $$37]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$t2])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.TestOpen2)  |PARTITIONED|
+                          data-scan []<-[$$35, $$t2] <- test.TestOpen2
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-06_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-06_ps.plan
index eb4e601..b9cb950 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-06_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-06_ps.plan
@@ -1,51 +1,102 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"c1": $$38, "c2": $$39}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$38) (ASC, $$39)
         -- STABLE_SORT [$$38(ASC), $$39(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$38(ASC), $$39(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$45
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$38, $$39])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$36, $$37))
                         -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                            assign [$$38, $$36] <- [$$t1.getField("c_x"), $$t1.getField("c_s")] project: [$$38, $$36]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$t1])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                                  data-scan []<-[$$34, $$t1] <- test.TestOpen1
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                            assign [$$39, $$37] <- [$$t2.getField("c_x"), $$t2.getField("c_s")] project: [$$39, $$37]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$t2])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.TestOpen2)  |PARTITIONED|
+                                  data-scan []<-[$$35, $$t2] <- test.TestOpen2
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$45] <- [agg-range-map($$42, $$43, $$44)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$42, $$43, $$44] <- [agg-local-sampling($$38, $$39), agg-null-writer($$38), agg-null-writer($$39)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$38, $$39])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$36, $$37))
                                 -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                                    assign [$$38, $$36] <- [$$t1.getField("c_x"), $$t1.getField("c_s")] project: [$$38, $$36]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$t1])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                                          data-scan []<-[$$34, $$t1] <- test.TestOpen1
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                                    assign [$$39, $$37] <- [$$t2.getField("c_x"), $$t2.getField("c_s")] project: [$$39, $$37]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$t2])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.TestOpen2)  |PARTITIONED|
+                                          data-scan []<-[$$35, $$t2] <- test.TestOpen2
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-07.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-07.plan
index 09a9501..6ff5356 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-07.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-07.plan
@@ -1,23 +1,46 @@
+distribute result [$$32]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"c1": $$40, "c2": $$41}] project: [$$32]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$40(ASC), $$41(ASC) ]  |PARTITIONED|
+        order (ASC, $$40) (ASC, $$41)
         -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$40, $$41])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (eq($$37, $$38))
                 -- HYBRID_HASH_JOIN [$$37][$$38]  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                    assign [$$37, $$40] <- [to-string($$t1.getField("c_s")), $$t1.getField("c_x")] project: [$$40, $$37]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$t1])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                          data-scan []<-[$$35, $$t1] <- test.TestOpen1
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+                    assign [$$41, $$38] <- [$$t2.getField("c_x"), $$t2.getField("c_s")] project: [$$41, $$38]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$t2])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.TestOpen2)  |PARTITIONED|
+                          data-scan []<-[$$36, $$t2] <- test.TestOpen2
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-07_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-07_ps.plan
index df1a86f..17587b1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-07_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-07_ps.plan
@@ -1,51 +1,102 @@
+distribute result [$$32]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"c1": $$40, "c2": $$41}] project: [$$32]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$40) (ASC, $$41)
         -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$47
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$40, $$41])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$37, $$38))
                         -- HYBRID_HASH_JOIN [$$37][$$38]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                            assign [$$37, $$40] <- [to-string($$t1.getField("c_s")), $$t1.getField("c_x")] project: [$$40, $$37]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$t1])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                                  data-scan []<-[$$35, $$t1] <- test.TestOpen1
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+                            assign [$$41, $$38] <- [$$t2.getField("c_x"), $$t2.getField("c_s")] project: [$$41, $$38]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$t2])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.TestOpen2)  |PARTITIONED|
+                                  data-scan []<-[$$36, $$t2] <- test.TestOpen2
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$47] <- [agg-range-map($$44, $$45, $$46)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$44, $$45, $$46] <- [agg-local-sampling($$40, $$41), agg-null-writer($$40), agg-null-writer($$41)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$40, $$41])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$37, $$38))
                                 -- HYBRID_HASH_JOIN [$$37][$$38]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                                    assign [$$37, $$40] <- [to-string($$t1.getField("c_s")), $$t1.getField("c_x")] project: [$$40, $$37]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$t1])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                                          data-scan []<-[$$35, $$t1] <- test.TestOpen1
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+                                    assign [$$41, $$38] <- [$$t2.getField("c_x"), $$t2.getField("c_s")] project: [$$41, $$38]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$t2])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.TestOpen2)  |PARTITIONED|
+                                          data-scan []<-[$$36, $$t2] <- test.TestOpen2
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-08.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-08.plan
index e7a7e6c..1c3f6ec 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-08.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-08.plan
@@ -1,24 +1,48 @@
+distribute result [$$32]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"c1": $$40, "c2": $$41}] project: [$$32]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$40(ASC), $$41(ASC) ]  |PARTITIONED|
+        order (ASC, $$40) (ASC, $$41)
         -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$37, $$t2.getField("c_s"))) project: [$$40, $$41]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$41] <- [$$t2.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$40, $$37, $$t2])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.TestOpen2.TestOpen2)  |PARTITIONED|
+                    unnest-map [$$36, $$t2] <- index-search("TestOpen2", 0, "Default", "test", "TestOpen2", true, false, 1, $$45, 1, $$45, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$45)
                         -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$40, $$37, $$45])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.TestOpen2.idx_t2_s)  |PARTITIONED|
+                                unnest-map [$$44, $$45] <- index-search("idx_t2_s", 0, "Default", "test", "TestOpen2", true, true, 1, $$37, 1, $$37, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$37, $$40] <- [to-string($$t1.getField("c_s")), $$t1.getField("c_x")] project: [$$37, $$40]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$t1])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                                          data-scan []<-[$$35, $$t1] <- test.TestOpen1
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-08_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-08_ps.plan
index bd8b971..c7d0124 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-08_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-08_ps.plan
@@ -1,53 +1,106 @@
+distribute result [$$32]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"c1": $$40, "c2": $$41}] project: [$$32]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$40) (ASC, $$41)
         -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$49
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (eq($$37, $$t2.getField("c_s"))) project: [$$40, $$41]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$41] <- [$$t2.getField("c_x")]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$40, $$37, $$t2])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.TestOpen2.TestOpen2)  |PARTITIONED|
+                            unnest-map [$$36, $$t2] <- index-search("TestOpen2", 0, "Default", "test", "TestOpen2", true, false, 1, $$45, 1, $$45, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$45)
                                 -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$40, $$37, $$45])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TestOpen2.idx_t2_s)  |PARTITIONED|
+                                        unnest-map [$$44, $$45] <- index-search("idx_t2_s", 0, "Default", "test", "TestOpen2", true, true, 1, $$37, 1, $$37, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            assign [$$37, $$40] <- [to-string($$t1.getField("c_s")), $$t1.getField("c_x")] project: [$$37, $$40]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$t1])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                                                  data-scan []<-[$$35, $$t1] <- test.TestOpen1
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$49] <- [agg-range-map($$46, $$47, $$48)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$46, $$47, $$48] <- [agg-local-sampling($$40, $$41), agg-null-writer($$40), agg-null-writer($$41)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (eq($$37, $$t2.getField("c_s"))) project: [$$40, $$41]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$41] <- [$$t2.getField("c_x")]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$40, $$37, $$t2])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TestOpen2.TestOpen2)  |PARTITIONED|
+                                    unnest-map [$$36, $$t2] <- index-search("TestOpen2", 0, "Default", "test", "TestOpen2", true, false, 1, $$45, 1, $$45, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$45)
                                         -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$40, $$37, $$45])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TestOpen2.idx_t2_s)  |PARTITIONED|
+                                                unnest-map [$$44, $$45] <- index-search("idx_t2_s", 0, "Default", "test", "TestOpen2", true, true, 1, $$37, 1, $$37, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$37, $$40] <- [to-string($$t1.getField("c_s")), $$t1.getField("c_x")] project: [$$37, $$40]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$t1])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                                                          data-scan []<-[$$35, $$t1] <- test.TestOpen1
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-09.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-09.plan
index afc9224..e249f74 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-09.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-09.plan
@@ -1,24 +1,48 @@
+distribute result [$$32]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"c1": $$40, "c2": $$41}] project: [$$32]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$40(ASC), $$41(ASC) ]  |PARTITIONED|
+        order (ASC, $$40) (ASC, $$41)
         -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$37, $$t2.getField("c_i64"))) project: [$$40, $$41]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$41] <- [$$t2.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$40, $$37, $$t2])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.TestOpen2.TestOpen2)  |PARTITIONED|
+                    unnest-map [$$36, $$t2] <- index-search("TestOpen2", 0, "Default", "test", "TestOpen2", true, false, 1, $$45, 1, $$45, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$45)
                         -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$40, $$37, $$45])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.TestOpen2.idx_t2_i64)  |PARTITIONED|
+                                unnest-map [$$44, $$45] <- index-search("idx_t2_i64", 0, "Default", "test", "TestOpen2", true, true, 1, $$37, 1, $$37, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$37, $$40] <- [to-bigint($$t1.getField("c_i64")), $$t1.getField("c_x")] project: [$$37, $$40]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$t1])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                                          data-scan []<-[$$35, $$t1] <- test.TestOpen1
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-09_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-09_ps.plan
index a98c6a7..ce09108 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-09_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-09_ps.plan
@@ -1,53 +1,106 @@
+distribute result [$$32]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"c1": $$40, "c2": $$41}] project: [$$32]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$40) (ASC, $$41)
         -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$49
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (eq($$37, $$t2.getField("c_i64"))) project: [$$40, $$41]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$41] <- [$$t2.getField("c_x")]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$40, $$37, $$t2])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.TestOpen2.TestOpen2)  |PARTITIONED|
+                            unnest-map [$$36, $$t2] <- index-search("TestOpen2", 0, "Default", "test", "TestOpen2", true, false, 1, $$45, 1, $$45, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$45)
                                 -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$40, $$37, $$45])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TestOpen2.idx_t2_i64)  |PARTITIONED|
+                                        unnest-map [$$44, $$45] <- index-search("idx_t2_i64", 0, "Default", "test", "TestOpen2", true, true, 1, $$37, 1, $$37, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            assign [$$37, $$40] <- [to-bigint($$t1.getField("c_i64")), $$t1.getField("c_x")] project: [$$37, $$40]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$t1])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                                                  data-scan []<-[$$35, $$t1] <- test.TestOpen1
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$49] <- [agg-range-map($$46, $$47, $$48)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$46, $$47, $$48] <- [agg-local-sampling($$40, $$41), agg-null-writer($$40), agg-null-writer($$41)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (eq($$37, $$t2.getField("c_i64"))) project: [$$40, $$41]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$41] <- [$$t2.getField("c_x")]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$40, $$37, $$t2])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TestOpen2.TestOpen2)  |PARTITIONED|
+                                    unnest-map [$$36, $$t2] <- index-search("TestOpen2", 0, "Default", "test", "TestOpen2", true, false, 1, $$45, 1, $$45, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$45)
                                         -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$40, $$37, $$45])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TestOpen2.idx_t2_i64)  |PARTITIONED|
+                                                unnest-map [$$44, $$45] <- index-search("idx_t2_i64", 0, "Default", "test", "TestOpen2", true, true, 1, $$37, 1, $$37, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$37, $$40] <- [to-bigint($$t1.getField("c_i64")), $$t1.getField("c_x")] project: [$$37, $$40]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$t1])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                                                          data-scan []<-[$$35, $$t1] <- test.TestOpen1
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-04.plan
index 1fd5284..0cd333c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-04.plan
@@ -1,20 +1,40 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$t.getField("c_s"), "world")) project: [$$21]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$21] <- [$$t.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                    unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$26, 1, $$26, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$26)
                         -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$26])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.TestOpen.idx_s)  |PARTITIONED|
+                                unnest-map [$$25, $$26] <- index-search("idx_s", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 1, $$24, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$23, $$24] <- ["world", "world"]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-04_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-04_ps.plan
index bfa6300..048ad39 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-04_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-04_ps.plan
@@ -1,45 +1,90 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$29
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (eq($$t.getField("c_s"), "world")) project: [$$21]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$21] <- [$$t.getField("c_x")]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                            unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$26, 1, $$26, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$26)
                                 -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$26])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TestOpen.idx_s)  |PARTITIONED|
+                                        unnest-map [$$25, $$26] <- index-search("idx_s", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 1, $$24, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$23, $$24] <- ["world", "world"]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$29] <- [agg-range-map($$27, $$28)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$27, $$28] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (eq($$t.getField("c_s"), "world")) project: [$$21]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$21] <- [$$t.getField("c_x")]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                                    unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$26, 1, $$26, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$26)
                                         -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$26])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TestOpen.idx_s)  |PARTITIONED|
+                                                unnest-map [$$25, $$26] <- index-search("idx_s", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 1, $$24, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$23, $$24] <- ["world", "world"]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-05.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-05.plan
index 57a6050..4dfa1ff 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-05.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-05.plan
@@ -1,20 +1,40 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$t.getField("c_i64"), 2)) project: [$$21]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$21] <- [$$t.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                    unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$26, 1, $$26, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$26)
                         -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$26])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.TestOpen.idx_i64)  |PARTITIONED|
+                                unnest-map [$$25, $$26] <- index-search("idx_i64", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 1, $$24, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$23, $$24] <- [2, 2]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-05_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-05_ps.plan
index 308a979..aa34d0e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-05_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-05_ps.plan
@@ -1,45 +1,90 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$29
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (eq($$t.getField("c_i64"), 2)) project: [$$21]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$21] <- [$$t.getField("c_x")]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                            unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$26, 1, $$26, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$26)
                                 -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$26])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TestOpen.idx_i64)  |PARTITIONED|
+                                        unnest-map [$$25, $$26] <- index-search("idx_i64", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 1, $$24, true, true, true)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$23, $$24] <- [2, 2]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$29] <- [agg-range-map($$27, $$28)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$27, $$28] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (eq($$t.getField("c_i64"), 2)) project: [$$21]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$21] <- [$$t.getField("c_x")]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                                    unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$26, 1, $$26, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$26)
                                         -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$26])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TestOpen.idx_i64)  |PARTITIONED|
+                                                unnest-map [$$25, $$26] <- index-search("idx_i64", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 1, $$24, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$23, $$24] <- [2, 2]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-06.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-06.plan
index 156ff5a..2ef12f0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-06.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-06.plan
@@ -1,20 +1,40 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$t.getField("c_i64"), 2)) project: [$$21]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$21] <- [$$t.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                    unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$25, 1, $$25, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$25)
                         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$25])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.TestOpen.idx_i64)  |PARTITIONED|
+                                unnest-map [$$24, $$25] <- index-search("idx_i64", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 0, true, true, false)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$23] <- [2]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-06_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-06_ps.plan
index 78ac4aa..9a51c0c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-06_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-06_ps.plan
@@ -1,45 +1,90 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$28
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (gt($$t.getField("c_i64"), 2)) project: [$$21]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$21] <- [$$t.getField("c_x")]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                            unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$25, 1, $$25, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$25)
                                 -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$25])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TestOpen.idx_i64)  |PARTITIONED|
+                                        unnest-map [$$24, $$25] <- index-search("idx_i64", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 0, true, true, false)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$23] <- [2]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$28] <- [agg-range-map($$26, $$27)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$26, $$27] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (gt($$t.getField("c_i64"), 2)) project: [$$21]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$21] <- [$$t.getField("c_x")]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                                    unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$25, 1, $$25, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$25)
                                         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$25])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TestOpen.idx_i64)  |PARTITIONED|
+                                                unnest-map [$$24, $$25] <- index-search("idx_i64", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 0, true, true, false)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$23] <- [2]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-07.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-07.plan
index 156ff5a..b4a380c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-07.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-07.plan
@@ -1,20 +1,40 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$t.getField("c_i64"), 2.0)) project: [$$21]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$21] <- [$$t.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                    unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$25, 1, $$25, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$25)
                         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$25])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.TestOpen.idx_i64)  |PARTITIONED|
+                                unnest-map [$$24, $$25] <- index-search("idx_i64", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 0, true, true, false)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$23] <- [2]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-07_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-07_ps.plan
index 78ac4aa..989fc84 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-07_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-07_ps.plan
@@ -1,45 +1,90 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$28
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (gt($$t.getField("c_i64"), 2.0)) project: [$$21]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$21] <- [$$t.getField("c_x")]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                            unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$25, 1, $$25, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$25)
                                 -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$25])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TestOpen.idx_i64)  |PARTITIONED|
+                                        unnest-map [$$24, $$25] <- index-search("idx_i64", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 0, true, true, false)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$23] <- [2]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$28] <- [agg-range-map($$26, $$27)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$26, $$27] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (gt($$t.getField("c_i64"), 2.0)) project: [$$21]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$21] <- [$$t.getField("c_x")]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                                    unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$25, 1, $$25, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$25)
                                         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$25])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TestOpen.idx_i64)  |PARTITIONED|
+                                                unnest-map [$$24, $$25] <- index-search("idx_i64", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 0, true, true, false)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$23] <- [2]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-08.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-08.plan
index 71142c3..4956cde 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-08.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-08.plan
@@ -1,20 +1,40 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$t.getField("c_i8"), 2)) project: [$$21]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$21] <- [$$t.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                    unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$25, 1, $$25, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$25)
                         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$25])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.TestOpen.idx_i8)  |PARTITIONED|
+                                unnest-map [$$24, $$25] <- index-search("idx_i8", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 0, true, true, false)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$23] <- [2]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-08_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-08_ps.plan
index 70ec934..90067d5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-08_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-08_ps.plan
@@ -1,45 +1,90 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$28
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (gt($$t.getField("c_i8"), 2)) project: [$$21]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$21] <- [$$t.getField("c_x")]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                            unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$25, 1, $$25, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$25)
                                 -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$25])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TestOpen.idx_i8)  |PARTITIONED|
+                                        unnest-map [$$24, $$25] <- index-search("idx_i8", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 0, true, true, false)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$23] <- [2]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$28] <- [agg-range-map($$26, $$27)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$26, $$27] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (gt($$t.getField("c_i8"), 2)) project: [$$21]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$21] <- [$$t.getField("c_x")]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                                    unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$25, 1, $$25, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$25)
                                         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$25])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TestOpen.idx_i8)  |PARTITIONED|
+                                                unnest-map [$$24, $$25] <- index-search("idx_i8", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 0, true, true, false)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$23] <- [2]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-09.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-09.plan
index 71142c3..b79d529 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-09.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-09.plan
@@ -1,20 +1,40 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$t.getField("c_i8"), 2.5)) project: [$$21]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$21] <- [$$t.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                    unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$25, 1, $$25, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$25)
                         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$25])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.TestOpen.idx_i8)  |PARTITIONED|
+                                unnest-map [$$24, $$25] <- index-search("idx_i8", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 0, true, true, false)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$23] <- [2]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-09_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-09_ps.plan
index 70ec934..89cdfd6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-09_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-09_ps.plan
@@ -1,45 +1,90 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$28
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (gt($$t.getField("c_i8"), 2.5)) project: [$$21]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$21] <- [$$t.getField("c_x")]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                            unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$25, 1, $$25, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$25)
                                 -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$25])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TestOpen.idx_i8)  |PARTITIONED|
+                                        unnest-map [$$24, $$25] <- index-search("idx_i8", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 0, true, true, false)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$23] <- [2]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$28] <- [agg-range-map($$26, $$27)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$26, $$27] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (gt($$t.getField("c_i8"), 2.5)) project: [$$21]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$21] <- [$$t.getField("c_x")]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                                    unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$25, 1, $$25, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$25)
                                         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$25])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TestOpen.idx_i8)  |PARTITIONED|
+                                                unnest-map [$$24, $$25] <- index-search("idx_i8", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 0, true, true, false)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$23] <- [2]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-10.plan
index c830e00..13a1619 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-10.plan
@@ -1,20 +1,40 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (ge($$t.getField("c_d"), 3.25)) project: [$$21]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$21] <- [$$t.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                    unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$25, 1, $$25, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$25)
                         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$25])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.TestOpen.idx_d)  |PARTITIONED|
+                                unnest-map [$$24, $$25] <- index-search("idx_d", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 0, true, true, false)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$23] <- [3.25]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-105.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-105.plan
index 96aaed6..bf26a49 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-105.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-105.plan
@@ -1,31 +1,62 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$20] <- [{"res": $$25}] project: [$$20]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+        order (ASC, $$25)
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$t.getField("c_i8"), 2), lt($$t.getField("c_i64"), 3))) project: [$$25]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25] <- [$$t.getField("c_x")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                    unnest-map [$$22, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$33, 1, $$33, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        intersect [$$33] <- [[$$29], [$$32]]
                         -- INTERSECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$29)
                             -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$29])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TestOpen.idx_3)  |PARTITIONED|
+                                    unnest-map [$$28, $$29] <- index-search("idx_3", 0, "Default", "test", "TestOpen", false, false, 0, 1, $$27, true, true, false)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$27] <- [3]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$32)
                             -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$32])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TestOpen.idx_4)  |PARTITIONED|
+                                    unnest-map [$$31, $$32] <- index-search("idx_4", 0, "Default", "test", "TestOpen", false, false, 1, $$30, 0, true, true, false)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$30] <- [2]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-105_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-105_ps.plan
index b5eca38..a5dbf36 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-105_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-105_ps.plan
@@ -1,67 +1,134 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$20] <- [{"res": $$25}] project: [$$20]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$25)
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$25(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$36
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (and(gt($$t.getField("c_i8"), 2), lt($$t.getField("c_i64"), 3))) project: [$$25]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$25] <- [$$t.getField("c_x")]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                            unnest-map [$$22, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$33, 1, $$33, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                intersect [$$33] <- [[$$29], [$$32]]
                                 -- INTERSECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$29)
                                     -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        project ([$$29])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- BTREE_SEARCH (test.TestOpen.idx_3)  |PARTITIONED|
+                                            unnest-map [$$28, $$29] <- index-search("idx_3", 0, "Default", "test", "TestOpen", false, false, 0, 1, $$27, true, true, false)
+                                            -- BTREE_SEARCH  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                assign [$$27] <- [3]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$32)
                                     -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        project ([$$32])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- BTREE_SEARCH (test.TestOpen.idx_4)  |PARTITIONED|
+                                            unnest-map [$$31, $$32] <- index-search("idx_4", 0, "Default", "test", "TestOpen", false, false, 1, $$30, 0, true, true, false)
+                                            -- BTREE_SEARCH  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                assign [$$30] <- [2]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$36] <- [agg-range-map($$34, $$35)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$34, $$35] <- [agg-local-sampling($$25), agg-null-writer($$25)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (and(gt($$t.getField("c_i8"), 2), lt($$t.getField("c_i64"), 3))) project: [$$25]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$25] <- [$$t.getField("c_x")]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                                    unnest-map [$$22, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$33, 1, $$33, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        intersect [$$33] <- [[$$29], [$$32]]
                                         -- INTERSECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$29)
                                             -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$29])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (test.TestOpen.idx_3)  |PARTITIONED|
+                                                    unnest-map [$$28, $$29] <- index-search("idx_3", 0, "Default", "test", "TestOpen", false, false, 0, 1, $$27, true, true, false)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        assign [$$27] <- [3]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$32)
                                             -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$32])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH (test.TestOpen.idx_4)  |PARTITIONED|
+                                                    unnest-map [$$31, $$32] <- index-search("idx_4", 0, "Default", "test", "TestOpen", false, false, 1, $$30, 0, true, true, false)
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        assign [$$30] <- [2]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-10_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-10_ps.plan
index 0b6b1c4..35cdec6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-10_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-10_ps.plan
@@ -1,45 +1,90 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21)
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$28
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (ge($$t.getField("c_d"), 3.25)) project: [$$21]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$21] <- [$$t.getField("c_x")]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                            unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$25, 1, $$25, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$25)
                                 -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$25])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TestOpen.idx_d)  |PARTITIONED|
+                                        unnest-map [$$24, $$25] <- index-search("idx_d", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 0, true, true, false)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$23] <- [3.25]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$28] <- [agg-range-map($$26, $$27)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$26, $$27] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (ge($$t.getField("c_d"), 3.25)) project: [$$21]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$21] <- [$$t.getField("c_x")]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                                    unnest-map [$$19, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$25, 1, $$25, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$25)
                                         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$25])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TestOpen.idx_d)  |PARTITIONED|
+                                                unnest-map [$$24, $$25] <- index-search("idx_d", 0, "Default", "test", "TestOpen", false, false, 1, $$23, 0, true, true, false)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$23] <- [3.25]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-11.plan
index 29b0374..6ee1cce 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-11.plan
@@ -1,20 +1,40 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$20] <- [{"res": $$24}] project: [$$20]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+        order (ASC, $$24)
         -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$22, 499), lt($$22, 99999))) project: [$$24]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$24, $$22] <- [$$t.getField("c_x"), $$t.getField("c_i8")] project: [$$24, $$22]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                    unnest-map [$$23, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$29, 1, $$29, true, true, true)
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$29)
                         -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$29])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.TestOpen.idx_i8)  |PARTITIONED|
+                                unnest-map [$$28, $$29] <- index-search("idx_i8", 0, "Default", "test", "TestOpen", false, false, 1, $$26, 1, $$27, true, true, false)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$26, $$27] <- [127, 127]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-11_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-11_ps.plan
index bc5e8ab..e00afa3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-11_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-11_ps.plan
@@ -1,45 +1,90 @@
+distribute result [$$20]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$20] <- [{"res": $$24}] project: [$$20]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$24)
         -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$24(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$32
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (and(gt($$22, 499), lt($$22, 99999))) project: [$$24]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$24, $$22] <- [$$t.getField("c_x"), $$t.getField("c_i8")] project: [$$24, $$22]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                            unnest-map [$$23, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$29, 1, $$29, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$29)
                                 -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$29])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- BTREE_SEARCH (test.TestOpen.idx_i8)  |PARTITIONED|
+                                        unnest-map [$$28, $$29] <- index-search("idx_i8", 0, "Default", "test", "TestOpen", false, false, 1, $$26, 1, $$27, true, true, false)
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$26, $$27] <- [127, 127]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$32] <- [agg-range-map($$30, $$31)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$30, $$31] <- [agg-local-sampling($$24), agg-null-writer($$24)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (and(gt($$22, 499), lt($$22, 99999))) project: [$$24]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$24, $$22] <- [$$t.getField("c_x"), $$t.getField("c_i8")] project: [$$24, $$22]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+                                    unnest-map [$$23, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$29, 1, $$29, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$29)
                                         -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$29])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TestOpen.idx_i8)  |PARTITIONED|
+                                                unnest-map [$$28, $$29] <- index-search("idx_i8", 0, "Default", "test", "TestOpen", false, false, 1, $$26, 1, $$27, true, true, false)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$26, $$27] <- [127, 127]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orderby-desc-using-gby_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orderby-desc-using-gby_ps.plan
index cc0b3e9..cf5cc21 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orderby-desc-using-gby_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orderby-desc-using-gby_ps.plan
@@ -1,41 +1,76 @@
+distribute result [$$50]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$50] <- [{"name": $$name, "age": $$age}] project: [$$50]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (DESC, $$name) (ASC, $$age)
         -- STABLE_SORT [$$name(DESC), $$age(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$name(DESC), $$age(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$57
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$51, $$52]  |PARTITIONED|
-                            {
+                    group by ([$$name := $$51; $$age := $$52]) decor ([]) {
+                              aggregate [] <- []
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$51, $$52]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$51, $$52]  |PARTITIONED|
+                        assign [$$52, $$51] <- [$$c.getField(2), $$c.getField(1)] project: [$$51, $$52]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$c])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (`gby-using-orderby-desc`.Customers)  |PARTITIONED|
+                              data-scan []<-[$$53, $$c] <- `gby-using-orderby-desc`.Customers
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$57] <- [agg-range-map($$54, $$55, $$56)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$54, $$55, $$56] <- [agg-local-sampling($$name, $$age), agg-null-writer($$name), agg-null-writer($$age)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- SORT_GROUP_BY[$$51, $$52]  |PARTITIONED|
-                                    {
+                            group by ([$$name := $$51; $$age := $$52]) decor ([]) {
+                                      aggregate [] <- []
                                       -- AGGREGATE  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- SORT_GROUP_BY[$$51, $$52]  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$51, $$52]  |PARTITIONED|
+                                assign [$$52, $$51] <- [$$c.getField(2), $$c.getField(1)] project: [$$51, $$52]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$c])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (`gby-using-orderby-desc`.Customers)  |PARTITIONED|
+                                      data-scan []<-[$$53, $$c] <- `gby-using-orderby-desc`.Customers
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orderby-nulls-first-last.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orderby-nulls-first-last.plan
index fe5e86f..b610831 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orderby-nulls-first-last.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orderby-nulls-first-last.plan
@@ -1,13 +1,26 @@
+distribute result [$$d]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$d])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$14(ASC), $$17(ASC), $$15(DESC), $$18(DESC) ]  |PARTITIONED|
+        order (ASC, $$14) (ASC, $$17) (DESC, $$15) (DESC, $$18)
         -- STABLE_SORT [$$14(ASC), $$17(ASC), $$15(DESC), $$18(DESC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            assign [$$15, $$14] <- [is-unknown($$18), is-unknown($$17)]
             -- ASSIGN  |PARTITIONED|
+              assign [$$18, $$17] <- [$$d.getField("b"), $$d.getField("a")]
               -- ASSIGN  |PARTITIONED|
+                project ([$$d])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.data)  |PARTITIONED|
+                    data-scan []<-[$$16, $$d] <- test.data
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+                        empty-tuple-source
+                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive-open_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive-open_01.plan
index c7db207..1edcdb6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive-open_01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive-open_01.plan
@@ -1,32 +1,38 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$21]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$21] <- [{"o_orderkey": $$24, "o_custkey": $$23}] project: [$$21]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+        order (ASC, $$24)
         -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$o.getField(3), 150000.0), eq($$23, 40))) project: [$$24, $$23]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$23] <- [$$o.getField(1)]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (tpch.Orders.Orders)  |PARTITIONED|
+                  unnest-map [$$24, $$o] <- index-search("Orders", 0, "Default", "tpch", "Orders", false, false, 1, $$31, 1, $$31, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$31)
                       -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$31])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (tpch.Orders.idx_Orders_Custkey)  |PARTITIONED|
+                              unnest-map [$$30, $$31] <- index-search("idx_Orders_Custkey", 0, "Default", "tpch", "Orders", false, false, 1, $$28, 1, $$29, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$28, $$29] <- [40, 40]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive-open_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive-open_01_ps.plan
index a568a2a..e983d27 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive-open_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive-open_01_ps.plan
@@ -1,57 +1,88 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$21]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$21] <- [{"o_orderkey": $$24, "o_custkey": $$23}] project: [$$21]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$24)
         -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$24(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$34
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (and(gt($$o.getField(3), 150000.0), eq($$23, 40))) project: [$$24, $$23]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$23] <- [$$o.getField(1)]
                       -- ASSIGN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (tpch.Orders.Orders)  |PARTITIONED|
+                          unnest-map [$$24, $$o] <- index-search("Orders", 0, "Default", "tpch", "Orders", false, false, 1, $$31, 1, $$31, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$31)
                               -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$31])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (tpch.Orders.idx_Orders_Custkey)  |PARTITIONED|
+                                      unnest-map [$$30, $$31] <- index-search("idx_Orders_Custkey", 0, "Default", "tpch", "Orders", false, false, 1, $$28, 1, $$29, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$28, $$29] <- [40, 40]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$34] <- [agg-range-map($$32, $$33)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$32, $$33] <- [agg-local-sampling($$24), agg-null-writer($$24)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$24])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (and(gt($$o.getField(3), 150000.0), eq($$23, 40))) project: [$$24, $$23]
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$23] <- [$$o.getField(1)]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (tpch.Orders.Orders)  |PARTITIONED|
+                                    unnest-map [$$24, $$o] <- index-search("Orders", 0, "Default", "tpch", "Orders", false, false, 1, $$31, 1, $$31, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$31)
                                         -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$31])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (tpch.Orders.idx_Orders_Custkey)  |PARTITIONED|
+                                                unnest-map [$$30, $$31] <- index-search("idx_Orders_Custkey", 0, "Default", "tpch", "Orders", false, false, 1, $$28, 1, $$29, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$28, $$29] <- [40, 40]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive-open_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive-open_02.plan
index 414c78b..44fa36b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive-open_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive-open_02.plan
@@ -1,32 +1,38 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$22]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$22] <- [{"o_orderkey": $$26, "o_custkey": $$24, "o_totalprice": $$25}] project: [$$22]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$26(ASC) ]  |PARTITIONED|
+        order (ASC, $$26)
         -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$25, 150000.0), eq($$24, 40)))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$24, $$25] <- [$$o.getField(1), $$o.getField(3)] project: [$$26, $$24, $$25]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (tpch.Orders.Orders)  |PARTITIONED|
+                  unnest-map [$$26, $$o] <- index-search("Orders", 0, "Default", "tpch", "Orders", false, false, 1, $$32, 1, $$32, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$32)
                       -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$32])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (tpch.Orders.idx_Orders_Custkey)  |PARTITIONED|
+                              unnest-map [$$31, $$32] <- index-search("idx_Orders_Custkey", 0, "Default", "tpch", "Orders", false, false, 1, $$29, 1, $$30, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$29, $$30] <- [40, 40]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive-open_02_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive-open_02_ps.plan
index 9dffd76..3a0701f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive-open_02_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive-open_02_ps.plan
@@ -1,57 +1,88 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$22]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$22] <- [{"o_orderkey": $$26, "o_custkey": $$24, "o_totalprice": $$25}] project: [$$22]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$26)
         -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$26(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$35
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (and(gt($$25, 150000.0), eq($$24, 40)))
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$24, $$25] <- [$$o.getField(1), $$o.getField(3)] project: [$$26, $$24, $$25]
                       -- ASSIGN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (tpch.Orders.Orders)  |PARTITIONED|
+                          unnest-map [$$26, $$o] <- index-search("Orders", 0, "Default", "tpch", "Orders", false, false, 1, $$32, 1, $$32, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$32)
                               -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$32])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (tpch.Orders.idx_Orders_Custkey)  |PARTITIONED|
+                                      unnest-map [$$31, $$32] <- index-search("idx_Orders_Custkey", 0, "Default", "tpch", "Orders", false, false, 1, $$29, 1, $$30, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$29, $$30] <- [40, 40]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$35] <- [agg-range-map($$33, $$34)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$33, $$34] <- [agg-local-sampling($$26), agg-null-writer($$26)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$26])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (and(gt($$25, 150000.0), eq($$24, 40)))
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$24, $$25] <- [$$o.getField(1), $$o.getField(3)] project: [$$26, $$24, $$25]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (tpch.Orders.Orders)  |PARTITIONED|
+                                    unnest-map [$$26, $$o] <- index-search("Orders", 0, "Default", "tpch", "Orders", false, false, 1, $$32, 1, $$32, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$32)
                                         -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$32])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (tpch.Orders.idx_Orders_Custkey)  |PARTITIONED|
+                                                unnest-map [$$31, $$32] <- index-search("idx_Orders_Custkey", 0, "Default", "tpch", "Orders", false, false, 1, $$29, 1, $$30, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$29, $$30] <- [40, 40]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive_01.plan
index c7db207..1edcdb6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive_01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive_01.plan
@@ -1,32 +1,38 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$21]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$21] <- [{"o_orderkey": $$24, "o_custkey": $$23}] project: [$$21]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+        order (ASC, $$24)
         -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$o.getField(3), 150000.0), eq($$23, 40))) project: [$$24, $$23]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$23] <- [$$o.getField(1)]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (tpch.Orders.Orders)  |PARTITIONED|
+                  unnest-map [$$24, $$o] <- index-search("Orders", 0, "Default", "tpch", "Orders", false, false, 1, $$31, 1, $$31, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$31)
                       -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$31])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (tpch.Orders.idx_Orders_Custkey)  |PARTITIONED|
+                              unnest-map [$$30, $$31] <- index-search("idx_Orders_Custkey", 0, "Default", "tpch", "Orders", false, false, 1, $$28, 1, $$29, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$28, $$29] <- [40, 40]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive_01_ps.plan
index a568a2a..e983d27 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive_01_ps.plan
@@ -1,57 +1,88 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$21]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$21] <- [{"o_orderkey": $$24, "o_custkey": $$23}] project: [$$21]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$24)
         -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$24(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$34
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (and(gt($$o.getField(3), 150000.0), eq($$23, 40))) project: [$$24, $$23]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$23] <- [$$o.getField(1)]
                       -- ASSIGN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (tpch.Orders.Orders)  |PARTITIONED|
+                          unnest-map [$$24, $$o] <- index-search("Orders", 0, "Default", "tpch", "Orders", false, false, 1, $$31, 1, $$31, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$31)
                               -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$31])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (tpch.Orders.idx_Orders_Custkey)  |PARTITIONED|
+                                      unnest-map [$$30, $$31] <- index-search("idx_Orders_Custkey", 0, "Default", "tpch", "Orders", false, false, 1, $$28, 1, $$29, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$28, $$29] <- [40, 40]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$34] <- [agg-range-map($$32, $$33)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$32, $$33] <- [agg-local-sampling($$24), agg-null-writer($$24)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$24])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (and(gt($$o.getField(3), 150000.0), eq($$23, 40))) project: [$$24, $$23]
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$23] <- [$$o.getField(1)]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (tpch.Orders.Orders)  |PARTITIONED|
+                                    unnest-map [$$24, $$o] <- index-search("Orders", 0, "Default", "tpch", "Orders", false, false, 1, $$31, 1, $$31, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$31)
                                         -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$31])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (tpch.Orders.idx_Orders_Custkey)  |PARTITIONED|
+                                                unnest-map [$$30, $$31] <- index-search("idx_Orders_Custkey", 0, "Default", "tpch", "Orders", false, false, 1, $$28, 1, $$29, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$28, $$29] <- [40, 40]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive_02.plan
index 414c78b..44fa36b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive_02.plan
@@ -1,32 +1,38 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$22]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$22] <- [{"o_orderkey": $$26, "o_custkey": $$24, "o_totalprice": $$25}] project: [$$22]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$26(ASC) ]  |PARTITIONED|
+        order (ASC, $$26)
         -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$25, 150000.0), eq($$24, 40)))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$24, $$25] <- [$$o.getField(1), $$o.getField(3)] project: [$$26, $$24, $$25]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (tpch.Orders.Orders)  |PARTITIONED|
+                  unnest-map [$$26, $$o] <- index-search("Orders", 0, "Default", "tpch", "Orders", false, false, 1, $$32, 1, $$32, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$32)
                       -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$32])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (tpch.Orders.idx_Orders_Custkey)  |PARTITIONED|
+                              unnest-map [$$31, $$32] <- index-search("idx_Orders_Custkey", 0, "Default", "tpch", "Orders", false, false, 1, $$29, 1, $$30, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$29, $$30] <- [40, 40]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive_02_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive_02_ps.plan
index 9dffd76..3a0701f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive_02_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/orders-index-search-conjunctive_02_ps.plan
@@ -1,57 +1,88 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$22]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$22] <- [{"o_orderkey": $$26, "o_custkey": $$24, "o_totalprice": $$25}] project: [$$22]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$26)
         -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$26(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$35
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (and(gt($$25, 150000.0), eq($$24, 40)))
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$24, $$25] <- [$$o.getField(1), $$o.getField(3)] project: [$$26, $$24, $$25]
                       -- ASSIGN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (tpch.Orders.Orders)  |PARTITIONED|
+                          unnest-map [$$26, $$o] <- index-search("Orders", 0, "Default", "tpch", "Orders", false, false, 1, $$32, 1, $$32, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$32)
                               -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$32])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (tpch.Orders.idx_Orders_Custkey)  |PARTITIONED|
+                                      unnest-map [$$31, $$32] <- index-search("idx_Orders_Custkey", 0, "Default", "tpch", "Orders", false, false, 1, $$29, 1, $$30, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$29, $$30] <- [40, 40]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$35] <- [agg-range-map($$33, $$34)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$33, $$34] <- [agg-local-sampling($$26), agg-null-writer($$26)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$26])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (and(gt($$25, 150000.0), eq($$24, 40)))
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$24, $$25] <- [$$o.getField(1), $$o.getField(3)] project: [$$26, $$24, $$25]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (tpch.Orders.Orders)  |PARTITIONED|
+                                    unnest-map [$$26, $$o] <- index-search("Orders", 0, "Default", "tpch", "Orders", false, false, 1, $$32, 1, $$32, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$32)
                                         -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$32])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (tpch.Orders.idx_Orders_Custkey)  |PARTITIONED|
+                                                unnest-map [$$31, $$32] <- index-search("idx_Orders_Custkey", 0, "Default", "tpch", "Orders", false, false, 1, $$29, 1, $$30, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$29, $$30] <- [40, 40]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/p_sort_join/p_sort_join.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/p_sort_join/p_sort_join.plan
index 8261d45..cce5afb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/p_sort_join/p_sort_join.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/p_sort_join/p_sort_join.plan
@@ -1,71 +1,136 @@
+distribute result [$$87]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$87] <- [{"id2": $$id2}] project: [$$87]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$id2)
         -- STABLE_SORT [$$id2(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$id2(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$101
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$93]  |PARTITIONED|
-                            {
+                    group by ([$$id2 := $$93]) decor ([]) {
+                              aggregate [] <- []
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$93]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$93])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (eq($$93, $$96))
                             -- HYBRID_HASH_JOIN [$$93][$$96]  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$93]  |PARTITIONED|
+                                order (ASC, $$93)
                                 -- STABLE_SORT [$$93(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- RANGE_PARTITION_EXCHANGE [$$93(ASC)] RANGE_MAP:{SPLIT:1}  |PARTITIONED|
+                                    assign [$$93] <- [$$TestDS1.getField(1)] project: [$$93]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$TestDS1])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.TestDS1)  |PARTITIONED|
+                                          data-scan []<-[$$90, $$TestDS1] <- test.TestDS1
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$96]  |PARTITIONED|
+                                order (ASC, $$96)
                                 -- STABLE_SORT [$$96(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- RANGE_PARTITION_EXCHANGE [$$96(ASC)] RANGE_MAP:{SPLIT:1}  |PARTITIONED|
+                                    assign [$$96] <- [$$TestDS2.getField(1)] project: [$$96]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$TestDS2])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.TestDS2)  |PARTITIONED|
+                                          data-scan []<-[$$91, $$TestDS2] <- test.TestDS2
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$101] <- [agg-range-map($$99, $$100)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$99, $$100] <- [agg-local-sampling($$id2), agg-null-writer($$id2)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- SORT_GROUP_BY[$$93]  |PARTITIONED|
-                                    {
+                            group by ([$$id2 := $$93]) decor ([]) {
+                                      aggregate [] <- []
                                       -- AGGREGATE  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- SORT_GROUP_BY[$$93]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$93])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (eq($$93, $$96))
                                     -- HYBRID_HASH_JOIN [$$93][$$96]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$93]  |PARTITIONED|
+                                        order (ASC, $$93)
                                         -- STABLE_SORT [$$93(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- RANGE_PARTITION_EXCHANGE [$$93(ASC)] RANGE_MAP:{SPLIT:1}  |PARTITIONED|
+                                            assign [$$93] <- [$$TestDS1.getField(1)] project: [$$93]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$TestDS1])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.TestDS1)  |PARTITIONED|
+                                                  data-scan []<-[$$90, $$TestDS1] <- test.TestDS1
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$96]  |PARTITIONED|
+                                        order (ASC, $$96)
                                         -- STABLE_SORT [$$96(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- RANGE_PARTITION_EXCHANGE [$$96(ASC)] RANGE_MAP:{SPLIT:1}  |PARTITIONED|
+                                            assign [$$96] <- [$$TestDS2.getField(1)] project: [$$96]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$TestDS2])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.TestDS2)  |PARTITIONED|
+                                                  data-scan []<-[$$91, $$TestDS2] <- test.TestDS2
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/p_sort_seq_merge/p_sort_seq_merge.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/p_sort_seq_merge/p_sort_seq_merge.plan
index a272cca..40c8e0c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/p_sort_seq_merge/p_sort_seq_merge.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/p_sort_seq_merge/p_sort_seq_merge.plan
@@ -1,32 +1,64 @@
+distribute result [$$12]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$12] <- [ordered-list-constructor($$19)] project: [$$12]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$19] <- [listify($$16)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- SEQUENTIAL_MERGE_EXCHANGE  |PARTITIONED|
+          assign [$$16] <- [{"v": $$v}] project: [$$16]
           -- ASSIGN  |PARTITIONED|
+            project ([$$v])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$21) (ASC, $$20)
                 -- STABLE_SORT [$$21(ASC), $$20(ASC)]  |PARTITIONED|
+                  exchange
                   -- RANGE_PARTITION_EXCHANGE [$$21(ASC), $$20(ASC)]  |PARTITIONED|
+                    forward: shared-variable = $$26
                     -- FORWARD  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$21] <- [$$v.getField(1)]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.TestDS)  |PARTITIONED|
+                                data-scan []<-[$$20, $$v] <- test.TestDS
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        aggregate [$$26] <- [agg-range-map($$23, $$24, $$25)]
                         -- AGGREGATE  |UNPARTITIONED|
+                          exchange
                           -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                            aggregate [$$23, $$24, $$25] <- [agg-local-sampling($$21, $$20), agg-null-writer($$21), agg-null-writer($$20)]
                             -- AGGREGATE  |PARTITIONED|
+                              project ([$$21, $$20])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  replicate
                                   -- REPLICATE  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$21] <- [$$v.getField(1)]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.TestDS)  |PARTITIONED|
+                                          data-scan []<-[$$20, $$v] <- test.TestDS
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/parallel_sort_enabled_disabled/parallel_sort_enabled_disabled.1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/parallel_sort_enabled_disabled/parallel_sort_enabled_disabled.1.plan
index a6bb323..1de42e6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/parallel_sort_enabled_disabled/parallel_sort_enabled_disabled.1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/parallel_sort_enabled_disabled/parallel_sort_enabled_disabled.1.plan
@@ -1,30 +1,60 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$14)
         -- STABLE_SORT [$$14(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$14(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$17
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    assign [$$14] <- [$$c.getField(1)]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$c])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                          data-scan []<-[$$13, $$c] <- test.Customers
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$17] <- [agg-range-map($$15, $$16)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$15, $$16] <- [agg-local-sampling($$14), agg-null-writer($$14)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$14])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$14] <- [$$c.getField(1)]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$c])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                    data-scan []<-[$$13, $$c] <- test.Customers
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/parallel_sort_enabled_disabled/parallel_sort_enabled_disabled.2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/parallel_sort_enabled_disabled/parallel_sort_enabled_disabled.2.plan
index 3dfb1a0..87e3e0d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/parallel_sort_enabled_disabled/parallel_sort_enabled_disabled.2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/parallel_sort_enabled_disabled/parallel_sort_enabled_disabled.2.plan
@@ -1,12 +1,24 @@
+distribute result [$$c]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$14(ASC) ]  |PARTITIONED|
+        order (ASC, $$14)
         -- STABLE_SORT [$$14(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            assign [$$14] <- [$$c.getField(1)]
             -- ASSIGN  |PARTITIONED|
+              project ([$$c])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                  data-scan []<-[$$13, $$c] <- test.Customers
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/delete-primary-key-index-with-secondary.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/delete-primary-key-index-with-secondary.plan
index b357af8..d4edc74 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/delete-primary-key-index-with-secondary.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/delete-primary-key-index-with-secondary.plan
@@ -1,20 +1,40 @@
+commit
 -- COMMIT  |PARTITIONED|
+  project ([$$16])
   -- STREAM_PROJECT  |PARTITIONED|
+    exchange
     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+      delete from titleIndex on test.DBLP from [$$22]
       -- INDEX_INSERT_DELETE  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          delete from pkIndex on test.DBLP from []
           -- INDEX_INSERT_DELETE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$22, $$16])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  delete from test.DBLP from record: $$DBLP partitioned by [$$16]
                   -- INSERT_DELETE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      materialize
                       -- MATERIALIZE  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$16]  |PARTITIONED|
+                          assign [$$22, $$16] <- [$$DBLP.getField(2), $$DBLP.getField(0)]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$DBLP])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                                unnest-map [$$17, $$DBLP] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$19, 0, false, true, false)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$19] <- [10]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-and-scan-primary-key-index-with-secondary.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-and-scan-primary-key-index-with-secondary.plan
index 512f7a8..5db8522 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-and-scan-primary-key-index-with-secondary.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-and-scan-primary-key-index-with-secondary.plan
@@ -1,18 +1,36 @@
+commit
 -- COMMIT  |PARTITIONED|
+  project ([$$17])
   -- STREAM_PROJECT  |PARTITIONED|
+    exchange
     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+      insert into nameIndex on test.myData from [$$21]
       -- INDEX_INSERT_DELETE  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          project ([$$21, $$17])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              insert into test.myData from record: $$18 partitioned by [$$17]
               -- INSERT_DELETE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  materialize
                   -- MATERIALIZE  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$17]  |PARTITIONED|
+                      assign [$$21, $$17] <- [$$18.getField(1), $$18.getField(0)]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$18] <- [cast({"id": numeric-add($$19, 1)})] project: [$$18]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$19])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.myData)  |PARTITIONED|
+                              data-scan []<-[$$19, $$x] <- test.myData
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-primary-key-index-with-auto-gen-pk.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-primary-key-index-with-auto-gen-pk.plan
index 32d087c..8cc7f64 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-primary-key-index-with-auto-gen-pk.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-primary-key-index-with-auto-gen-pk.plan
@@ -1,9 +1,18 @@
+commit
 -- COMMIT  |PARTITIONED|
+  project ([$$3])
   -- STREAM_PROJECT  |PARTITIONED|
+    exchange
     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+      insert into test.DBLP from record: $$5 partitioned by [$$3]
       -- INSERT_DELETE  |PARTITIONED|
+        exchange
         -- HASH_PARTITION_EXCHANGE [$$3]  |PARTITIONED|
+          assign [$$3] <- [$$5.getField(0)]
           -- ASSIGN  |UNPARTITIONED|
+            assign [$$5] <- [cast(check-unknown(put-autogenerated-key({ "dblpid": "books/acm/kim95/Blakeley95", "title": "OQL[C++]  Extending C++ with an Object Query Capability.", "authors": "José A. Blakeley", "misc": "2002-01-03 69-88 Modern Database Systems db/books/collections/kim95.html#Blakeley95 1995" }, "id")))]
             -- ASSIGN  |UNPARTITIONED|
+              assign [$$1] <- [{ "dblpid": "books/acm/kim95/Blakeley95", "title": "OQL[C++]  Extending C++ with an Object Query Capability.", "authors": "José A. Blakeley", "misc": "2002-01-03 69-88 Modern Database Systems db/books/collections/kim95.html#Blakeley95 1995" }] project: []
               -- ASSIGN  |UNPARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-primary-key-index.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-primary-key-index.plan
index 2c493d3..bafd5ed 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-primary-key-index.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/insert-primary-key-index.plan
@@ -1,8 +1,16 @@
+commit
 -- COMMIT  |PARTITIONED|
+  project ([$$3])
   -- STREAM_PROJECT  |PARTITIONED|
+    exchange
     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+      insert into test.DBLP from record: $$1 partitioned by [$$3]
       -- INSERT_DELETE  |PARTITIONED|
+        exchange
         -- HASH_PARTITION_EXCHANGE [$$3]  |PARTITIONED|
+          assign [$$3] <- [1]
           -- ASSIGN  |UNPARTITIONED|
+            assign [$$1] <- [{ "id": 1, "dblpid": "books/acm/kim95/Blakeley95", "title": "OQL[C++]  Extending C++ with an Object Query Capability.", "authors": "José A. Blakeley", "misc": "2002-01-03 69-88 Modern Database Systems db/books/collections/kim95.html#Blakeley95 1995" }]
             -- ASSIGN  |UNPARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/load-primary-key-index-with-secondary.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/load-primary-key-index-with-secondary.plan
index bde8db0..edddc4b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/load-primary-key-index-with-secondary.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/load-primary-key-index-with-secondary.plan
@@ -1,66 +1,132 @@
+sink
 -- SINK  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        insert into kwds_index on test.MyData from [$$3] [bulkload]
         -- INDEX_BULKLOAD  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$3) (ASC, $$2)
             -- STABLE_SORT [$$3(ASC), $$2(ASC)]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$3, $$2])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    replicate
                     -- REPLICATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$3, $$4, $$2])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            insert into test.MyData from record: $$1 partitioned by [$$2] [bulkload]
                             -- BULKLOAD  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$2)
                                 -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
+                                    assign [$$3, $$4, $$2] <- [$$1.getField(2), $$1.getField(1), $$1.getField(0)]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
+                                        data-scan []<-[$$1] <- loadable_dv.loadable_ds
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        insert into pkIndex on test.MyData from [] [bulkload]
         -- INDEX_BULKLOAD  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$2])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$3, $$4, $$2])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        insert into test.MyData from record: $$1 partitioned by [$$2] [bulkload]
                         -- BULKLOAD  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$2)
                             -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
+                                assign [$$3, $$4, $$2] <- [$$1.getField(2), $$1.getField(1), $$1.getField(0)]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
+                                    data-scan []<-[$$1] <- loadable_dv.loadable_ds
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        insert into rtree_index_point on test.MyData from [$$5, $$6, $$5, $$6] [bulkload]
         -- INDEX_BULKLOAD  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$5) (ASC, $$6) (ASC, $$2)
             -- STABLE_SORT [$$5(ASC), $$6(ASC), $$2(ASC)]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$5, $$6] <- [create-mbr($$4, 2, 0), create-mbr($$4, 2, 1)] project: [$$2, $$5, $$6]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$4, $$2])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      replicate
                       -- REPLICATE  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$3, $$4, $$2])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              insert into test.MyData from record: $$1 partitioned by [$$2] [bulkload]
                               -- BULKLOAD  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$2)
                                   -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
+                                      assign [$$3, $$4, $$2] <- [$$1.getField(2), $$1.getField(1), $$1.getField(0)]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
+                                          data-scan []<-[$$1] <- loadable_dv.loadable_ds
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/load-primary-key-index.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/load-primary-key-index.plan
index 3f0b903..9db29bf 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/load-primary-key-index.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/load-primary-key-index.plan
@@ -1,17 +1,34 @@
+sink
 -- SINK  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        insert into pkIndex on test.MyData from [] [bulkload]
         -- INDEX_BULKLOAD  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$2])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                insert into test.MyData from record: $$1 partitioned by [$$2] [bulkload]
                 -- BULKLOAD  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$2)
                     -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
+                        assign [$$2] <- [$$1.getField(0)]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
+                            data-scan []<-[$$1] <- loadable_dv.loadable_ds
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/upsert-primary-key-index-with-secondary.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/upsert-primary-key-index-with-secondary.plan
index beabd3d..f8deefa 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/upsert-primary-key-index-with-secondary.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/primary-key-index/upsert-primary-key-index-with-secondary.plan
@@ -1,15 +1,30 @@
+commit
 -- COMMIT  |PARTITIONED|
+  project ([$$3])
   -- STREAM_PROJECT  |PARTITIONED|
+    exchange
     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+      upsert into titleIndex on test.DBLP from  replace:[$$7] with:[$$6]
       -- INDEX_INSERT_DELETE  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          upsert into pkIndex on test.DBLP from  replace:[] with:[]
           -- INDEX_INSERT_DELETE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              assign [$$7] <- [$$5.getField(2)] project: [$$4, $$6, $$3, $$7]
               -- ASSIGN  |PARTITIONED|
+                project ([$$4, $$5, $$6, $$3])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    upsert into test.DBLP from record: $$1 partitioned by [$$3] out: ([record-before-upsert:$$5]) 
                     -- INSERT_DELETE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$3]  |PARTITIONED|
+                        assign [$$6, $$3] <- [$$1.getField(2), 1]
                         -- ASSIGN  |UNPARTITIONED|
+                          assign [$$1] <- [{ "id": 1, "dblpid": "books/acm/kim95/Blakeley95", "title": "OQL[C++]  Extending C++ with an Object Query Capability.", "authors": "José A. Blakeley", "misc": "2002-01-03 69-88 Modern Database Systems db/books/collections/kim95.html#Blakeley95 1995" }]
                           -- ASSIGN  |UNPARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/pull_select_above_eq_join.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/pull_select_above_eq_join.plan
index 9c1996b..d603204 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/pull_select_above_eq_join.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/pull_select_above_eq_join.plan
@@ -1,19 +1,38 @@
+distribute result [$$35]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"uid": $$36, "vid": $$37}] project: [$$35]
     -- ASSIGN  |PARTITIONED|
+      select (neq($$38, $$39)) project: [$$36, $$37]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$36, $$38, $$37, $$39])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$40, $$41))
             -- HYBRID_HASH_JOIN [$$40][$$41]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$40]  |PARTITIONED|
+                assign [$$40, $$38] <- [$$user.getField(1), $$user.getField(2)] project: [$$36, $$38, $$40]
                 -- ASSIGN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (`pull-select-above-eq-join`.Users)  |PARTITIONED|
+                    data-scan []<-[$$36, $$user] <- `pull-select-above-eq-join`.Users
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$41]  |PARTITIONED|
+                assign [$$41, $$39] <- [$$visitor.getField(1), $$visitor.getField(2)] project: [$$37, $$39, $$41]
                 -- ASSIGN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (`pull-select-above-eq-join`.Visitors)  |PARTITIONED|
+                    data-scan []<-[$$37, $$visitor] <- `pull-select-above-eq-join`.Visitors
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/push-project-through-group.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/push-project-through-group.plan
index d8108fb..c9b45e9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/push-project-through-group.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/push-project-through-group.plan
@@ -1,29 +1,55 @@
+distribute result [$$44]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"id": $$51, "matches": $$41}] project: [$$44]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$45]  |PARTITIONED|
-                {
+        group by ([$$51 := $$45]) decor ([]) {
+                  aggregate [$$41] <- [listify($$40)]
                   -- AGGREGATE  |LOCAL|
+                    select (not(is-missing($$50)))
                     -- STREAM_SELECT  |LOCAL|
+                      nested tuple source
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$45]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$45)
             -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$45]  |PARTITIONED|
+                project ([$$40, $$50, $$45])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    left outer join (eq($$47, $$48))
                     -- HYBRID_HASH_JOIN [$$48][$$47]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+                        assign [$$48] <- [$$paperDBLP.getField(3)] project: [$$45, $$48]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (fuzzyjoin_080.DBLP)  |PARTITIONED|
+                            data-scan []<-[$$45, $$paperDBLP] <- fuzzyjoin_080.DBLP
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
+                        assign [$$50, $$40, $$47] <- [true, $$paper.getField(2), $$paper.getField(3)] project: [$$40, $$50, $$47]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$paper])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (fuzzyjoin_080.DBLP)  |PARTITIONED|
+                              data-scan []<-[$$46, $$paper] <- fuzzyjoin_080.DBLP
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/q01_pricing_summary_report_nt_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/q01_pricing_summary_report_nt_ps.plan
index b1c772d..ac3f19c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/q01_pricing_summary_report_nt_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/q01_pricing_summary_report_nt_ps.plan
@@ -1,71 +1,104 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC), $$3(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2, $$3]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$191]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$191] <- [{"l_returnflag": $$l_returnflag, "l_linestatus": $$l_linestatus, "sum_qty": $$197, "sum_base_price": $$198, "sum_disc_price": $$199, "sum_charge": $$200, "ave_qty": $$201, "ave_price": $$202, "ave_disc": $$203, "count_order": $$204}] project: [$$191]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$l_returnflag) (ASC, $$l_linestatus)
         -- STABLE_SORT [$$l_returnflag(ASC), $$l_linestatus(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$l_returnflag(ASC), $$l_linestatus(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$222
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- EXTERNAL_GROUP_BY[$$217, $$218]  |PARTITIONED|
-                            {
+                    group by ([$$l_returnflag := $$217; $$l_linestatus := $$218]) decor ([]) {
+                              aggregate [$$197, $$198, $$199, $$200, $$201, $$202, $$203, $$204] <- [global-sum-serial($$209), global-sum-serial($$210), global-sum-serial($$211), global-sum-serial($$212), global-avg-serial($$213), global-avg-serial($$214), global-avg-serial($$215), sum-serial($$216)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- EXTERNAL_GROUP_BY[$$217, $$218]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$217, $$218]  |PARTITIONED|
-                        -- EXTERNAL_GROUP_BY[$$192, $$193]  |PARTITIONED|
-                                {
+                        group by ([$$217 := $$192; $$218 := $$193]) decor ([]) {
+                                  aggregate [$$209, $$210, $$211, $$212, $$213, $$214, $$215, $$216] <- [local-sum-serial($$147), local-sum-serial($$152), local-sum-serial(numeric-multiply($$152, numeric-subtract(1, $$206))), local-sum-serial(numeric-multiply(numeric-multiply($$152, numeric-subtract(1, $$206)), numeric-add(1, $$208))), local-avg-serial($$147), local-avg-serial($$152), local-avg-serial($$206), count-serial($$139)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- EXTERNAL_GROUP_BY[$$192, $$193]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$139] <- [{"l": $$l}] project: [$$147, $$152, $$206, $$208, $$139, $$192, $$193]
                             -- ASSIGN  |PARTITIONED|
+                              select (le($$l.getField(10), "1998-09-02"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$193, $$192, $$147, $$206, $$208, $$152] <- [$$l.getField(9), $$l.getField(8), $$l.getField(4), $$l.getField(6), $$l.getField(7), $$l.getField(5)]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$l])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                      data-scan []<-[$$195, $$196, $$l] <- tpch.LineItem
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$222] <- [agg-range-map($$219, $$220, $$221)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$219, $$220, $$221] <- [agg-local-sampling($$l_returnflag, $$l_linestatus), agg-null-writer($$l_returnflag), agg-null-writer($$l_linestatus)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$l_returnflag, $$l_linestatus])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- EXTERNAL_GROUP_BY[$$217, $$218]  |PARTITIONED|
-                                      {
+                              group by ([$$l_returnflag := $$217; $$l_linestatus := $$218]) decor ([]) {
+                                        aggregate [$$197, $$198, $$199, $$200, $$201, $$202, $$203, $$204] <- [global-sum-serial($$209), global-sum-serial($$210), global-sum-serial($$211), global-sum-serial($$212), global-avg-serial($$213), global-avg-serial($$214), global-avg-serial($$215), sum-serial($$216)]
                                         -- AGGREGATE  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- EXTERNAL_GROUP_BY[$$217, $$218]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$217, $$218]  |PARTITIONED|
-                                  -- EXTERNAL_GROUP_BY[$$192, $$193]  |PARTITIONED|
-                                          {
+                                  group by ([$$217 := $$192; $$218 := $$193]) decor ([]) {
+                                            aggregate [$$209, $$210, $$211, $$212, $$213, $$214, $$215, $$216] <- [local-sum-serial($$147), local-sum-serial($$152), local-sum-serial(numeric-multiply($$152, numeric-subtract(1, $$206))), local-sum-serial(numeric-multiply(numeric-multiply($$152, numeric-subtract(1, $$206)), numeric-add(1, $$208))), local-avg-serial($$147), local-avg-serial($$152), local-avg-serial($$206), count-serial($$139)]
                                             -- AGGREGATE  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                          }
+                                         }
+                                  -- EXTERNAL_GROUP_BY[$$192, $$193]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$139] <- [{"l": $$l}] project: [$$147, $$152, $$206, $$208, $$139, $$192, $$193]
                                       -- ASSIGN  |PARTITIONED|
+                                        select (le($$l.getField(10), "1998-09-02"))
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$193, $$192, $$147, $$206, $$208, $$152] <- [$$l.getField(9), $$l.getField(8), $$l.getField(4), $$l.getField(6), $$l.getField(7), $$l.getField(5)]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$l])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                                data-scan []<-[$$195, $$196, $$l] <- tpch.LineItem
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/q08_group_by.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/q08_group_by.plan
index 42e72a1..0f013e2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/q08_group_by.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/q08_group_by.plan
@@ -1,70 +1,140 @@
+distribute result [$$203]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$203] <- [{"o_orderdate": $$228, "l_discount": $$231, "l_extendedprice": $$232, "l_suppkey": $$233, "s_nationkey": $$242}] project: [$$203]
     -- ASSIGN  |PARTITIONED|
+      project ([$$242, $$228, $$231, $$232, $$233])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$205, $$233))
           -- HYBRID_HASH_JOIN [$$205][$$233]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$205]  |PARTITIONED|
+              assign [$$242] <- [$$s.getField(3)] project: [$$242, $$205]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (q08_group_by.Supplier)  |PARTITIONED|
+                  data-scan []<-[$$205, $$s] <- q08_group_by.Supplier
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$233]  |PARTITIONED|
+              project ([$$228, $$231, $$232, $$233])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$212, $$230))
                   -- HYBRID_HASH_JOIN [$$230][$$212]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$230]  |PARTITIONED|
+                      project ([$$228, $$231, $$232, $$233, $$230])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          join (eq($$206, $$208))
                           -- HYBRID_HASH_JOIN [$$206][$$208]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$206]  |PARTITIONED|
+                              assign [$$233, $$232, $$231, $$230] <- [$$l.getField(2), $$l.getField(5), $$l.getField(6), $$l.getField(1)] project: [$$231, $$232, $$233, $$230, $$206]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$206, $$l])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (q08_group_by.LineItem)  |PARTITIONED|
+                                    data-scan []<-[$$206, $$207, $$l] <- q08_group_by.LineItem
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$208]  |PARTITIONED|
+                              project ([$$228, $$208])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  join (eq($$209, $$221))
                                   -- HYBRID_HASH_JOIN [$$221][$$209]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$221]  |PARTITIONED|
+                                      select (and(ge($$228, "1995-01-01"), le($$228, "1996-12-31")))
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        assign [$$228, $$221] <- [$$o.getField(4), $$o.getField(1)] project: [$$208, $$228, $$221]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (q08_group_by.Orders)  |PARTITIONED|
+                                            data-scan []<-[$$208, $$o] <- q08_group_by.Orders
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$209]  |PARTITIONED|
+                                      project ([$$209])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          join (eq($$218, $$210))
                                           -- HYBRID_HASH_JOIN [$$218][$$210]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$218]  |PARTITIONED|
+                                              assign [$$218] <- [$$c.getField(3)] project: [$$209, $$218]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (q08_group_by.Customer)  |PARTITIONED|
+                                                  data-scan []<-[$$209, $$c] <- q08_group_by.Customer
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$210]  |PARTITIONED|
+                                              project ([$$210])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  join (eq($$216, $$211))
                                                   -- HYBRID_HASH_JOIN [$$216][$$211]  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$216]  |PARTITIONED|
+                                                      assign [$$216] <- [$$n1.getField(2)] project: [$$210, $$216]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (q08_group_by.Nation)  |PARTITIONED|
+                                                          data-scan []<-[$$210, $$n1] <- q08_group_by.Nation
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$211]  |PARTITIONED|
+                                                      select (eq($$r1.getField(1), "AMERICA")) project: [$$211]
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (q08_group_by.Region)  |PARTITIONED|
+                                                          data-scan []<-[$$211, $$r1] <- q08_group_by.Region
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$212]  |PARTITIONED|
+                      select (eq($$p.getField(4), "ECONOMY ANODIZED STEEL")) project: [$$212]
                       -- STREAM_SELECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (q08_group_by.Part)  |PARTITIONED|
+                          data-scan []<-[$$212, $$p] <- q08_group_by.Part
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/q09_group_by.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/q09_group_by.plan
index 9c30f8f..5cb6e2c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/q09_group_by.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/q09_group_by.plan
@@ -1,49 +1,98 @@
+distribute result [$$145]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$145] <- [{"l_extendedprice": $$166, "l_discount": $$167, "l_quantity": $$168, "l_orderkey": $$152, "n_name": $$165, "ps_supplycost": $$177}] project: [$$145]
     -- ASSIGN  |PARTITIONED|
+      project ([$$166, $$167, $$168, $$152, $$165, $$177])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$147, $$169))
           -- HYBRID_HASH_JOIN [$$147][$$169]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$147]  |PARTITIONED|
+              select (contains($$p.getField(1), "green")) project: [$$147]
               -- STREAM_SELECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (q09_group_by.Part)  |PARTITIONED|
+                  data-scan []<-[$$147, $$p] <- q09_group_by.Part
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$169]  |PARTITIONED|
+              project ([$$166, $$167, $$168, $$152, $$165, $$177, $$169])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (and(eq($$148, $$169), eq($$149, $$154)))
                   -- HYBRID_HASH_JOIN [$$148, $$149][$$169, $$154]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$148, $$149]  |PARTITIONED|
+                      assign [$$177] <- [$$ps.getField(3)] project: [$$177, $$148, $$149]
                       -- ASSIGN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (q09_group_by.Partsupp)  |PARTITIONED|
+                          data-scan []<-[$$148, $$149, $$ps] <- q09_group_by.Partsupp
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$169, $$154]  |PARTITIONED|
+                      project ([$$166, $$167, $$168, $$152, $$165, $$169, $$154])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          join (eq($$150, $$154))
                           -- HYBRID_HASH_JOIN [$$150][$$154]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$150]  |PARTITIONED|
+                              project ([$$165, $$150])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  join (eq($$151, $$157))
                                   -- HYBRID_HASH_JOIN [$$157][$$151]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$157]  |PARTITIONED|
+                                      assign [$$157] <- [$$s.getField(3)] project: [$$150, $$157]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (q09_group_by.Supplier)  |PARTITIONED|
+                                          data-scan []<-[$$150, $$s] <- q09_group_by.Supplier
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$151]  |PARTITIONED|
+                                      assign [$$165] <- [$$n.getField(1)] project: [$$165, $$151]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (q09_group_by.Nation)  |PARTITIONED|
+                                          data-scan []<-[$$151, $$n] <- q09_group_by.Nation
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$154]  |PARTITIONED|
+                              assign [$$169, $$168, $$167, $$166, $$154] <- [$$l.getField(1), $$l.getField(4), $$l.getField(6), $$l.getField(5), $$l.getField(2)] project: [$$166, $$167, $$168, $$152, $$169, $$154]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$152, $$l])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (q09_group_by.LineItem)  |PARTITIONED|
+                                    data-scan []<-[$$152, $$153, $$l] <- q09_group_by.LineItem
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/quantifiers/query-ASTERIXDB-2696.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/quantifiers/query-ASTERIXDB-2696.plan
index 4da9a4a..1cba9ea 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/quantifiers/query-ASTERIXDB-2696.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/quantifiers/query-ASTERIXDB-2696.plan
@@ -1,23 +1,40 @@
+distribute result [$$74]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$74] <- [{"a": $$a, "s": $$76}] project: [$$74]
     -- ASSIGN  |LOCAL|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |LOCAL|
-        -- PRE_CLUSTERED_GROUP_BY[$$75]  |LOCAL|
-                {
+        group by ([$$a := $$75]) decor ([]) {
+                  aggregate [$$76] <- [agg-global-sql-sum($$80)]
                   -- AGGREGATE  |LOCAL|
+                    aggregate [$$80] <- [agg-local-sql-sum(switch-case(true, $$71, 1, 0))]
                     -- AGGREGATE  |LOCAL|
-                      -- SUBPLAN  |LOCAL|
-                              {
+                      subplan {
+                                aggregate [$$71] <- [non-empty-stream()]
                                 -- AGGREGATE  |LOCAL|
+                                  select (ge($$x, 50))
                                   -- STREAM_SELECT  |LOCAL|
+                                    unnest $$x <- scan-collection($$78)
                                     -- UNNEST  |LOCAL|
+                                      nested tuple source
                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- SUBPLAN  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$75]  |LOCAL|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+            order (ASC, $$75)
             -- STABLE_SORT [$$75(ASC)]  |LOCAL|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                assign [$$78, $$75] <- [$$t.getField(1), $$t.getField(0)] project: [$$78, $$75]
                 -- ASSIGN  |UNPARTITIONED|
+                  unnest $$t <- scan-collection(array: [ { "a": 1, "b": array: [ 10, 20, 30 ] }, { "a": 1, "b": array: [ 40, 50, 60 ] }, { "a": 1, "b": array: [ 70, 80, 90 ] }, { "a": 2, "b": array: [ 100, 200, 300 ] }, { "a": 2, "b": array: [ 400, 500, 600 ] }, { "a": 2, "b": array: [ 700, 800, 900 ] } ])
                   -- UNNEST  |UNPARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-159-3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-159-3.plan
index cff15c6..4a643aa 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-159-3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-159-3.plan
@@ -1,50 +1,97 @@
+distribute result [$$41]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 5
     -- STREAM_LIMIT  |UNPARTITIONED|
+      assign [$$41] <- [{"id1": $$47, "id2": $$48}] project: [$$41]
       -- ASSIGN  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$47(DESC), $$48(DESC) ]  |PARTITIONED|
+          limit 5
           -- STREAM_LIMIT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (topK: 5) (DESC, $$47) (DESC, $$48)
               -- STABLE_SORT [topK: 5] [$$47(DESC), $$48(DESC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$47, $$48])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      left outer join (eq($$47, $$56))
                       -- HYBRID_HASH_JOIN [$$47][$$56]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
+                          assign [$$47] <- [$$48] project: [$$47]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate
                               -- REPLICATE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$48])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+                                      data-scan []<-[$$48, $$fu2] <- TinySocial.FacebookUsers
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$56]  |PARTITIONED|
+                          select (and(lt($$49, 5), gt($$49, 2))) project: [$$48, $$56]
                           -- STREAM_SELECT  |PARTITIONED|
-                            -- SUBPLAN  |PARTITIONED|
-                                    {
+                            subplan {
+                                      aggregate [$$49] <- [agg-count(1)]
                                       -- AGGREGATE  |LOCAL|
+                                        unnest $$45 <- range($$56, $$48)
                                         -- UNNEST  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- SUBPLAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (true)
                                 -- NESTED_LOOP  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$56] <- [$$48] project: [$$56]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$48])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+                                                data-scan []<-[$$48, $$fu2] <- TinySocial.FacebookUsers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        project ([$$48])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+                                            data-scan []<-[$$48, $$fu2] <- TinySocial.FacebookUsers
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1671.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1671.plan
index c0b4e80..018c6dd 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1671.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1671.plan
@@ -1,16 +1,32 @@
+distribute result [$$14]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 0
     -- STREAM_LIMIT  |UNPARTITIONED|
+      assign [$$14] <- [{"l": $$l}] project: [$$14]
       -- ASSIGN  |PARTITIONED|
+        project ([$$l])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- SORT_MERGE_EXCHANGE [$$20(ASC), $$21(ASC) ]  |PARTITIONED|
+            limit 0
             -- STREAM_LIMIT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (topK: 0) (ASC, $$20) (ASC, $$21)
                 -- STABLE_SORT [topK: 0] [$$20(ASC), $$21(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    assign [$$21, $$20] <- [$$l.getField("l_linestatus"), $$l.getField("l_returnflag")]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$l])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                          data-scan []<-[$$18, $$19, $$l] <- tpch.LineItem
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1806.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1806.plan
index 63b4f0f..e46d3f9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1806.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1806.plan
@@ -1,23 +1,40 @@
+distribute result [$$136]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$136] <- [{"l_returnflag": $$l_returnflag, "l_linestatus": $$l_linestatus, "sum_qty": $$142, "sum_base_price": $$143, "sum_disc_price": $$144, "sum_charge": $$145, "ave_qty": $$146, "ave_price": $$147, "ave_disc": $$148, "count_order": $$149}] project: [$$136]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$l_returnflag(ASC), $$l_linestatus(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$163, $$164]  |PARTITIONED|
-                {
+        group by ([$$l_returnflag := $$163; $$l_linestatus := $$164]) decor ([]) {
+                  aggregate [$$142, $$143, $$144, $$145, $$146, $$147, $$148, $$149] <- [agg-global-sql-sum($$155), agg-global-sql-sum($$156), agg-global-sql-sum($$157), agg-global-sql-sum($$158), agg-global-sql-avg($$159), agg-global-sql-avg($$160), agg-global-sql-avg($$161), agg-sql-sum($$162)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$163, $$164]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$163, $$164]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$137, $$138]  |PARTITIONED|
-                    {
+            group by ([$$163 := $$137; $$164 := $$138]) decor ([]) {
+                      aggregate [$$155, $$156, $$157, $$158, $$159, $$160, $$161, $$162] <- [agg-local-sql-sum($$90), agg-local-sql-sum($$95), agg-local-sql-sum(numeric-multiply($$95, numeric-subtract(1, $$152))), agg-local-sql-sum(numeric-multiply(numeric-multiply($$95, numeric-subtract(1, $$152)), numeric-add(1, $$154))), agg-local-sql-avg($$90), agg-local-sql-avg($$95), agg-local-sql-avg($$152), agg-sql-count(1)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$137, $$138]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (inject-failure(le($$l.getField(10), "1998-09-02"), eq($$140, 5988))) project: [$$90, $$95, $$152, $$154, $$137, $$138]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$138, $$137, $$90, $$152, $$154, $$95] <- [$$l.getField(9), $$l.getField(8), $$l.getField(4), $$l.getField(6), $$l.getField(7), $$l.getField(5)]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$140, $$l])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                        data-scan []<-[$$140, $$141, $$l] <- tpch.LineItem
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1806_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1806_ps.plan
index 640eed5..592af18 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1806_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1806_ps.plan
@@ -1,56 +1,100 @@
+distribute result [$$136]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$136] <- [{"l_returnflag": $$l_returnflag, "l_linestatus": $$l_linestatus, "sum_qty": $$142, "sum_base_price": $$143, "sum_disc_price": $$144, "sum_charge": $$145, "ave_qty": $$146, "ave_price": $$147, "ave_disc": $$148, "count_order": $$149}] project: [$$136]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$l_returnflag) (ASC, $$l_linestatus)
         -- STABLE_SORT [$$l_returnflag(ASC), $$l_linestatus(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$l_returnflag(ASC), $$l_linestatus(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$168
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$163, $$164]  |PARTITIONED|
-                            {
+                    group by ([$$l_returnflag := $$163; $$l_linestatus := $$164]) decor ([]) {
+                              aggregate [$$142, $$143, $$144, $$145, $$146, $$147, $$148, $$149] <- [agg-global-sql-sum($$155), agg-global-sql-sum($$156), agg-global-sql-sum($$157), agg-global-sql-sum($$158), agg-global-sql-avg($$159), agg-global-sql-avg($$160), agg-global-sql-avg($$161), agg-sql-sum($$162)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$163, $$164]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$163, $$164]  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$137, $$138]  |PARTITIONED|
-                                {
+                        group by ([$$163 := $$137; $$164 := $$138]) decor ([]) {
+                                  aggregate [$$155, $$156, $$157, $$158, $$159, $$160, $$161, $$162] <- [agg-local-sql-sum($$90), agg-local-sql-sum($$95), agg-local-sql-sum(numeric-multiply($$95, numeric-subtract(1, $$152))), agg-local-sql-sum(numeric-multiply(numeric-multiply($$95, numeric-subtract(1, $$152)), numeric-add(1, $$154))), agg-local-sql-avg($$90), agg-local-sql-avg($$95), agg-local-sql-avg($$152), agg-sql-count(1)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$137, $$138]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (inject-failure(le($$l.getField(10), "1998-09-02"), eq($$140, 5988))) project: [$$90, $$95, $$152, $$154, $$137, $$138]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$138, $$137, $$90, $$152, $$154, $$95] <- [$$l.getField(9), $$l.getField(8), $$l.getField(4), $$l.getField(6), $$l.getField(7), $$l.getField(5)]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$140, $$l])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                    data-scan []<-[$$140, $$141, $$l] <- tpch.LineItem
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$168] <- [agg-range-map($$165, $$166, $$167)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$165, $$166, $$167] <- [agg-local-sampling($$l_returnflag, $$l_linestatus), agg-null-writer($$l_returnflag), agg-null-writer($$l_linestatus)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$l_returnflag, $$l_linestatus])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- SORT_GROUP_BY[$$163, $$164]  |PARTITIONED|
-                                      {
+                              group by ([$$l_returnflag := $$163; $$l_linestatus := $$164]) decor ([]) {
+                                        aggregate [$$142, $$143, $$144, $$145, $$146, $$147, $$148, $$149] <- [agg-global-sql-sum($$155), agg-global-sql-sum($$156), agg-global-sql-sum($$157), agg-global-sql-sum($$158), agg-global-sql-avg($$159), agg-global-sql-avg($$160), agg-global-sql-avg($$161), agg-sql-sum($$162)]
                                         -- AGGREGATE  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- SORT_GROUP_BY[$$163, $$164]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$163, $$164]  |PARTITIONED|
-                                  -- SORT_GROUP_BY[$$137, $$138]  |PARTITIONED|
-                                          {
+                                  group by ([$$163 := $$137; $$164 := $$138]) decor ([]) {
+                                            aggregate [$$155, $$156, $$157, $$158, $$159, $$160, $$161, $$162] <- [agg-local-sql-sum($$90), agg-local-sql-sum($$95), agg-local-sql-sum(numeric-multiply($$95, numeric-subtract(1, $$152))), agg-local-sql-sum(numeric-multiply(numeric-multiply($$95, numeric-subtract(1, $$152)), numeric-add(1, $$154))), agg-local-sql-avg($$90), agg-local-sql-avg($$95), agg-local-sql-avg($$152), agg-sql-count(1)]
                                             -- AGGREGATE  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                          }
+                                         }
+                                  -- SORT_GROUP_BY[$$137, $$138]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      select (inject-failure(le($$l.getField(10), "1998-09-02"), eq($$140, 5988))) project: [$$90, $$95, $$152, $$154, $$137, $$138]
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        assign [$$138, $$137, $$90, $$152, $$154, $$95] <- [$$l.getField(9), $$l.getField(8), $$l.getField(4), $$l.getField(6), $$l.getField(7), $$l.getField(5)]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$140, $$l])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                              data-scan []<-[$$140, $$141, $$l] <- tpch.LineItem
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2354.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2354.plan
index 6bdc847..fa996ed 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2354.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2354.plan
@@ -1,42 +1,84 @@
+distribute result [$#1]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$#1])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$127(ASC), $$128(ASC), $$129(ASC) ]  |PARTITIONED|
+        order (ASC, $$127) (ASC, $$128) (ASC, $$129)
         -- STABLE_SORT [$$127(ASC), $$128(ASC), $$129(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            union ($$226, $$227, $#1) ($$130, $$87, $$129) ($$156, $$86, $$128) ($$84, $$89, $$127)
             -- UNION_ALL  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$226, $$130, $$156, $$84])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- RANDOM_PARTITION_EXCHANGE  |PARTITIONED|
+                    assign [$$226, $$130, $$156] <- [cast($$52), $$52.getField("v3"), $$52.getField("v2")] project: [$$84, $$226, $$130, $$156]
                     -- ASSIGN  |PARTITIONED|
+                      assign [$$52] <- [{"v1": $$84}]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$84] <- [$$89] project: [$$84]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (and(ge($$89, "Orders"), lt($$89, "Ordert")))
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  project ([$$89])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (Metadata.Dataset)  |PARTITIONED|
+                                      data-scan []<-[$$88, $$89, $$ds] <- Metadata.Dataset
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$227] <- [cast({"v1": $$89, "v2": $$86, "v3": $$87})] project: [$$227, $$87, $$86, $$89]
                 -- ASSIGN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true)
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange
                       -- RANDOM_PARTITION_EXCHANGE  |PARTITIONED|
+                        select (and(ge($$86, "Orders"), lt($$86, "Ordert")))
                         -- STREAM_SELECT  |PARTITIONED|
+                          project ([$$86, $$87])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (Metadata.Index)  |PARTITIONED|
+                              data-scan []<-[$$85, $$86, $$87, $$idx] <- Metadata.Index
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (and(ge($$89, "Orders"), lt($$89, "Ordert")))
                             -- STREAM_SELECT  |PARTITIONED|
+                              project ([$$89])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (Metadata.Dataset)  |PARTITIONED|
+                                  data-scan []<-[$$88, $$89, $$ds] <- Metadata.Dataset
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2354_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2354_ps.plan
index 32a3a17..6a4abe5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2354_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2354_ps.plan
@@ -1,90 +1,180 @@
+distribute result [$#1]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$#1])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$127) (ASC, $$128) (ASC, $$129)
         -- STABLE_SORT [$$127(ASC), $$128(ASC), $$129(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$127(ASC), $$128(ASC), $$129(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$232
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    union ($$226, $$227, $#1) ($$130, $$87, $$129) ($$156, $$86, $$128) ($$84, $$89, $$127)
                     -- UNION_ALL  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$226, $$130, $$156, $$84])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- RANDOM_PARTITION_EXCHANGE  |PARTITIONED|
+                            assign [$$226, $$130, $$156] <- [cast($$52), $$52.getField("v3"), $$52.getField("v2")] project: [$$84, $$226, $$130, $$156]
                             -- ASSIGN  |PARTITIONED|
+                              assign [$$52] <- [{"v1": $$84}]
                               -- ASSIGN  |PARTITIONED|
+                                assign [$$84] <- [$$89] project: [$$84]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        select (and(ge($$89, "Orders"), lt($$89, "Ordert")))
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          project ([$$89])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (Metadata.Dataset)  |PARTITIONED|
+                                              data-scan []<-[$$88, $$89, $$ds] <- Metadata.Dataset
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$227] <- [cast({"v1": $$89, "v2": $$86, "v3": $$87})] project: [$$227, $$87, $$86, $$89]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (true)
                             -- NESTED_LOOP  |PARTITIONED|
+                              exchange
                               -- RANDOM_PARTITION_EXCHANGE  |PARTITIONED|
+                                select (and(ge($$86, "Orders"), lt($$86, "Ordert")))
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  project ([$$86, $$87])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (Metadata.Index)  |PARTITIONED|
+                                      data-scan []<-[$$85, $$86, $$87, $$idx] <- Metadata.Index
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                replicate
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    select (and(ge($$89, "Orders"), lt($$89, "Ordert")))
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      project ([$$89])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (Metadata.Dataset)  |PARTITIONED|
+                                          data-scan []<-[$$88, $$89, $$ds] <- Metadata.Dataset
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$232] <- [agg-range-map($$228, $$229, $$230, $$231)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$228, $$229, $$230, $$231] <- [agg-local-sampling($$127, $$128, $$129), agg-null-writer($$127), agg-null-writer($$128), agg-null-writer($$129)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$127, $$128, $$129])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              union ($$226, $$227, $#1) ($$130, $$87, $$129) ($$156, $$86, $$128) ($$84, $$89, $$127)
                               -- UNION_ALL  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$226, $$130, $$156, $$84])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- RANDOM_PARTITION_EXCHANGE  |PARTITIONED|
+                                      assign [$$226, $$130, $$156] <- [cast($$52), $$52.getField("v3"), $$52.getField("v2")] project: [$$84, $$226, $$130, $$156]
                                       -- ASSIGN  |PARTITIONED|
+                                        assign [$$52] <- [{"v1": $$84}]
                                         -- ASSIGN  |PARTITIONED|
+                                          assign [$$84] <- [$$89] project: [$$84]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              replicate
                                               -- REPLICATE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  select (and(ge($$89, "Orders"), lt($$89, "Ordert")))
                                                   -- STREAM_SELECT  |PARTITIONED|
+                                                    project ([$$89])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (Metadata.Dataset)  |PARTITIONED|
+                                                        data-scan []<-[$$88, $$89, $$ds] <- Metadata.Dataset
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$227] <- [cast({"v1": $$89, "v2": $$86, "v3": $$87})] project: [$$227, $$87, $$86, $$89]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      join (true)
                                       -- NESTED_LOOP  |PARTITIONED|
+                                        exchange
                                         -- RANDOM_PARTITION_EXCHANGE  |PARTITIONED|
+                                          select (and(ge($$86, "Orders"), lt($$86, "Ordert")))
                                           -- STREAM_SELECT  |PARTITIONED|
+                                            project ([$$86, $$87])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (Metadata.Index)  |PARTITIONED|
+                                                data-scan []<-[$$85, $$86, $$87, $$idx] <- Metadata.Index
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              select (and(ge($$89, "Orders"), lt($$89, "Ordert")))
                                               -- STREAM_SELECT  |PARTITIONED|
+                                                project ([$$89])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (Metadata.Dataset)  |PARTITIONED|
+                                                    data-scan []<-[$$88, $$89, $$ds] <- Metadata.Dataset
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2408.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2408.plan
index 0168b4f..f56c182 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2408.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2408.plan
@@ -1,33 +1,63 @@
+distribute result [$$43]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$43] <- [{"name": $$51, "orders": $$40}] project: [$$43]
     -- ASSIGN  |PARTITIONED|
+      project ([$$51, $$40])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$48(ASC) ]  |PARTITIONED|
+          order (ASC, $$48)
           -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$51, $$40, $$48])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- PRE_CLUSTERED_GROUP_BY[$$46]  |PARTITIONED|
-                          {
+                  group by ([$$53 := $$46]) decor ([$$51]) {
+                            aggregate [$$40, $$48] <- [listify($$47), agg-sql-count($$47)]
                             -- AGGREGATE  |LOCAL|
+                              select (not(is-missing($$52)))
                               -- STREAM_SELECT  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                          }
+                         }
+                  -- PRE_CLUSTERED_GROUP_BY[$$46]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$46)
                       -- STABLE_SORT [$$46(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$51, $$47, $$52, $$46])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              left outer join (eq($$49, $$46))
                               -- HYBRID_HASH_JOIN [$$46][$$49]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$46]  |PARTITIONED|
+                                  assign [$$51] <- [$$c.getField("name")] project: [$$51, $$46]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.customers)  |PARTITIONED|
+                                      data-scan []<-[$$46, $$c] <- test.customers
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$49]  |PARTITIONED|
+                                  assign [$$52, $$49] <- [true, $$o.getField("customer_id")] project: [$$47, $$52, $$49]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                      data-scan []<-[$$47, $$o] <- test.orders
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2408_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2408_ps.plan
index d63b567..c7267f0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2408_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2408_ps.plan
@@ -1,71 +1,136 @@
+distribute result [$$43]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$43] <- [{"name": $$51, "orders": $$40}] project: [$$43]
     -- ASSIGN  |PARTITIONED|
+      project ([$$51, $$40])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$48)
           -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$48(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$56
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$51, $$40, $$48])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- PRE_CLUSTERED_GROUP_BY[$$46]  |PARTITIONED|
-                                  {
+                          group by ([$$53 := $$46]) decor ([$$51]) {
+                                    aggregate [$$40, $$48] <- [listify($$47), agg-sql-count($$47)]
                                     -- AGGREGATE  |LOCAL|
+                                      select (not(is-missing($$52)))
                                       -- STREAM_SELECT  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
+                                 }
+                          -- PRE_CLUSTERED_GROUP_BY[$$46]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$46)
                               -- STABLE_SORT [$$46(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$51, $$47, $$52, $$46])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      left outer join (eq($$49, $$46))
                                       -- HYBRID_HASH_JOIN [$$46][$$49]  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$46]  |PARTITIONED|
+                                          assign [$$51] <- [$$c.getField("name")] project: [$$51, $$46]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.customers)  |PARTITIONED|
+                                              data-scan []<-[$$46, $$c] <- test.customers
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$49]  |PARTITIONED|
+                                          assign [$$52, $$49] <- [true, $$o.getField("customer_id")] project: [$$47, $$52, $$49]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                              data-scan []<-[$$47, $$o] <- test.orders
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$56] <- [agg-range-map($$54, $$55)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$54, $$55] <- [agg-local-sampling($$48), agg-null-writer($$48)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$48])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$51, $$40, $$48])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- PRE_CLUSTERED_GROUP_BY[$$46]  |PARTITIONED|
-                                            {
+                                    group by ([$$53 := $$46]) decor ([$$51]) {
+                                              aggregate [$$40, $$48] <- [listify($$47), agg-sql-count($$47)]
                                               -- AGGREGATE  |LOCAL|
+                                                select (not(is-missing($$52)))
                                                 -- STREAM_SELECT  |LOCAL|
+                                                  nested tuple source
                                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                           }
+                                    -- PRE_CLUSTERED_GROUP_BY[$$46]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$46)
                                         -- STABLE_SORT [$$46(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$51, $$47, $$52, $$46])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                left outer join (eq($$49, $$46))
                                                 -- HYBRID_HASH_JOIN [$$46][$$49]  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$46]  |PARTITIONED|
+                                                    assign [$$51] <- [$$c.getField("name")] project: [$$51, $$46]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.customers)  |PARTITIONED|
+                                                        data-scan []<-[$$46, $$c] <- test.customers
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$49]  |PARTITIONED|
+                                                    assign [$$52, $$49] <- [true, $$o.getField("customer_id")] project: [$$47, $$52, $$49]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                        data-scan []<-[$$47, $$o] <- test.orders
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2700.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2700.plan
index cc46216..e018b3a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2700.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-2700.plan
@@ -1,32 +1,64 @@
+distribute result [$$46]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$46] <- [{"uname": $$55, "message": $$msg.getField("message")}] project: [$$46]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$msg.getField("author_id"), $$48)) project: [$$55, $$msg]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$55, $$48, $$msg])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (bigfun.GleambookMessagesComposite.GleambookMessagesComposite)  |PARTITIONED|
+            unnest-map [$$49, $$50, $$msg] <- index-search("GleambookMessagesComposite", 0, "Default", "bigfun", "GleambookMessagesComposite", true, false, 2, $$62, $$63, 2, $$62, $$63, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$62) (ASC, $$63)
                 -- STABLE_SORT [$$62(ASC), $$63(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$55, $$48, $$62, $$63])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (bigfun.GleambookMessagesComposite.authorIdIx)  |PARTITIONED|
+                        unnest-map [$$61, $$62, $$63] <- index-search("authorIdIx", 0, "Default", "bigfun", "GleambookMessagesComposite", true, true, 1, $$48, 1, $$48, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [] <- []
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- SORT_MERGE_EXCHANGE [$$48(ASC) ]  |PARTITIONED|
+                                order (ASC, $$48)
                                 -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    select (ge($$u.getField("user_since"), "2008-07-22T00:00:00")) project: [$$55, $$48]
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      assign [$$55] <- [$$u.getField("name")]
                                       -- ASSIGN  |PARTITIONED|
+                                        project ([$$48, $$u])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- BTREE_SEARCH (bigfun.GleambookUsersComposite.GleambookUsersComposite)  |PARTITIONED|
+                                            unnest-map [$$47, $$48, $$u] <- index-search("GleambookUsersComposite", 0, "Default", "bigfun", "GleambookUsersComposite", false, false, 2, $$59, $$60, 2, $$59, $$60, true, true, true)
+                                            -- BTREE_SEARCH  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                order (ASC, $$59) (ASC, $$60)
                                                 -- STABLE_SORT [$$59(ASC), $$60(ASC)]  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    project ([$$59, $$60])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- BTREE_SEARCH (bigfun.GleambookUsersComposite.usrSinceIx)  |PARTITIONED|
+                                                        unnest-map [$$58, $$59, $$60] <- index-search("usrSinceIx", 0, "Default", "bigfun", "GleambookUsersComposite", false, false, 1, $$57, 0, true, true, false)
+                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            assign [$$57] <- ["2008-07-22T00:00:00"]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-3334.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-3334.plan
index 54dec5e..923838e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-3334.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-3334.plan
@@ -1,56 +1,100 @@
+distribute result [$$800]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$800] <- [{"Employee Name": $$Employee Name, "avg:Employee Salary:ok": $$812}] project: [$$800]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- SORT_GROUP_BY[$$1120]  |PARTITIONED|
-                {
+        group by ([$$Employee Name := $$1120]) decor ([]) {
+                  aggregate [$$812] <- [agg-global-sql-avg($$1119)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$1120]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$1120]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$1121]  |PARTITIONED|
-                    {
+            group by ([$$1120 := $$1121]) decor ([]) {
+                      aggregate [$$1119] <- [agg-local-sql-avg($$1126)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$1121]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$1126, $$1121])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (and(eq($$1121, $$Employee Name), eq($$1122, $$Call Center Region)))
                     -- HYBRID_HASH_JOIN [$$1121, $$1122][$$Employee Name, $$Call Center Region]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$1122, $$1121]  |PARTITIONED|
+                        select (and(not(is-null(int64-default-null($#6.getField("Item Count")))), not(is-null(string-default-null($#6.getField("Ship Priority")))), not(is-null(string-default-null($#6.getField("Order Priority")))), not(is-null(string-default-null($#6.getField("Order Status")))), not(is-null(double-default-null($#6.getField("Order Quantity")))), not(is-null(double-default-null($#6.getField("Sales Total")))), not(is-null(double-default-null($#6.getField("Discount")))), not(is-null(double-default-null($#6.getField("Tax Rate")))), not(is-null(string-default-null($#6.getField("Ship Mode")))), not(is-null(double-default-null($#6.getField("Fill Time")))), not(is-null(double-default-null($#6.getField("Gross Profit")))), not(is-null(double-default-null($#6.getField("Price")))), not(is-null(double-default-null($#6.getField("Ship Handle Cost")))), not(is-null($$1121)), not(is-null(string-default-null($#6.getField("Employee Dept")))), not(is-null(string-default-null($#6.getField("Manager Name")))), not(is-null(double-default-null($#6.getField("Employee Yrs Exp")))), not(is-null($$1126)), not(is-null(string-default-null($#6.getField("Customer Name")))), not(is-null(string-default-null($#6.getField("Customer State")))), not(is-null($$1122)), not(is-null(double-default-null($#6.getField("Customer Balance")))), not(is-null(string-default-null($#6.getField("Customer Segment")))), not(is-null(string-default-null($#6.getField("Prod Type1")))), not(is-null(string-default-null($#6.getField("Prod Type2")))), not(is-null(string-default-null($#6.getField("Prod Type3")))), not(is-null(string-default-null($#6.getField("Prod Type4")))), not(is-null(string-default-null($#6.getField("Product Name")))), not(is-null(string-default-null($#6.getField("Product Container")))), not(is-null(string-default-null($#6.getField("Ship Promo")))), not(is-null(string-default-null($#6.getField("Supplier Name")))), not(is-null(double-default-null($#6.getField("Supplier Balance")))), not(is-null(string-default-null($#6.getField("Supplier Region")))), not(is-null(string-default-null($#6.getField("Supplier State")))), not(is-null(string-default-null($#6.getField("Order ID")))), not(is-null(int64-default-null($#6.getField("Order Year")))), not(is-null(int64-default-null($#6.getField("Order Month")))), not(is-null(int64-default-null($#6.getField("Order Day")))), not(is-null(datetime-default-null($#6.getField("Order Date")))), not(is-null(string-default-null($#6.getField("Order Quarter")))), not(is-null(double-default-null($#6.getField("Product Base Margin")))), not(is-null(string-default-null($#6.getField("Product ID")))), not(is-null(double-default-null($#6.getField("Receive Time")))), not(is-null(datetime-default-null($#6.getField("Received Date")))), not(is-null(datetime-default-null($#6.getField("Ship Date")))), not(is-null(double-default-null($#6.getField("Ship Charge")))), not(is-null(double-default-null($#6.getField("Total Cycle Time")))), not(is-null(string-default-null($#6.getField("Product In Stock")))), not(is-null(int64-default-null($#6.getField("PID")))), not(is-null(string-default-null($#6.getField("Market Segment")))))) project: [$$1126, $$1121, $$1122]
                         -- STREAM_SELECT  |PARTITIONED|
+                          assign [$$1126, $$1122, $$1121] <- [double-default-null($#6.getField("Employee Salary")), string-default-null($#6.getField("Call Center Region")), string-default-null($#6.getField("Employee Name"))]
                           -- ASSIGN  |PARTITIONED|
+                            assign [$#6] <- [$#6] project: [$#6]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                replicate
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$#6])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                        data-scan []<-[$$806, $#6] <- test.collection0
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        select (and(ge($$811, 102499.99999999898), le($$810, 110000.0000000011))) project: [$$Employee Name, $$Call Center Region]
                         -- STREAM_SELECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- SORT_GROUP_BY[$$1117, $$1118]  |PARTITIONED|
-                                    {
+                            group by ([$$Call Center Region := $$1117; $$Employee Name := $$1118]) decor ([]) {
+                                      aggregate [$$810, $$811] <- [agg-global-sql-avg($$1115), agg-global-sql-avg($$1116)]
                                       -- AGGREGATE  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- SORT_GROUP_BY[$$1117, $$1118]  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$1117, $$1118]  |PARTITIONED|
-                                -- SORT_GROUP_BY[$$1125, $$1124]  |PARTITIONED|
-                                        {
+                                group by ([$$1117 := $$1125; $$1118 := $$1124]) decor ([]) {
+                                          aggregate [$$1115, $$1116] <- [agg-local-sql-avg($$1123), agg-local-sql-avg($$1123)]
                                           -- AGGREGATE  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- SORT_GROUP_BY[$$1125, $$1124]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    select (and(not(is-null(int64-default-null($#6.getField("Item Count")))), not(is-null(string-default-null($#6.getField("Ship Priority")))), not(is-null(string-default-null($#6.getField("Order Priority")))), not(is-null(string-default-null($#6.getField("Order Status")))), not(is-null(double-default-null($#6.getField("Order Quantity")))), not(is-null(double-default-null($#6.getField("Sales Total")))), not(is-null(double-default-null($#6.getField("Discount")))), not(is-null(double-default-null($#6.getField("Tax Rate")))), not(is-null(string-default-null($#6.getField("Ship Mode")))), not(is-null(double-default-null($#6.getField("Fill Time")))), not(is-null(double-default-null($#6.getField("Gross Profit")))), not(is-null(double-default-null($#6.getField("Price")))), not(is-null(double-default-null($#6.getField("Ship Handle Cost")))), not(is-null($$1124)), not(is-null(string-default-null($#6.getField("Employee Dept")))), not(is-null(string-default-null($#6.getField("Manager Name")))), not(is-null(double-default-null($#6.getField("Employee Yrs Exp")))), not(is-null($$1123)), not(is-null(string-default-null($#6.getField("Customer Name")))), not(is-null(string-default-null($#6.getField("Customer State")))), not(is-null($$1125)), not(is-null(double-default-null($#6.getField("Customer Balance")))), not(is-null(string-default-null($#6.getField("Customer Segment")))), not(is-null(string-default-null($#6.getField("Prod Type1")))), not(is-null(string-default-null($#6.getField("Prod Type2")))), not(is-null(string-default-null($#6.getField("Prod Type3")))), not(is-null(string-default-null($#6.getField("Prod Type4")))), not(is-null(string-default-null($#6.getField("Product Name")))), not(is-null(string-default-null($#6.getField("Product Container")))), not(is-null(string-default-null($#6.getField("Ship Promo")))), not(is-null(string-default-null($#6.getField("Supplier Name")))), not(is-null(double-default-null($#6.getField("Supplier Balance")))), not(is-null(string-default-null($#6.getField("Supplier Region")))), not(is-null(string-default-null($#6.getField("Supplier State")))), not(is-null(string-default-null($#6.getField("Order ID")))), not(is-null(int64-default-null($#6.getField("Order Year")))), not(is-null(int64-default-null($#6.getField("Order Month")))), not(is-null(int64-default-null($#6.getField("Order Day")))), not(is-null(datetime-default-null($#6.getField("Order Date")))), not(is-null(string-default-null($#6.getField("Order Quarter")))), not(is-null(double-default-null($#6.getField("Product Base Margin")))), not(is-null(string-default-null($#6.getField("Product ID")))), not(is-null(double-default-null($#6.getField("Receive Time")))), not(is-null(datetime-default-null($#6.getField("Received Date")))), not(is-null(datetime-default-null($#6.getField("Ship Date")))), not(is-null(double-default-null($#6.getField("Ship Charge")))), not(is-null(double-default-null($#6.getField("Total Cycle Time")))), not(is-null(string-default-null($#6.getField("Product In Stock")))), not(is-null(int64-default-null($#6.getField("PID")))), not(is-null(string-default-null($#6.getField("Market Segment")))))) project: [$$1123, $$1125, $$1124]
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      assign [$$1125, $$1124, $$1123] <- [string-default-null($#6.getField("Call Center Region")), string-default-null($#6.getField("Employee Name")), double-default-null($#6.getField("Employee Salary"))]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$#6])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                  data-scan []<-[$$806, $#6] <- test.collection0
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-3512.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-3512.plan
index 5c94534..ab4bd19 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-3512.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-3512.plan
@@ -1,26 +1,52 @@
+distribute result [$$97]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    union ($$89, $$94, $$97)
     -- UNION_ALL  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        assign [$$89] <- [{"sym": $$S.getField("sym")}] project: [$$89]
         -- ASSIGN  |PARTITIONED|
+          select (lt($$S.getField("date"), print-date(current-date(), "YYYY-MM-DD")))
           -- STREAM_SELECT  |PARTITIONED|
+            project ([$$S])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                data-scan []<-[$$108, $$S] <- test.collection1
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        assign [$$94] <- [{"sym": $$106.getField("sym")}] project: [$$94]
         -- ASSIGN  |PARTITIONED|
+          select (lt($$106.getField("date"), print-date(current-date(), "YYYY-MM-DD")))
           -- STREAM_SELECT  |PARTITIONED|
+            project ([$$106])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.collection2.collection2)  |PARTITIONED|
+                unnest-map [$$111, $$106] <- index-search("collection2", 0, "Default", "test", "collection2", false, false, 1, $$123, 1, $$123, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$123)
                     -- STABLE_SORT [$$123(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$123])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.collection2.idx1)  |PARTITIONED|
+                            unnest-map [$$119, $$120, $$121, $$122, $$123] <- index-search("idx1", 0, "Default", "test", "collection2", false, false, 0, 1, $$118, true, false, false)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$118] <- [print-date(current-date(), "YYYY-MM-DD")]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-2.plan
index 044420e..bab4b0d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-2.plan
@@ -1,36 +1,62 @@
+distribute result [$$113]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$113] <- [{"l_returnflag": $$l_returnflag, "l_linestatus": $$l_linestatus, "count_cheaps": $$120, "count_expensives": $$121}] project: [$$113]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$l_returnflag(ASC), $$l_linestatus(ASC) ]  |PARTITIONED|
+        group by ([$$l_returnflag := $$128; $$l_linestatus := $$129]) decor ([]) {
+                  aggregate [$$120] <- [agg-sum($$126)]
+                  -- AGGREGATE  |LOCAL|
+                    nested tuple source
+                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+               }
+               {
+                  aggregate [$$121] <- [agg-sum($$127)]
+                  -- AGGREGATE  |LOCAL|
+                    nested tuple source
+                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+               }
         -- PRE_CLUSTERED_GROUP_BY[$$128, $$129]  |PARTITIONED|
-                {
-                  -- AGGREGATE  |LOCAL|
-                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
-                  -- AGGREGATE  |LOCAL|
-                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$128) (ASC, $$129)
             -- STABLE_SORT [$$128(ASC), $$129(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$128, $$129]  |PARTITIONED|
+                group by ([$$128 := $$114; $$129 := $$115]) decor ([]) {
+                          aggregate [$$126] <- [agg-count($$l)]
+                          -- AGGREGATE  |LOCAL|
+                            select (gt($$124, 0.05))
+                            -- STREAM_SELECT  |LOCAL|
+                              nested tuple source
+                              -- NESTED_TUPLE_SOURCE  |LOCAL|
+                       }
+                       {
+                          aggregate [$$127] <- [agg-count($$l)]
+                          -- AGGREGATE  |LOCAL|
+                            select (le($$124, 0.05))
+                            -- STREAM_SELECT  |LOCAL|
+                              nested tuple source
+                              -- NESTED_TUPLE_SOURCE  |LOCAL|
+                       }
                 -- PRE_CLUSTERED_GROUP_BY[$$114, $$115]  |PARTITIONED|
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$114) (ASC, $$115)
                     -- STABLE_SORT [$$114(ASC), $$115(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$115, $$114, $$124] <- [$$l.getField(9), $$l.getField(8), $$l.getField(6)]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$l])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                              data-scan []<-[$$118, $$119, $$l] <- tpch.LineItem
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-2_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-2_ps.plan
index bbb0517..24eb512 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-2_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-2_ps.plan
@@ -1,82 +1,144 @@
+distribute result [$$113]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$113] <- [{"l_returnflag": $$l_returnflag, "l_linestatus": $$l_linestatus, "count_cheaps": $$120, "count_expensives": $$121}] project: [$$113]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$l_returnflag) (ASC, $$l_linestatus)
         -- STABLE_SORT [$$l_returnflag(ASC), $$l_linestatus(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$l_returnflag(ASC), $$l_linestatus(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$133
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    group by ([$$l_returnflag := $$128; $$l_linestatus := $$129]) decor ([]) {
+                              aggregate [$$120] <- [agg-sum($$126)]
+                              -- AGGREGATE  |LOCAL|
+                                nested tuple source
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                           }
+                           {
+                              aggregate [$$121] <- [agg-sum($$127)]
+                              -- AGGREGATE  |LOCAL|
+                                nested tuple source
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                           }
                     -- PRE_CLUSTERED_GROUP_BY[$$128, $$129]  |PARTITIONED|
-                            {
-                              -- AGGREGATE  |LOCAL|
-                                -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
-                            {
-                              -- AGGREGATE  |LOCAL|
-                                -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$128) (ASC, $$129)
                         -- STABLE_SORT [$$128(ASC), $$129(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$128, $$129]  |PARTITIONED|
+                            group by ([$$128 := $$114; $$129 := $$115]) decor ([]) {
+                                      aggregate [$$126] <- [agg-count($$l)]
+                                      -- AGGREGATE  |LOCAL|
+                                        select (gt($$124, 0.05))
+                                        -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
+                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                   }
+                                   {
+                                      aggregate [$$127] <- [agg-count($$l)]
+                                      -- AGGREGATE  |LOCAL|
+                                        select (le($$124, 0.05))
+                                        -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
+                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                   }
                             -- PRE_CLUSTERED_GROUP_BY[$$114, $$115]  |PARTITIONED|
-                                    {
-                                      -- AGGREGATE  |LOCAL|
-                                        -- STREAM_SELECT  |LOCAL|
-                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
-                                    {
-                                      -- AGGREGATE  |LOCAL|
-                                        -- STREAM_SELECT  |LOCAL|
-                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$114) (ASC, $$115)
                                 -- STABLE_SORT [$$114(ASC), $$115(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$115, $$114, $$124] <- [$$l.getField(9), $$l.getField(8), $$l.getField(6)]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$l])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                          data-scan []<-[$$118, $$119, $$l] <- tpch.LineItem
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$133] <- [agg-range-map($$130, $$131, $$132)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$130, $$131, $$132] <- [agg-local-sampling($$l_returnflag, $$l_linestatus), agg-null-writer($$l_returnflag), agg-null-writer($$l_linestatus)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$l_returnflag, $$l_linestatus])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              group by ([$$l_returnflag := $$128; $$l_linestatus := $$129]) decor ([]) {
+                                        aggregate [$$120] <- [agg-sum($$126)]
+                                        -- AGGREGATE  |LOCAL|
+                                          nested tuple source
+                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                     }
+                                     {
+                                        aggregate [$$121] <- [agg-sum($$127)]
+                                        -- AGGREGATE  |LOCAL|
+                                          nested tuple source
+                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                     }
                               -- PRE_CLUSTERED_GROUP_BY[$$128, $$129]  |PARTITIONED|
-                                      {
-                                        -- AGGREGATE  |LOCAL|
-                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
-                                      {
-                                        -- AGGREGATE  |LOCAL|
-                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$128) (ASC, $$129)
                                   -- STABLE_SORT [$$128(ASC), $$129(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$128, $$129]  |PARTITIONED|
+                                      group by ([$$128 := $$114; $$129 := $$115]) decor ([]) {
+                                                aggregate [$$126] <- [agg-count($$l)]
+                                                -- AGGREGATE  |LOCAL|
+                                                  select (gt($$124, 0.05))
+                                                  -- STREAM_SELECT  |LOCAL|
+                                                    nested tuple source
+                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                             }
+                                             {
+                                                aggregate [$$127] <- [agg-count($$l)]
+                                                -- AGGREGATE  |LOCAL|
+                                                  select (le($$124, 0.05))
+                                                  -- STREAM_SELECT  |LOCAL|
+                                                    nested tuple source
+                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                             }
                                       -- PRE_CLUSTERED_GROUP_BY[$$114, $$115]  |PARTITIONED|
-                                              {
-                                                -- AGGREGATE  |LOCAL|
-                                                  -- STREAM_SELECT  |LOCAL|
-                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                              }
-                                              {
-                                                -- AGGREGATE  |LOCAL|
-                                                  -- STREAM_SELECT  |LOCAL|
-                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                              }
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          order (ASC, $$114) (ASC, $$115)
                                           -- STABLE_SORT [$$114(ASC), $$115(ASC)]  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$115, $$114, $$124] <- [$$l.getField(9), $$l.getField(8), $$l.getField(6)]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$l])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                                    data-scan []<-[$$118, $$119, $$l] <- tpch.LineItem
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-3.plan
index fdbbcce..b98f872 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-3.plan
@@ -1,36 +1,62 @@
+distribute result [$$125]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$125] <- [{"l_returnflag": $$l_returnflag, "l_linestatus": $$l_linestatus, "count_cheaps": $$131, "count_expensives": $$132}] project: [$$125]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$l_returnflag(ASC), $$l_linestatus(ASC) ]  |PARTITIONED|
+        group by ([$$l_returnflag := $$139; $$l_linestatus := $$140]) decor ([]) {
+                  aggregate [$$131] <- [agg-sum($$137)]
+                  -- AGGREGATE  |LOCAL|
+                    nested tuple source
+                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+               }
+               {
+                  aggregate [$$132] <- [agg-sum($$138)]
+                  -- AGGREGATE  |LOCAL|
+                    nested tuple source
+                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+               }
         -- PRE_CLUSTERED_GROUP_BY[$$139, $$140]  |PARTITIONED|
-                {
-                  -- AGGREGATE  |LOCAL|
-                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
-                  -- AGGREGATE  |LOCAL|
-                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$139) (ASC, $$140)
             -- STABLE_SORT [$$139(ASC), $$140(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$139, $$140]  |PARTITIONED|
+                group by ([$$139 := $$126; $$140 := $$127]) decor ([]) {
+                          aggregate [$$137] <- [agg-count($$l)]
+                          -- AGGREGATE  |LOCAL|
+                            select (gt($$135, 0.05))
+                            -- STREAM_SELECT  |LOCAL|
+                              nested tuple source
+                              -- NESTED_TUPLE_SOURCE  |LOCAL|
+                       }
+                       {
+                          aggregate [$$138] <- [agg-count($$l)]
+                          -- AGGREGATE  |LOCAL|
+                            select (le($$135, 0.05))
+                            -- STREAM_SELECT  |LOCAL|
+                              nested tuple source
+                              -- NESTED_TUPLE_SOURCE  |LOCAL|
+                       }
                 -- PRE_CLUSTERED_GROUP_BY[$$126, $$127]  |PARTITIONED|
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$126) (ASC, $$127)
                     -- STABLE_SORT [$$126(ASC), $$127(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$127, $$126, $$135] <- [$$l.getField(9), $$l.getField(8), $$l.getField(6)]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$l])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                              data-scan []<-[$$129, $$130, $$l] <- tpch.LineItem
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-3_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-3_ps.plan
index 8fc7dc7..4d3af5c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-3_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-3_ps.plan
@@ -1,82 +1,144 @@
+distribute result [$$125]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$125] <- [{"l_returnflag": $$l_returnflag, "l_linestatus": $$l_linestatus, "count_cheaps": $$131, "count_expensives": $$132}] project: [$$125]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$l_returnflag) (ASC, $$l_linestatus)
         -- STABLE_SORT [$$l_returnflag(ASC), $$l_linestatus(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$l_returnflag(ASC), $$l_linestatus(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$144
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    group by ([$$l_returnflag := $$139; $$l_linestatus := $$140]) decor ([]) {
+                              aggregate [$$131] <- [agg-sum($$137)]
+                              -- AGGREGATE  |LOCAL|
+                                nested tuple source
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                           }
+                           {
+                              aggregate [$$132] <- [agg-sum($$138)]
+                              -- AGGREGATE  |LOCAL|
+                                nested tuple source
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                           }
                     -- PRE_CLUSTERED_GROUP_BY[$$139, $$140]  |PARTITIONED|
-                            {
-                              -- AGGREGATE  |LOCAL|
-                                -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
-                            {
-                              -- AGGREGATE  |LOCAL|
-                                -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$139) (ASC, $$140)
                         -- STABLE_SORT [$$139(ASC), $$140(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$139, $$140]  |PARTITIONED|
+                            group by ([$$139 := $$126; $$140 := $$127]) decor ([]) {
+                                      aggregate [$$137] <- [agg-count($$l)]
+                                      -- AGGREGATE  |LOCAL|
+                                        select (gt($$135, 0.05))
+                                        -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
+                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                   }
+                                   {
+                                      aggregate [$$138] <- [agg-count($$l)]
+                                      -- AGGREGATE  |LOCAL|
+                                        select (le($$135, 0.05))
+                                        -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
+                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                   }
                             -- PRE_CLUSTERED_GROUP_BY[$$126, $$127]  |PARTITIONED|
-                                    {
-                                      -- AGGREGATE  |LOCAL|
-                                        -- STREAM_SELECT  |LOCAL|
-                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
-                                    {
-                                      -- AGGREGATE  |LOCAL|
-                                        -- STREAM_SELECT  |LOCAL|
-                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$126) (ASC, $$127)
                                 -- STABLE_SORT [$$126(ASC), $$127(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$127, $$126, $$135] <- [$$l.getField(9), $$l.getField(8), $$l.getField(6)]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$l])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                          data-scan []<-[$$129, $$130, $$l] <- tpch.LineItem
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$144] <- [agg-range-map($$141, $$142, $$143)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$141, $$142, $$143] <- [agg-local-sampling($$l_returnflag, $$l_linestatus), agg-null-writer($$l_returnflag), agg-null-writer($$l_linestatus)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$l_returnflag, $$l_linestatus])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              group by ([$$l_returnflag := $$139; $$l_linestatus := $$140]) decor ([]) {
+                                        aggregate [$$131] <- [agg-sum($$137)]
+                                        -- AGGREGATE  |LOCAL|
+                                          nested tuple source
+                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                     }
+                                     {
+                                        aggregate [$$132] <- [agg-sum($$138)]
+                                        -- AGGREGATE  |LOCAL|
+                                          nested tuple source
+                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                     }
                               -- PRE_CLUSTERED_GROUP_BY[$$139, $$140]  |PARTITIONED|
-                                      {
-                                        -- AGGREGATE  |LOCAL|
-                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
-                                      {
-                                        -- AGGREGATE  |LOCAL|
-                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$139) (ASC, $$140)
                                   -- STABLE_SORT [$$139(ASC), $$140(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$139, $$140]  |PARTITIONED|
+                                      group by ([$$139 := $$126; $$140 := $$127]) decor ([]) {
+                                                aggregate [$$137] <- [agg-count($$l)]
+                                                -- AGGREGATE  |LOCAL|
+                                                  select (gt($$135, 0.05))
+                                                  -- STREAM_SELECT  |LOCAL|
+                                                    nested tuple source
+                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                             }
+                                             {
+                                                aggregate [$$138] <- [agg-count($$l)]
+                                                -- AGGREGATE  |LOCAL|
+                                                  select (le($$135, 0.05))
+                                                  -- STREAM_SELECT  |LOCAL|
+                                                    nested tuple source
+                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                             }
                                       -- PRE_CLUSTERED_GROUP_BY[$$126, $$127]  |PARTITIONED|
-                                              {
-                                                -- AGGREGATE  |LOCAL|
-                                                  -- STREAM_SELECT  |LOCAL|
-                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                              }
-                                              {
-                                                -- AGGREGATE  |LOCAL|
-                                                  -- STREAM_SELECT  |LOCAL|
-                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                              }
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          order (ASC, $$126) (ASC, $$127)
                                           -- STABLE_SORT [$$126(ASC), $$127(ASC)]  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$127, $$126, $$135] <- [$$l.getField(9), $$l.getField(8), $$l.getField(6)]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$l])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                                    data-scan []<-[$$129, $$130, $$l] <- tpch.LineItem
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810.plan
index 7767cc3..b925f4a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810.plan
@@ -1,36 +1,62 @@
+distribute result [$$137]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$137] <- [{"l_returnflag": $$l_returnflag, "l_linestatus": $$l_linestatus, "count_cheaps": $$142, "count_expensives": $$143}] project: [$$137]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$l_returnflag(ASC), $$l_linestatus(ASC) ]  |PARTITIONED|
+        group by ([$$l_returnflag := $$150; $$l_linestatus := $$151]) decor ([]) {
+                  aggregate [$$142] <- [agg-sum($$148)]
+                  -- AGGREGATE  |LOCAL|
+                    nested tuple source
+                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+               }
+               {
+                  aggregate [$$143] <- [agg-sum($$149)]
+                  -- AGGREGATE  |LOCAL|
+                    nested tuple source
+                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+               }
         -- PRE_CLUSTERED_GROUP_BY[$$150, $$151]  |PARTITIONED|
-                {
-                  -- AGGREGATE  |LOCAL|
-                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
-                  -- AGGREGATE  |LOCAL|
-                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$150) (ASC, $$151)
             -- STABLE_SORT [$$150(ASC), $$151(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$150, $$151]  |PARTITIONED|
+                group by ([$$150 := $$138; $$151 := $$139]) decor ([]) {
+                          aggregate [$$148] <- [agg-count($$l)]
+                          -- AGGREGATE  |LOCAL|
+                            select (gt($$146, 0.05))
+                            -- STREAM_SELECT  |LOCAL|
+                              nested tuple source
+                              -- NESTED_TUPLE_SOURCE  |LOCAL|
+                       }
+                       {
+                          aggregate [$$149] <- [agg-count($$l)]
+                          -- AGGREGATE  |LOCAL|
+                            select (le($$146, 0.05))
+                            -- STREAM_SELECT  |LOCAL|
+                              nested tuple source
+                              -- NESTED_TUPLE_SOURCE  |LOCAL|
+                       }
                 -- PRE_CLUSTERED_GROUP_BY[$$138, $$139]  |PARTITIONED|
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$138) (ASC, $$139)
                     -- STABLE_SORT [$$138(ASC), $$139(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$139, $$138, $$146] <- [$$l.getField(9), $$l.getField(8), $$l.getField(6)]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$l])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                              data-scan []<-[$$140, $$141, $$l] <- tpch.LineItem
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810_ps.plan
index 7fb7d4a..510903c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810_ps.plan
@@ -1,82 +1,144 @@
+distribute result [$$137]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$137] <- [{"l_returnflag": $$l_returnflag, "l_linestatus": $$l_linestatus, "count_cheaps": $$142, "count_expensives": $$143}] project: [$$137]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$l_returnflag) (ASC, $$l_linestatus)
         -- STABLE_SORT [$$l_returnflag(ASC), $$l_linestatus(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$l_returnflag(ASC), $$l_linestatus(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$155
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    group by ([$$l_returnflag := $$150; $$l_linestatus := $$151]) decor ([]) {
+                              aggregate [$$142] <- [agg-sum($$148)]
+                              -- AGGREGATE  |LOCAL|
+                                nested tuple source
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                           }
+                           {
+                              aggregate [$$143] <- [agg-sum($$149)]
+                              -- AGGREGATE  |LOCAL|
+                                nested tuple source
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                           }
                     -- PRE_CLUSTERED_GROUP_BY[$$150, $$151]  |PARTITIONED|
-                            {
-                              -- AGGREGATE  |LOCAL|
-                                -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
-                            {
-                              -- AGGREGATE  |LOCAL|
-                                -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$150) (ASC, $$151)
                         -- STABLE_SORT [$$150(ASC), $$151(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$150, $$151]  |PARTITIONED|
+                            group by ([$$150 := $$138; $$151 := $$139]) decor ([]) {
+                                      aggregate [$$148] <- [agg-count($$l)]
+                                      -- AGGREGATE  |LOCAL|
+                                        select (gt($$146, 0.05))
+                                        -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
+                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                   }
+                                   {
+                                      aggregate [$$149] <- [agg-count($$l)]
+                                      -- AGGREGATE  |LOCAL|
+                                        select (le($$146, 0.05))
+                                        -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
+                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                   }
                             -- PRE_CLUSTERED_GROUP_BY[$$138, $$139]  |PARTITIONED|
-                                    {
-                                      -- AGGREGATE  |LOCAL|
-                                        -- STREAM_SELECT  |LOCAL|
-                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
-                                    {
-                                      -- AGGREGATE  |LOCAL|
-                                        -- STREAM_SELECT  |LOCAL|
-                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$138) (ASC, $$139)
                                 -- STABLE_SORT [$$138(ASC), $$139(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$139, $$138, $$146] <- [$$l.getField(9), $$l.getField(8), $$l.getField(6)]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$l])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                          data-scan []<-[$$140, $$141, $$l] <- tpch.LineItem
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$155] <- [agg-range-map($$152, $$153, $$154)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$152, $$153, $$154] <- [agg-local-sampling($$l_returnflag, $$l_linestatus), agg-null-writer($$l_returnflag), agg-null-writer($$l_linestatus)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$l_returnflag, $$l_linestatus])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              group by ([$$l_returnflag := $$150; $$l_linestatus := $$151]) decor ([]) {
+                                        aggregate [$$142] <- [agg-sum($$148)]
+                                        -- AGGREGATE  |LOCAL|
+                                          nested tuple source
+                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                     }
+                                     {
+                                        aggregate [$$143] <- [agg-sum($$149)]
+                                        -- AGGREGATE  |LOCAL|
+                                          nested tuple source
+                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                     }
                               -- PRE_CLUSTERED_GROUP_BY[$$150, $$151]  |PARTITIONED|
-                                      {
-                                        -- AGGREGATE  |LOCAL|
-                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
-                                      {
-                                        -- AGGREGATE  |LOCAL|
-                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$150) (ASC, $$151)
                                   -- STABLE_SORT [$$150(ASC), $$151(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$150, $$151]  |PARTITIONED|
+                                      group by ([$$150 := $$138; $$151 := $$139]) decor ([]) {
+                                                aggregate [$$148] <- [agg-count($$l)]
+                                                -- AGGREGATE  |LOCAL|
+                                                  select (gt($$146, 0.05))
+                                                  -- STREAM_SELECT  |LOCAL|
+                                                    nested tuple source
+                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                             }
+                                             {
+                                                aggregate [$$149] <- [agg-count($$l)]
+                                                -- AGGREGATE  |LOCAL|
+                                                  select (le($$146, 0.05))
+                                                  -- STREAM_SELECT  |LOCAL|
+                                                    nested tuple source
+                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                             }
                                       -- PRE_CLUSTERED_GROUP_BY[$$138, $$139]  |PARTITIONED|
-                                              {
-                                                -- AGGREGATE  |LOCAL|
-                                                  -- STREAM_SELECT  |LOCAL|
-                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                              }
-                                              {
-                                                -- AGGREGATE  |LOCAL|
-                                                  -- STREAM_SELECT  |LOCAL|
-                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                              }
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          order (ASC, $$138) (ASC, $$139)
                                           -- STABLE_SORT [$$138(ASC), $$139(ASC)]  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$139, $$138, $$146] <- [$$l.getField(9), $$l.getField(8), $$l.getField(6)]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$l])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                                    data-scan []<-[$$140, $$141, $$l] <- tpch.LineItem
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-issue562_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-issue562_ps.plan
index 079729e..4f32889 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-issue562_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-issue562_ps.plan
@@ -1,130 +1,236 @@
+distribute result [$$154]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$154] <- [{"cntrycode": $$cntrycode, "numcust": $$160, "totacctbal": $$161}] project: [$$154]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$cntrycode)
         -- STABLE_SORT [$$cntrycode(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$cntrycode(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$179
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$176]  |PARTITIONED|
-                            {
+                    group by ([$$cntrycode := $$176]) decor ([]) {
+                              aggregate [$$160, $$161] <- [agg-sum($$174), agg-global-sum($$175)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$176]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$176]  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$phone_substr]  |PARTITIONED|
-                                {
+                        group by ([$$176 := $$phone_substr]) decor ([]) {
+                                  aggregate [$$174, $$175] <- [agg-count($$144), agg-local-sum($$165)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$phone_substr]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$144] <- [{"ct": $$135}] project: [$$144, $$165, $$phone_substr]
                             -- ASSIGN  |PARTITIONED|
+                              select (eq($$159, 0)) project: [$$phone_substr, $$165, $$135]
                               -- STREAM_SELECT  |PARTITIONED|
+                                project ([$$159, $$phone_substr, $$165, $$135])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- SORT_GROUP_BY[$$173]  |PARTITIONED|
-                                            {
+                                    group by ([$$171 := $$173]) decor ([$$phone_substr; $$165; $$135]) {
+                                              aggregate [$$159] <- [agg-sum($$172)]
                                               -- AGGREGATE  |LOCAL|
+                                                nested tuple source
                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                           }
+                                    -- SORT_GROUP_BY[$$173]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$173]  |PARTITIONED|
-                                        -- PRE_CLUSTERED_GROUP_BY[$$169]  |PARTITIONED|
-                                                {
+                                        group by ([$$173 := $$169]) decor ([$$phone_substr; $$165; $$135]) {
+                                                  aggregate [$$172] <- [agg-count($$o)]
                                                   -- AGGREGATE  |LOCAL|
+                                                    select (not(is-missing($$170)))
                                                     -- STREAM_SELECT  |LOCAL|
+                                                      nested tuple source
                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                               }
+                                        -- PRE_CLUSTERED_GROUP_BY[$$169]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$169)
                                             -- STABLE_SORT [$$169(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$165, $$phone_substr, $$135, $$o, $$170, $$169])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    left outer join (eq($$156, $$163))
                                                     -- HYBRID_HASH_JOIN [$$156][$$163]  |PARTITIONED|
+                                                      exchange
                                                       -- HASH_PARTITION_EXCHANGE [$$156]  |PARTITIONED|
+                                                        running-aggregate [$$169] <- [create-query-uid()]
                                                         -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                          assign [$$135] <- [{"c_acctbal": $$165, "c_custkey": $$156, "cntrycode": $$phone_substr}]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            project ([$$165, $$phone_substr, $$156])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                join (eq($$158, $$phone_substr))
                                                                 -- HYBRID_HASH_JOIN [$$phone_substr][$$158]  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    assign [$$phone_substr, $$165] <- [substring($$c.getField(4), 0, 2), $$c.getField(5)] project: [$$165, $$phone_substr, $$156]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                                                        data-scan []<-[$$156, $$c] <- tpch.Customer
+                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                  exchange
                                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                    unnest $$158 <- scan-collection(array: [ "23", "13", "17", "29", "18", "30", "31" ])
                                                                     -- UNNEST  |UNPARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                      exchange
                                                       -- HASH_PARTITION_EXCHANGE [$$163]  |PARTITIONED|
+                                                        assign [$$170, $$163] <- [true, $$o.getField(1)]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          project ([$$o])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                                              data-scan []<-[$$157, $$o] <- tpch.Orders
+                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$179] <- [agg-range-map($$177, $$178)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$177, $$178] <- [agg-local-sampling($$cntrycode), agg-null-writer($$cntrycode)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$cntrycode])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- SORT_GROUP_BY[$$176]  |PARTITIONED|
-                                      {
+                              group by ([$$cntrycode := $$176]) decor ([]) {
+                                        aggregate [$$160, $$161] <- [agg-sum($$174), agg-global-sum($$175)]
                                         -- AGGREGATE  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- SORT_GROUP_BY[$$176]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$176]  |PARTITIONED|
-                                  -- SORT_GROUP_BY[$$phone_substr]  |PARTITIONED|
-                                          {
+                                  group by ([$$176 := $$phone_substr]) decor ([]) {
+                                            aggregate [$$174, $$175] <- [agg-count($$144), agg-local-sum($$165)]
                                             -- AGGREGATE  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                          }
+                                         }
+                                  -- SORT_GROUP_BY[$$phone_substr]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$144] <- [{"ct": $$135}] project: [$$144, $$165, $$phone_substr]
                                       -- ASSIGN  |PARTITIONED|
+                                        select (eq($$159, 0)) project: [$$phone_substr, $$165, $$135]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          project ([$$159, $$phone_substr, $$165, $$135])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- SORT_GROUP_BY[$$173]  |PARTITIONED|
-                                                      {
+                                              group by ([$$171 := $$173]) decor ([$$phone_substr; $$165; $$135]) {
+                                                        aggregate [$$159] <- [agg-sum($$172)]
                                                         -- AGGREGATE  |LOCAL|
+                                                          nested tuple source
                                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                      }
+                                                     }
+                                              -- SORT_GROUP_BY[$$173]  |PARTITIONED|
+                                                exchange
                                                 -- HASH_PARTITION_EXCHANGE [$$173]  |PARTITIONED|
-                                                  -- PRE_CLUSTERED_GROUP_BY[$$169]  |PARTITIONED|
-                                                          {
+                                                  group by ([$$173 := $$169]) decor ([$$phone_substr; $$165; $$135]) {
+                                                            aggregate [$$172] <- [agg-count($$o)]
                                                             -- AGGREGATE  |LOCAL|
+                                                              select (not(is-missing($$170)))
                                                               -- STREAM_SELECT  |LOCAL|
+                                                                nested tuple source
                                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                          }
+                                                         }
+                                                  -- PRE_CLUSTERED_GROUP_BY[$$169]  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      order (ASC, $$169)
                                                       -- STABLE_SORT [$$169(ASC)]  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          project ([$$165, $$phone_substr, $$135, $$o, $$170, $$169])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              left outer join (eq($$156, $$163))
                                                               -- HYBRID_HASH_JOIN [$$156][$$163]  |PARTITIONED|
+                                                                exchange
                                                                 -- HASH_PARTITION_EXCHANGE [$$156]  |PARTITIONED|
+                                                                  running-aggregate [$$169] <- [create-query-uid()]
                                                                   -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                                    assign [$$135] <- [{"c_acctbal": $$165, "c_custkey": $$156, "cntrycode": $$phone_substr}]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      project ([$$165, $$phone_substr, $$156])
                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          join (eq($$158, $$phone_substr))
                                                                           -- HYBRID_HASH_JOIN [$$phone_substr][$$158]  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              assign [$$phone_substr, $$165] <- [substring($$c.getField(4), 0, 2), $$c.getField(5)] project: [$$165, $$phone_substr, $$156]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                                                                  data-scan []<-[$$156, $$c] <- tpch.Customer
+                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      empty-tuple-source
                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                            exchange
                                                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                              unnest $$158 <- scan-collection(array: [ "23", "13", "17", "29", "18", "30", "31" ])
                                                                               -- UNNEST  |UNPARTITIONED|
+                                                                                empty-tuple-source
                                                                                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                                exchange
                                                                 -- HASH_PARTITION_EXCHANGE [$$163]  |PARTITIONED|
+                                                                  assign [$$170, $$163] <- [true, $$o.getField(1)]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    project ([$$o])
                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                                                        data-scan []<-[$$157, $$o] <- tpch.Orders
+                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-issue601.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-issue601.plan
index 2c79baa..bea6883 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-issue601.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-issue601.plan
@@ -1,21 +1,36 @@
+distribute result [$$46]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$46] <- [{"l_linenumber": $$l_linenumber, "count_order": $$50}] project: [$$46]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- SORT_GROUP_BY[$$52]  |PARTITIONED|
-                {
+        group by ([$$l_linenumber := $$52]) decor ([]) {
+                  aggregate [$$50] <- [agg-sql-sum($$51)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$52]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$52]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$49]  |PARTITIONED|
-                    {
+            group by ([$$52 := $$49]) decor ([]) {
+                      aggregate [$$51] <- [agg-sql-count(1)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$49]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$49])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                    data-scan []<-[$$48, $$49, $$l] <- tpch.LineItem
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue3316.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue3316.plan
index 5ffc3f8..b869d74 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue3316.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue3316.plan
@@ -1,900 +1,1755 @@
+distribute result [$$192]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    distinct ([$$192])
     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$192)
         -- STABLE_SORT [$$192(ASC)]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$192]  |PARTITIONED|
+            assign [$$192] <- [object-concat-strict(to-object-var-str($$116), {"sub_query1": $$156, "sub_query2": $$191})] project: [$$192]
             -- ASSIGN  |PARTITIONED|
+              project ([$$191, $$116, $$156])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- PRE_CLUSTERED_GROUP_BY[$$227]  |PARTITIONED|
-                          {
+                  group by ([$$318 := $$227]) decor ([$$116; $$156]) {
+                            aggregate [$$191] <- [listify($$190)]
                             -- AGGREGATE  |LOCAL|
+                              select (not(is-missing($$317)))
                               -- STREAM_SELECT  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                          }
+                         }
+                  -- PRE_CLUSTERED_GROUP_BY[$$227]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$116, $$156, $$190, $$317, $$227])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          left outer join (eq($$227, $$388))
                           -- HYBRID_HASH_JOIN [$$227][$$388]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$193]  |PARTITIONED|
-                                      {
+                              group by ([$$227 := $$193]) decor ([$$116]) {
+                                        aggregate [$$156] <- [listify($$155)]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$226)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$193]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$193)
                                   -- STABLE_SORT [$$193(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$116, $$155, $$226, $$193])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          left outer join (eq($$193, $$240))
                                           -- HYBRID_HASH_JOIN [$$193][$$240]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$193]  |PARTITIONED|
+                                              assign [$$116] <- [{"x_id": $$T0.getField("x_id")}] project: [$$116, $$193]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                  data-scan []<-[$$193, $$T0] <- test.collection0
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$240]  |PARTITIONED|
+                                              assign [$$226, $$155] <- [true, {"u": $$213}] project: [$$155, $$226, $$240]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$240, $$213])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    join (eq($$199, $$126))
                                                     -- HYBRID_HASH_JOIN [$$126][$$199]  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        select ($$151) project: [$$240, $$213, $$126]
                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                          project ([$$151, $$240, $$213, $$126])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- PRE_CLUSTERED_GROUP_BY[$$225, $$194]  |PARTITIONED|
-                                                                      {
+                                                              group by ([$$240 := $$225; $$241 := $$194]) decor ([$$213; $$126]) {
+                                                                        aggregate [$$151] <- [non-empty-stream()]
                                                                         -- AGGREGATE  |LOCAL|
+                                                                          select (not(is-missing($$239)))
                                                                           -- STREAM_SELECT  |LOCAL|
+                                                                            nested tuple source
                                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                      }
+                                                                     }
+                                                              -- PRE_CLUSTERED_GROUP_BY[$$225, $$194]  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  order (ASC, $$225) (ASC, $$194)
                                                                   -- STABLE_SORT [$$225(ASC), $$194(ASC)]  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      project ([$$213, $$126, $$239, $$225, $$194])
                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          left outer join (and(eq($$225, $$254), eq($$194, $$255)))
                                                                           -- HYBRID_HASH_JOIN [$$225, $$194][$$254, $$255]  |PARTITIONED|
+                                                                            exchange
                                                                             -- HASH_PARTITION_EXCHANGE [$$225, $$194]  |PARTITIONED|
+                                                                              project ([$$213, $$126, $$225, $$194])
                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  join (eq($$207, $$223))
                                                                                   -- HYBRID_HASH_JOIN [$$223][$$207]  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      assign [$$225, $$223] <- [$$409, $$417] project: [$$225, $$223]
                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                          replicate
                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                              assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                  replicate
                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                      assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                          -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                          data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                              empty-tuple-source
                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- HASH_PARTITION_EXCHANGE [$$207]  |PARTITIONED|
+                                                                                      select (eq($$H.getField("to_u"), "aaaaa")) project: [$$213, $$126, $$194, $$207]
                                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                                        assign [$$213, $$126, $$207] <- [$$H.getField("u"), $$H.getField("a"), $$H.getField("y_id")]
                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                          assign [$$194, $$H] <- [$$411, $$413] project: [$$194, $$H]
                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              replicate
                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                  -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                  data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                      empty-tuple-source
                                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              assign [$$239] <- [true]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                select (eq($$233, $#7)) project: [$$254, $$255]
                                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                                  unnest $#7 <- scan-collection($$148) project: [$$254, $$255, $$233, $#7]
                                                                                   -- UNNEST  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$238, $$235]  |PARTITIONED|
-                                                                                              {
+                                                                                      group by ([$$254 := $$238; $$255 := $$235]) decor ([$$233]) {
+                                                                                                aggregate [$$148] <- [listify($$203)]
                                                                                                 -- AGGREGATE  |LOCAL|
+                                                                                                  aggregate [$$203] <- [agg-sql-max($$145)]
                                                                                                   -- AGGREGATE  |LOCAL|
+                                                                                                    select (not(is-missing($$253)))
                                                                                                     -- STREAM_SELECT  |LOCAL|
+                                                                                                      nested tuple source
                                                                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                              }
+                                                                                             }
+                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$238, $$235]  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                          order (ASC, $$238) (ASC, $$235)
                                                                                           -- STABLE_SORT [$$238(ASC), $$235(ASC)]  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              project ([$$233, $$145, $$253, $$238, $$235])
                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                  left outer join (and(eq($$238, $$252), eq($$235, $$249)))
                                                                                                   -- HYBRID_HASH_JOIN [$$238, $$235][$$252, $$249]  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                      assign [$$233, $$238, $$235] <- [$$422, $$425, $$426] project: [$$233, $$238, $$235]
                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                          replicate
                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- HASH_PARTITION_EXCHANGE [$$425, $$426]  |PARTITIONED|
+                                                                                                              project ([$$422, $$425, $$426])
                                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                exchange
                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                  join (eq($$427, $$428))
                                                                                                                   -- HYBRID_HASH_JOIN [$$428][$$427]  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                      assign [$$425, $$428] <- [$$409, $$417] project: [$$425, $$428]
                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                        exchange
                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                          replicate
                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                              assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                exchange
                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                  replicate
                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                    exchange
                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                      assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                        exchange
                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                          -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                          data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                            exchange
                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                              empty-tuple-source
                                                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$427]  |PARTITIONED|
+                                                                                                                      select (eq($$430.getField("to_u"), "aaaaa")) project: [$$422, $$426, $$427]
                                                                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                        exchange
                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                          replicate
                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                              assign [$$427, $$422] <- [$$430.getField("y_id"), $$430.getField("b")]
                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                assign [$$426, $$430] <- [$$411, $$413] project: [$$426, $$430]
                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                  exchange
                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                    replicate
                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                      exchange
                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                        -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                        data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                          exchange
                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                            empty-tuple-source
                                                                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- HASH_PARTITION_EXCHANGE [$$252, $$249]  |PARTITIONED|
+                                                                                                      assign [$$253] <- [true]
                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                        project ([$$145, $$252, $$249])
                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                          exchange
                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                            join (eq($$198, $$135))
                                                                                                             -- HYBRID_HASH_JOIN [$$135][$$198]  |PARTITIONED|
+                                                                                                              exchange
                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                project ([$$145, $$252, $$249, $$135])
                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                  exchange
                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                    join (eq($$210, $$243))
                                                                                                                     -- HYBRID_HASH_JOIN [$$243][$$210]  |PARTITIONED|
+                                                                                                                      exchange
                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                        assign [$$252, $$249, $$243] <- [$$435, $$436, $$445] project: [$$252, $$249, $$243]
                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                          exchange
                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                            replicate
                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                              exchange
                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                project ([$$435, $$436, $$445])
                                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                  exchange
                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                    join (eq($$448, $$445))
                                                                                                                                     -- HYBRID_HASH_JOIN [$$445][$$448]  |PARTITIONED|
+                                                                                                                                      exchange
                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                        assign [$$435, $$445] <- [$$409, $$417] project: [$$435, $$445]
                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                          exchange
                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                            replicate
                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                              exchange
                                                                                                                                               -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                  exchange
                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                    replicate
                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                      exchange
                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                        assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                          exchange
                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                            -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                            data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                              exchange
                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                empty-tuple-source
                                                                                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                      exchange
                                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$448]  |PARTITIONED|
+                                                                                                                                        select (eq($$450.getField("to_u"), "aaaaa")) project: [$$436, $$448]
                                                                                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                          exchange
                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                            replicate
                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                              exchange
                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                assign [$$448] <- [$$450.getField("y_id")]
                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                  assign [$$436, $$450] <- [$$411, $$413] project: [$$436, $$450]
                                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                                    exchange
                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                      replicate
                                                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                                                        exchange
                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                          -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                          data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                            exchange
                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                              empty-tuple-source
                                                                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                      exchange
                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$210]  |PARTITIONED|
+                                                                                                                        select (eq($$L.getField("to_u"), "aaaaa")) project: [$$145, $$135, $$210]
                                                                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                          assign [$$135, $$210, $$145] <- [$$L.getField("a"), $$L.getField("y_id"), $$L.getField("b")]
                                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                                            assign [$$L] <- [$$441] project: [$$L]
                                                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                                                              exchange
                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                replicate
                                                                                                                                 -- REPLICATE  |PARTITIONED|
+                                                                                                                                  exchange
                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                    assign [$$447, $$441] <- [$$411, $$413] project: [$$441]
                                                                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                                                                      exchange
                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                        replicate
                                                                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                                                                          exchange
                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                            -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                            data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                              exchange
                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                empty-tuple-source
                                                                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                              exchange
                                                                                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                                unnest $$198 <- scan-collection(array: [ 66, 67, 26, 12, 13 ])
                                                                                                                 -- UNNEST  |UNPARTITIONED|
+                                                                                                                  empty-tuple-source
                                                                                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        unnest $$199 <- scan-collection(array: [ 66, 67, 26, 12, 13 ])
                                                         -- UNNEST  |UNPARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$388]  |PARTITIONED|
+                              assign [$$317, $$190] <- [true, {"u": $$219}] project: [$$190, $$317, $$388]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$388, $$219])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (eq($$202, $$162))
                                     -- HYBRID_HASH_JOIN [$$162][$$202]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        project ([$$388, $$219, $$162])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            join (eq($$201, $$165))
                                             -- HYBRID_HASH_JOIN [$$165][$$201]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                select ($$186) project: [$$388, $$219, $$162, $$165]
                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                  project ([$$186, $$388, $$162, $$165, $$219])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- PRE_CLUSTERED_GROUP_BY[$$256, $$196]  |PARTITIONED|
-                                                              {
+                                                      group by ([$$388 := $$256; $$389 := $$196]) decor ([$$162; $$165; $$219]) {
+                                                                aggregate [$$186] <- [non-empty-stream()]
                                                                 -- AGGREGATE  |LOCAL|
+                                                                  select (not(is-missing($$387)))
                                                                   -- STREAM_SELECT  |LOCAL|
+                                                                    nested tuple source
                                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                              }
+                                                             }
+                                                      -- PRE_CLUSTERED_GROUP_BY[$$256, $$196]  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          order (ASC, $$256) (ASC, $$196)
                                                           -- STABLE_SORT [$$256(ASC), $$196(ASC)]  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              project ([$$219, $$162, $$165, $$387, $$256, $$196])
                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  left outer join (and(eq($$256, $$459), eq($$196, $$460)))
                                                                   -- HYBRID_HASH_JOIN [$$256, $$196][$$459, $$460]  |PARTITIONED|
+                                                                    exchange
                                                                     -- HASH_PARTITION_EXCHANGE [$$256, $$196]  |PARTITIONED|
+                                                                      project ([$$219, $$162, $$165, $$256, $$196])
                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          join (eq($$214, $$260))
                                                                           -- HYBRID_HASH_JOIN [$$260][$$214]  |PARTITIONED|
+                                                                            exchange
                                                                             -- HASH_PARTITION_EXCHANGE [$$260]  |PARTITIONED|
-                                                                              -- PRE_CLUSTERED_GROUP_BY[$$257]  |PARTITIONED|
-                                                                                      {
+                                                                              group by ([$$256 := $$257]) decor ([$$260]) {
+                                                                                        aggregate [] <- []
                                                                                         -- AGGREGATE  |LOCAL|
+                                                                                          select (not(is-missing($$262)))
                                                                                           -- STREAM_SELECT  |LOCAL|
+                                                                                            nested tuple source
                                                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                      }
+                                                                                     }
+                                                                              -- PRE_CLUSTERED_GROUP_BY[$$257]  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  order (ASC, $$257)
                                                                                   -- STABLE_SORT [$$257(ASC)]  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      project ([$$260, $$262, $$257])
                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                          left outer join (eq($$257, $$261))
                                                                                           -- HYBRID_HASH_JOIN [$$257][$$261]  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              assign [$$260, $$257] <- [$$391, $$399] project: [$$260, $$257]
                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                  replicate
                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- HASH_PARTITION_EXCHANGE [$$399]  |PARTITIONED|
+                                                                                                      replicate
                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                          assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                              -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                              data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                exchange
                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                  empty-tuple-source
                                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- HASH_PARTITION_EXCHANGE [$$261]  |PARTITIONED|
+                                                                                              assign [$$262] <- [true]
                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                project ([$$261])
                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    join (eq($$265, $$266))
                                                                                                     -- HYBRID_HASH_JOIN [$$266][$$265]  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                        select ($$267) project: [$$261, $$266]
                                                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                                                          project ([$$267, $$261, $$266])
                                                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                              -- PRE_CLUSTERED_GROUP_BY[$$268, $$270]  |PARTITIONED|
-                                                                                                                      {
+                                                                                                              group by ([$$261 := $$268; $$269 := $$270]) decor ([$$266]) {
+                                                                                                                        aggregate [$$267] <- [non-empty-stream()]
                                                                                                                         -- AGGREGATE  |LOCAL|
+                                                                                                                          select (not(is-missing($$280)))
                                                                                                                           -- STREAM_SELECT  |LOCAL|
+                                                                                                                            nested tuple source
                                                                                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                      }
+                                                                                                                     }
+                                                                                                              -- PRE_CLUSTERED_GROUP_BY[$$268, $$270]  |PARTITIONED|
+                                                                                                                exchange
                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                  order (ASC, $$268) (ASC, $$270)
                                                                                                                   -- STABLE_SORT [$$268(ASC), $$270(ASC)]  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                      project ([$$266, $$280, $$268, $$270])
                                                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                        exchange
                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                          left outer join (and(eq($$268, $$278), eq($$270, $$279)))
                                                                                                                           -- HYBRID_HASH_JOIN [$$268, $$270][$$278, $$279]  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                              assign [$$266, $$268, $$270] <- [$$407, $$409, $$411] project: [$$266, $$268, $$270]
                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                exchange
                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                  replicate
                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                    exchange
                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$409, $$411]  |PARTITIONED|
+                                                                                                                                      project ([$$407, $$409, $$411])
                                                                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                        exchange
                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                          join (eq($$418, $$417))
                                                                                                                                           -- HYBRID_HASH_JOIN [$$417][$$418]  |PARTITIONED|
+                                                                                                                                            exchange
                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                              replicate
                                                                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                                                                exchange
                                                                                                                                                 -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                  assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                                    exchange
                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                      replicate
                                                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                                                        exchange
                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                          assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                                                                            exchange
                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                              -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                              data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                exchange
                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                  empty-tuple-source
                                                                                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                            exchange
                                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$418]  |PARTITIONED|
+                                                                                                                                              select (eq($$413.getField("to_u"), "aaaaa")) project: [$$407, $$411, $$418]
                                                                                                                                               -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                assign [$$418, $$407] <- [$$413.getField("y_id"), $$413.getField("a")]
                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                  exchange
                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                    replicate
                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                      exchange
                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                        -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                        data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                          exchange
                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                            empty-tuple-source
                                                                                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                              assign [$$280] <- [true]
                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                select (eq($$281, $$282)) project: [$$278, $$279]
                                                                                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                  unnest $$282 <- scan-collection($$283) project: [$$278, $$279, $$281, $$282]
                                                                                                                                   -- UNNEST  |PARTITIONED|
+                                                                                                                                    exchange
                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$284, $$285]  |PARTITIONED|
-                                                                                                                                              {
+                                                                                                                                      group by ([$$278 := $$284; $$279 := $$285]) decor ([$$281]) {
+                                                                                                                                                aggregate [$$283] <- [listify($$315)]
                                                                                                                                                 -- AGGREGATE  |LOCAL|
+                                                                                                                                                  aggregate [$$315] <- [agg-sql-max($$297)]
                                                                                                                                                   -- AGGREGATE  |LOCAL|
+                                                                                                                                                    select (not(is-missing($$296)))
                                                                                                                                                     -- STREAM_SELECT  |LOCAL|
+                                                                                                                                                      nested tuple source
                                                                                                                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                                              }
+                                                                                                                                             }
+                                                                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$284, $$285]  |PARTITIONED|
+                                                                                                                                        exchange
                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                          order (ASC, $$284) (ASC, $$285)
                                                                                                                                           -- STABLE_SORT [$$284(ASC), $$285(ASC)]  |PARTITIONED|
+                                                                                                                                            exchange
                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                              project ([$$281, $$297, $$296, $$284, $$285])
                                                                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                exchange
                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                  left outer join (and(eq($$284, $$294), eq($$285, $$295)))
                                                                                                                                                   -- HYBRID_HASH_JOIN [$$284, $$285][$$294, $$295]  |PARTITIONED|
+                                                                                                                                                    exchange
                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                      assign [$$281, $$284, $$285] <- [$$422, $$425, $$426] project: [$$281, $$284, $$285]
                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                        exchange
                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                          replicate
                                                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                                                            exchange
                                                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$425, $$426]  |PARTITIONED|
+                                                                                                                                                              project ([$$422, $$425, $$426])
                                                                                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                exchange
                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                  join (eq($$427, $$428))
                                                                                                                                                                   -- HYBRID_HASH_JOIN [$$428][$$427]  |PARTITIONED|
+                                                                                                                                                                    exchange
                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                      assign [$$425, $$428] <- [$$409, $$417] project: [$$425, $$428]
                                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                        exchange
                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                          replicate
                                                                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                            exchange
                                                                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                                              assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                exchange
                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                  replicate
                                                                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                    exchange
                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                      assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                        exchange
                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                          -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                                                          data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                            exchange
                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                              empty-tuple-source
                                                                                                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                    exchange
                                                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$427]  |PARTITIONED|
+                                                                                                                                                                      select (eq($$430.getField("to_u"), "aaaaa")) project: [$$422, $$426, $$427]
                                                                                                                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                        exchange
                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                          replicate
                                                                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                            exchange
                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                              assign [$$427, $$422] <- [$$430.getField("y_id"), $$430.getField("b")]
                                                                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                assign [$$426, $$430] <- [$$411, $$413] project: [$$426, $$430]
                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                  exchange
                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                    replicate
                                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                      exchange
                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                        -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                        data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                          exchange
                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                            empty-tuple-source
                                                                                                                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                    exchange
                                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$294, $$295]  |PARTITIONED|
+                                                                                                                                                      assign [$$296] <- [true]
                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                        project ([$$297, $$294, $$295])
                                                                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                          exchange
                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                            join (eq($$301, $$302))
                                                                                                                                                             -- HYBRID_HASH_JOIN [$$302][$$301]  |PARTITIONED|
+                                                                                                                                                              exchange
                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                project ([$$297, $$294, $$295, $$302])
                                                                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                  exchange
                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                    join (eq($$303, $$304))
                                                                                                                                                                     -- HYBRID_HASH_JOIN [$$304][$$303]  |PARTITIONED|
+                                                                                                                                                                      exchange
                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                        assign [$$294, $$295, $$304] <- [$$435, $$436, $$445] project: [$$294, $$295, $$304]
                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                          exchange
                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                            replicate
                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                              exchange
                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                project ([$$435, $$436, $$445])
                                                                                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                  exchange
                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                    join (eq($$448, $$445))
                                                                                                                                                                                     -- HYBRID_HASH_JOIN [$$445][$$448]  |PARTITIONED|
+                                                                                                                                                                                      exchange
                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                        assign [$$435, $$445] <- [$$409, $$417] project: [$$435, $$445]
                                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                          exchange
                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                            replicate
                                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                              exchange
                                                                                                                                                                                               -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                                                                assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                  exchange
                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                    replicate
                                                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                      exchange
                                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                        assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                          exchange
                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                            -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                                                                            data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                              exchange
                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                empty-tuple-source
                                                                                                                                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                      exchange
                                                                                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$448]  |PARTITIONED|
+                                                                                                                                                                                        select (eq($$450.getField("to_u"), "aaaaa")) project: [$$436, $$448]
                                                                                                                                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                          exchange
                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                            replicate
                                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                              exchange
                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                assign [$$448] <- [$$450.getField("y_id")]
                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                  assign [$$436, $$450] <- [$$411, $$413] project: [$$436, $$450]
                                                                                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                    exchange
                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                      replicate
                                                                                                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                        exchange
                                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                          -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                                          data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                            exchange
                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                              empty-tuple-source
                                                                                                                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                      exchange
                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                        assign [$$297, $$302, $$303] <- [$$438, $$443, $$444] project: [$$297, $$302, $$303]
                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                          exchange
                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                            replicate
                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                              exchange
                                                                                                                                                                               -- HASH_PARTITION_EXCHANGE [$$444]  |PARTITIONED|
+                                                                                                                                                                                select (eq($$441.getField("to_u"), "aaaaa")) project: [$$438, $$443, $$444]
                                                                                                                                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                  assign [$$444, $$443, $$438] <- [$$441.getField("y_id"), $$441.getField("a"), $$441.getField("b")]
                                                                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                    exchange
                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                      replicate
                                                                                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                        exchange
                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                          assign [$$447, $$441] <- [$$411, $$413] project: [$$441]
                                                                                                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                            exchange
                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                              replicate
                                                                                                                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                exchange
                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                  -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                                  data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                    exchange
                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                      empty-tuple-source
                                                                                                                                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                              exchange
                                                                                                                                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                unnest $$301 <- scan-collection(array: [ 66, 67, 26, 12, 13 ])
                                                                                                                                                                 -- UNNEST  |UNPARTITIONED|
+                                                                                                                                                                  empty-tuple-source
                                                                                                                                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                                                                      exchange
                                                                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                        unnest $$265 <- scan-collection(array: [ 66, 67, 26, 12, 13 ])
                                                                                                         -- UNNEST  |UNPARTITIONED|
+                                                                                                          empty-tuple-source
                                                                                                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                                            exchange
                                                                             -- HASH_PARTITION_EXCHANGE [$$214]  |PARTITIONED|
+                                                                              assign [$$219, $$165, $$162, $$214] <- [$$H.getField("u"), $$H.getField("posi"), $$H.getField("a"), $$H.getField("y_id")] project: [$$219, $$162, $$165, $$196, $$214]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                assign [$$196, $$H] <- [$$411, $$413] project: [$$196, $$H]
                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    replicate
                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                        -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                        data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            empty-tuple-source
                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      assign [$$387] <- [true]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        select (eq($$324, $#11)) project: [$$459, $$460]
                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                          unnest $#11 <- scan-collection($$183) project: [$$459, $$460, $$324, $#11]
                                                                           -- UNNEST  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                              -- PRE_CLUSTERED_GROUP_BY[$$327, $$326]  |PARTITIONED|
-                                                                                      {
+                                                                              group by ([$$459 := $$327; $$460 := $$326]) decor ([$$324]) {
+                                                                                        aggregate [$$183] <- [listify($$204)]
                                                                                         -- AGGREGATE  |LOCAL|
+                                                                                          aggregate [$$204] <- [agg-sql-max($$180)]
                                                                                           -- AGGREGATE  |LOCAL|
+                                                                                            select (not(is-missing($$458)))
                                                                                             -- STREAM_SELECT  |LOCAL|
+                                                                                              nested tuple source
                                                                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                      }
+                                                                                     }
+                                                                              -- PRE_CLUSTERED_GROUP_BY[$$327, $$326]  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  order (ASC, $$327) (ASC, $$326)
                                                                                   -- STABLE_SORT [$$327(ASC), $$326(ASC)]  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      project ([$$324, $$180, $$458, $$327, $$326])
                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                          left outer join (and(eq($$327, $$398), eq($$326, $$397)))
                                                                                           -- HYBRID_HASH_JOIN [$$327, $$326][$$398, $$397]  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- HASH_PARTITION_EXCHANGE [$$327, $$326]  |PARTITIONED|
+                                                                                              project ([$$324, $$327, $$326])
                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                  join (eq($$319, $$320))
                                                                                                   -- HYBRID_HASH_JOIN [$$320][$$319]  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- HASH_PARTITION_EXCHANGE [$$320]  |PARTITIONED|
-                                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$328]  |PARTITIONED|
-                                                                                                              {
+                                                                                                      group by ([$$327 := $$328]) decor ([$$320]) {
+                                                                                                                aggregate [] <- []
                                                                                                                 -- AGGREGATE  |LOCAL|
+                                                                                                                  select (not(is-missing($$332)))
                                                                                                                   -- STREAM_SELECT  |LOCAL|
+                                                                                                                    nested tuple source
                                                                                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                              }
+                                                                                                             }
+                                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$328]  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                          order (ASC, $$328)
                                                                                                           -- STABLE_SORT [$$328(ASC)]  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                              project ([$$320, $$332, $$328])
                                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                exchange
                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                  left outer join (eq($$328, $$331))
                                                                                                                   -- HYBRID_HASH_JOIN [$$328][$$331]  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                      assign [$$320, $$328] <- [$$391, $$399] project: [$$320, $$328]
                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                        exchange
                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                          replicate
                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$399]  |PARTITIONED|
+                                                                                                                              replicate
                                                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                                                exchange
                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                  assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                    exchange
                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                      -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                      data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                        exchange
                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                          empty-tuple-source
                                                                                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$331]  |PARTITIONED|
+                                                                                                                      assign [$$332] <- [true]
                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                        project ([$$331])
                                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                          exchange
                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                            join (eq($$335, $$336))
                                                                                                                             -- HYBRID_HASH_JOIN [$$336][$$335]  |PARTITIONED|
+                                                                                                                              exchange
                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                select ($$337) project: [$$331, $$336]
                                                                                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                  project ([$$337, $$331, $$336])
                                                                                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                    exchange
                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$338, $$340]  |PARTITIONED|
-                                                                                                                                              {
+                                                                                                                                      group by ([$$331 := $$338; $$339 := $$340]) decor ([$$336]) {
+                                                                                                                                                aggregate [$$337] <- [non-empty-stream()]
                                                                                                                                                 -- AGGREGATE  |LOCAL|
+                                                                                                                                                  select (not(is-missing($$350)))
                                                                                                                                                   -- STREAM_SELECT  |LOCAL|
+                                                                                                                                                    nested tuple source
                                                                                                                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                                              }
+                                                                                                                                             }
+                                                                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$338, $$340]  |PARTITIONED|
+                                                                                                                                        exchange
                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                          order (ASC, $$338) (ASC, $$340)
                                                                                                                                           -- STABLE_SORT [$$338(ASC), $$340(ASC)]  |PARTITIONED|
+                                                                                                                                            exchange
                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                              project ([$$336, $$350, $$338, $$340])
                                                                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                exchange
                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                  left outer join (and(eq($$338, $$348), eq($$340, $$349)))
                                                                                                                                                   -- HYBRID_HASH_JOIN [$$338, $$340][$$348, $$349]  |PARTITIONED|
+                                                                                                                                                    exchange
                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                      assign [$$336, $$338, $$340] <- [$$407, $$409, $$411] project: [$$336, $$338, $$340]
                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                        exchange
                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                          replicate
                                                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                                                            exchange
                                                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$409, $$411]  |PARTITIONED|
+                                                                                                                                                              project ([$$407, $$409, $$411])
                                                                                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                exchange
                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                  join (eq($$418, $$417))
                                                                                                                                                                   -- HYBRID_HASH_JOIN [$$417][$$418]  |PARTITIONED|
+                                                                                                                                                                    exchange
                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                      replicate
                                                                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                        exchange
                                                                                                                                                                         -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                                          assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                            exchange
                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                              replicate
                                                                                                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                exchange
                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                  assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                    exchange
                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                      -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                                                      data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                        exchange
                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                          empty-tuple-source
                                                                                                                                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                    exchange
                                                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$418]  |PARTITIONED|
+                                                                                                                                                                      select (eq($$413.getField("to_u"), "aaaaa")) project: [$$407, $$411, $$418]
                                                                                                                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                        assign [$$418, $$407] <- [$$413.getField("y_id"), $$413.getField("a")]
                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                          exchange
                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                            replicate
                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                              exchange
                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                  exchange
                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                    empty-tuple-source
                                                                                                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                    exchange
                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                      assign [$$350] <- [true]
                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                        select (eq($$351, $$352)) project: [$$348, $$349]
                                                                                                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                          unnest $$352 <- scan-collection($$353) project: [$$348, $$349, $$351, $$352]
                                                                                                                                                           -- UNNEST  |PARTITIONED|
+                                                                                                                                                            exchange
                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                              -- PRE_CLUSTERED_GROUP_BY[$$354, $$355]  |PARTITIONED|
-                                                                                                                                                                      {
+                                                                                                                                                              group by ([$$348 := $$354; $$349 := $$355]) decor ([$$351]) {
+                                                                                                                                                                        aggregate [$$353] <- [listify($$385)]
                                                                                                                                                                         -- AGGREGATE  |LOCAL|
+                                                                                                                                                                          aggregate [$$385] <- [agg-sql-max($$367)]
                                                                                                                                                                           -- AGGREGATE  |LOCAL|
+                                                                                                                                                                            select (not(is-missing($$366)))
                                                                                                                                                                             -- STREAM_SELECT  |LOCAL|
+                                                                                                                                                                              nested tuple source
                                                                                                                                                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                                                                      }
+                                                                                                                                                                     }
+                                                                                                                                                              -- PRE_CLUSTERED_GROUP_BY[$$354, $$355]  |PARTITIONED|
+                                                                                                                                                                exchange
                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                  order (ASC, $$354) (ASC, $$355)
                                                                                                                                                                   -- STABLE_SORT [$$354(ASC), $$355(ASC)]  |PARTITIONED|
+                                                                                                                                                                    exchange
                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                      project ([$$351, $$367, $$366, $$354, $$355])
                                                                                                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                        exchange
                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                          left outer join (and(eq($$354, $$364), eq($$355, $$365)))
                                                                                                                                                                           -- HYBRID_HASH_JOIN [$$354, $$355][$$364, $$365]  |PARTITIONED|
+                                                                                                                                                                            exchange
                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                              assign [$$351, $$354, $$355] <- [$$422, $$425, $$426] project: [$$351, $$354, $$355]
                                                                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                exchange
                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                  replicate
                                                                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                    exchange
                                                                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$425, $$426]  |PARTITIONED|
+                                                                                                                                                                                      project ([$$422, $$425, $$426])
                                                                                                                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                        exchange
                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                          join (eq($$427, $$428))
                                                                                                                                                                                           -- HYBRID_HASH_JOIN [$$428][$$427]  |PARTITIONED|
+                                                                                                                                                                                            exchange
                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                              assign [$$425, $$428] <- [$$409, $$417] project: [$$425, $$428]
                                                                                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                exchange
                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                  replicate
                                                                                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                    exchange
                                                                                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                                                                      assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                        exchange
                                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                          replicate
                                                                                                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                            exchange
                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                              assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                  -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                                                                                  data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                    exchange
                                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                      empty-tuple-source
                                                                                                                                                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                            exchange
                                                                                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$427]  |PARTITIONED|
+                                                                                                                                                                                              select (eq($$430.getField("to_u"), "aaaaa")) project: [$$422, $$426, $$427]
                                                                                                                                                                                               -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                                exchange
                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                  replicate
                                                                                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                    exchange
                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                      assign [$$427, $$422] <- [$$430.getField("y_id"), $$430.getField("b")]
                                                                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                        assign [$$426, $$430] <- [$$411, $$413] project: [$$426, $$430]
                                                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                          exchange
                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                            replicate
                                                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                              exchange
                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                                                data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                    empty-tuple-source
                                                                                                                                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                            exchange
                                                                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$364, $$365]  |PARTITIONED|
+                                                                                                                                                                              assign [$$366] <- [true]
                                                                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                project ([$$367, $$364, $$365])
                                                                                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                  exchange
                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                    join (eq($$371, $$372))
                                                                                                                                                                                     -- HYBRID_HASH_JOIN [$$372][$$371]  |PARTITIONED|
+                                                                                                                                                                                      exchange
                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                        project ([$$367, $$364, $$365, $$372])
                                                                                                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                          exchange
                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                            join (eq($$373, $$374))
                                                                                                                                                                                             -- HYBRID_HASH_JOIN [$$374][$$373]  |PARTITIONED|
+                                                                                                                                                                                              exchange
                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                assign [$$364, $$365, $$374] <- [$$435, $$436, $$445] project: [$$364, $$365, $$374]
                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                  exchange
                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                    replicate
                                                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                      exchange
                                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                        project ([$$435, $$436, $$445])
                                                                                                                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                                          exchange
                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                            join (eq($$448, $$445))
                                                                                                                                                                                                             -- HYBRID_HASH_JOIN [$$445][$$448]  |PARTITIONED|
+                                                                                                                                                                                                              exchange
                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                assign [$$435, $$445] <- [$$409, $$417] project: [$$435, $$445]
                                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                    replicate
                                                                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                      exchange
                                                                                                                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                                                                                        assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                          exchange
                                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                            replicate
                                                                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                              exchange
                                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                                    -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                                                                                                    data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                                                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                                      exchange
                                                                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                        empty-tuple-source
                                                                                                                                                                                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                                              exchange
                                                                                                                                                                                                               -- HASH_PARTITION_EXCHANGE [$$448]  |PARTITIONED|
+                                                                                                                                                                                                                select (eq($$450.getField("to_u"), "aaaaa")) project: [$$436, $$448]
                                                                                                                                                                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                    replicate
                                                                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                      exchange
                                                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                        assign [$$448] <- [$$450.getField("y_id")]
                                                                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                          assign [$$436, $$450] <- [$$411, $$413] project: [$$436, $$450]
                                                                                                                                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                            exchange
                                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                              replicate
                                                                                                                                                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                                  -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                                                                  data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                                                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                                    exchange
                                                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                      empty-tuple-source
                                                                                                                                                                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                              exchange
                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                assign [$$367, $$372, $$373] <- [$$438, $$443, $$444] project: [$$367, $$372, $$373]
                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                  exchange
                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                    replicate
                                                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                      exchange
                                                                                                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$444]  |PARTITIONED|
+                                                                                                                                                                                                        select (eq($$441.getField("to_u"), "aaaaa")) project: [$$438, $$443, $$444]
                                                                                                                                                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                                          assign [$$444, $$443, $$438] <- [$$441.getField("y_id"), $$441.getField("a"), $$441.getField("b")]
                                                                                                                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                            exchange
                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                              replicate
                                                                                                                                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                  assign [$$447, $$441] <- [$$411, $$413] project: [$$441]
                                                                                                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                    exchange
                                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                      replicate
                                                                                                                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                        exchange
                                                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                          -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                                                          data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                            exchange
                                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                              empty-tuple-source
                                                                                                                                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                      exchange
                                                                                                                                                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                        unnest $$371 <- scan-collection(array: [ 66, 67, 26, 12, 13 ])
                                                                                                                                                                                         -- UNNEST  |UNPARTITIONED|
+                                                                                                                                                                                          empty-tuple-source
                                                                                                                                                                                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                                                                                              exchange
                                                                                                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                                                unnest $$335 <- scan-collection(array: [ 66, 67, 26, 12, 13 ])
                                                                                                                                 -- UNNEST  |UNPARTITIONED|
+                                                                                                                                  empty-tuple-source
                                                                                                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                                                                    exchange
                                                                                                     -- HASH_PARTITION_EXCHANGE [$$319]  |PARTITIONED|
+                                                                                                      assign [$$326, $$321, $$319, $$324] <- [$$426, $$430, $$427, $$422] project: [$$324, $$326, $$319]
                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                          replicate
                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                              assign [$$427, $$422] <- [$$430.getField("y_id"), $$430.getField("b")]
                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                assign [$$426, $$430] <- [$$411, $$413] project: [$$426, $$430]
                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                  exchange
                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                    replicate
                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                      exchange
                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                        -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                        data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                          exchange
                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                            empty-tuple-source
                                                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- HASH_PARTITION_EXCHANGE [$$398, $$397]  |PARTITIONED|
+                                                                                              assign [$$458] <- [true]
                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                project ([$$180, $$398, $$397])
                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    join (eq($$200, $$172))
                                                                                                     -- HYBRID_HASH_JOIN [$$172][$$200]  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                        project ([$$180, $$398, $$397, $$172])
                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                          exchange
                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                            join (eq($$216, $$391))
                                                                                                             -- HYBRID_HASH_JOIN [$$391][$$216]  |PARTITIONED|
+                                                                                                              exchange
                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                project ([$$398, $$397, $$391])
                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                  exchange
                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                    join (eq($$390, $$391))
                                                                                                                     -- HYBRID_HASH_JOIN [$$391][$$390]  |PARTITIONED|
+                                                                                                                      exchange
                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$391]  |PARTITIONED|
-                                                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$399]  |PARTITIONED|
-                                                                                                                                {
+                                                                                                                        group by ([$$398 := $$399]) decor ([$$391]) {
+                                                                                                                                  aggregate [] <- []
                                                                                                                                   -- AGGREGATE  |LOCAL|
+                                                                                                                                    select (not(is-missing($$403)))
                                                                                                                                     -- STREAM_SELECT  |LOCAL|
+                                                                                                                                      nested tuple source
                                                                                                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                                }
+                                                                                                                               }
+                                                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$399]  |PARTITIONED|
+                                                                                                                          exchange
                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                            order (ASC, $$399)
                                                                                                                             -- STABLE_SORT [$$399(ASC)]  |PARTITIONED|
+                                                                                                                              exchange
                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                project ([$$391, $$403, $$399])
                                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                  exchange
                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                    left outer join (eq($$399, $$402))
                                                                                                                                     -- HYBRID_HASH_JOIN [$$399][$$402]  |PARTITIONED|
+                                                                                                                                      exchange
                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                        replicate
                                                                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                                                                          exchange
                                                                                                                                           -- HASH_PARTITION_EXCHANGE [$$399]  |PARTITIONED|
+                                                                                                                                            replicate
                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                              exchange
                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                  exchange
                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                    -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                    data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                      exchange
                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                        empty-tuple-source
                                                                                                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                      exchange
                                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$402]  |PARTITIONED|
+                                                                                                                                        assign [$$403] <- [true]
                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                          project ([$$402])
                                                                                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                            exchange
                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                              join (eq($$406, $$407))
                                                                                                                                               -- HYBRID_HASH_JOIN [$$407][$$406]  |PARTITIONED|
+                                                                                                                                                exchange
                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                  select ($$408) project: [$$402, $$407]
                                                                                                                                                   -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                    project ([$$408, $$402, $$407])
                                                                                                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                      exchange
                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$409, $$411]  |PARTITIONED|
-                                                                                                                                                                {
+                                                                                                                                                        group by ([$$402 := $$409; $$410 := $$411]) decor ([$$407]) {
+                                                                                                                                                                  aggregate [$$408] <- [non-empty-stream()]
                                                                                                                                                                   -- AGGREGATE  |LOCAL|
+                                                                                                                                                                    select (not(is-missing($$421)))
                                                                                                                                                                     -- STREAM_SELECT  |LOCAL|
+                                                                                                                                                                      nested tuple source
                                                                                                                                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                                                                }
+                                                                                                                                                               }
+                                                                                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$409, $$411]  |PARTITIONED|
+                                                                                                                                                          exchange
                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                            order (ASC, $$409) (ASC, $$411)
                                                                                                                                                             -- STABLE_SORT [$$409(ASC), $$411(ASC)]  |PARTITIONED|
+                                                                                                                                                              exchange
                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                project ([$$407, $$421, $$409, $$411])
                                                                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                  exchange
                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                    left outer join (and(eq($$409, $$419), eq($$411, $$420)))
                                                                                                                                                                     -- HYBRID_HASH_JOIN [$$409, $$411][$$419, $$420]  |PARTITIONED|
+                                                                                                                                                                      exchange
                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                        replicate
                                                                                                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                          exchange
                                                                                                                                                                           -- HASH_PARTITION_EXCHANGE [$$409, $$411]  |PARTITIONED|
+                                                                                                                                                                            project ([$$407, $$409, $$411])
                                                                                                                                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                              exchange
                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                join (eq($$418, $$417))
                                                                                                                                                                                 -- HYBRID_HASH_JOIN [$$417][$$418]  |PARTITIONED|
+                                                                                                                                                                                  exchange
                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                    replicate
                                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                      exchange
                                                                                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                                                        assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                          exchange
                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                            replicate
                                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                              exchange
                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                  exchange
                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                    -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                                                                    data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                      exchange
                                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                        empty-tuple-source
                                                                                                                                                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                  exchange
                                                                                                                                                                                   -- HASH_PARTITION_EXCHANGE [$$418]  |PARTITIONED|
+                                                                                                                                                                                    select (eq($$413.getField("to_u"), "aaaaa")) project: [$$407, $$411, $$418]
                                                                                                                                                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                      assign [$$418, $$407] <- [$$413.getField("y_id"), $$413.getField("a")]
                                                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                        exchange
                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                          replicate
                                                                                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                            exchange
                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                              -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                              data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                exchange
                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                  empty-tuple-source
                                                                                                                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                      exchange
                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                        assign [$$421] <- [true]
                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                          select (eq($$422, $$423)) project: [$$419, $$420]
                                                                                                                                                                           -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                            unnest $$423 <- scan-collection($$424) project: [$$419, $$420, $$422, $$423]
                                                                                                                                                                             -- UNNEST  |PARTITIONED|
+                                                                                                                                                                              exchange
                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                -- PRE_CLUSTERED_GROUP_BY[$$425, $$426]  |PARTITIONED|
-                                                                                                                                                                                        {
+                                                                                                                                                                                group by ([$$419 := $$425; $$420 := $$426]) decor ([$$422]) {
+                                                                                                                                                                                          aggregate [$$424] <- [listify($$456)]
                                                                                                                                                                                           -- AGGREGATE  |LOCAL|
+                                                                                                                                                                                            aggregate [$$456] <- [agg-sql-max($$438)]
                                                                                                                                                                                             -- AGGREGATE  |LOCAL|
+                                                                                                                                                                                              select (not(is-missing($$437)))
                                                                                                                                                                                               -- STREAM_SELECT  |LOCAL|
+                                                                                                                                                                                                nested tuple source
                                                                                                                                                                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                                                                                        }
+                                                                                                                                                                                       }
+                                                                                                                                                                                -- PRE_CLUSTERED_GROUP_BY[$$425, $$426]  |PARTITIONED|
+                                                                                                                                                                                  exchange
                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                    order (ASC, $$425) (ASC, $$426)
                                                                                                                                                                                     -- STABLE_SORT [$$425(ASC), $$426(ASC)]  |PARTITIONED|
+                                                                                                                                                                                      exchange
                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                        project ([$$422, $$438, $$437, $$425, $$426])
                                                                                                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                          exchange
                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                            left outer join (and(eq($$425, $$435), eq($$426, $$436)))
                                                                                                                                                                                             -- HYBRID_HASH_JOIN [$$425, $$426][$$435, $$436]  |PARTITIONED|
+                                                                                                                                                                                              exchange
                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                replicate
                                                                                                                                                                                                 -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                  exchange
                                                                                                                                                                                                   -- HASH_PARTITION_EXCHANGE [$$425, $$426]  |PARTITIONED|
+                                                                                                                                                                                                    project ([$$422, $$425, $$426])
                                                                                                                                                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                                      exchange
                                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                        join (eq($$427, $$428))
                                                                                                                                                                                                         -- HYBRID_HASH_JOIN [$$428][$$427]  |PARTITIONED|
+                                                                                                                                                                                                          exchange
                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                            assign [$$425, $$428] <- [$$409, $$417] project: [$$425, $$428]
                                                                                                                                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                              exchange
                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                replicate
                                                                                                                                                                                                                 -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                   -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                                                                                    assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                      exchange
                                                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                        replicate
                                                                                                                                                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                          exchange
                                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                            assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                              exchange
                                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                                -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                                                                                                data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                    empty-tuple-source
                                                                                                                                                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                                          exchange
                                                                                                                                                                                                           -- HASH_PARTITION_EXCHANGE [$$427]  |PARTITIONED|
+                                                                                                                                                                                                            select (eq($$430.getField("to_u"), "aaaaa")) project: [$$422, $$426, $$427]
                                                                                                                                                                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                                              exchange
                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                replicate
                                                                                                                                                                                                                 -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                    assign [$$427, $$422] <- [$$430.getField("y_id"), $$430.getField("b")]
                                                                                                                                                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                      assign [$$426, $$430] <- [$$411, $$413] project: [$$426, $$430]
                                                                                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                        exchange
                                                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                          replicate
                                                                                                                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                            exchange
                                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                              -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                                                              data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                                                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                  empty-tuple-source
                                                                                                                                                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                              exchange
                                                                                                                                                                                               -- HASH_PARTITION_EXCHANGE [$$435, $$436]  |PARTITIONED|
+                                                                                                                                                                                                assign [$$437] <- [true]
                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                  project ([$$438, $$435, $$436])
                                                                                                                                                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                                    exchange
                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                      join (eq($$442, $$443))
                                                                                                                                                                                                       -- HYBRID_HASH_JOIN [$$443][$$442]  |PARTITIONED|
+                                                                                                                                                                                                        exchange
                                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                          project ([$$438, $$435, $$436, $$443])
                                                                                                                                                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                                            exchange
                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                              join (eq($$444, $$445))
                                                                                                                                                                                                               -- HYBRID_HASH_JOIN [$$445][$$444]  |PARTITIONED|
+                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                  replicate
                                                                                                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                    exchange
                                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                      project ([$$435, $$436, $$445])
                                                                                                                                                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                                                        exchange
                                                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                          join (eq($$448, $$445))
                                                                                                                                                                                                                           -- HYBRID_HASH_JOIN [$$445][$$448]  |PARTITIONED|
+                                                                                                                                                                                                                            exchange
                                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                              assign [$$435, $$445] <- [$$409, $$417] project: [$$435, $$445]
                                                                                                                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                  replicate
                                                                                                                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                                    exchange
                                                                                                                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                                                                                                      assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                                        exchange
                                                                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                          replicate
                                                                                                                                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                                            exchange
                                                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                              assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                                                  -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                                                                                                                  data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                                                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                                                    exchange
                                                                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                                      empty-tuple-source
                                                                                                                                                                                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                                                            exchange
                                                                                                                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$448]  |PARTITIONED|
+                                                                                                                                                                                                                              select (eq($$450.getField("to_u"), "aaaaa")) project: [$$436, $$448]
                                                                                                                                                                                                                               -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                  replicate
                                                                                                                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                                    exchange
                                                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                      assign [$$448] <- [$$450.getField("y_id")]
                                                                                                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                                        assign [$$436, $$450] <- [$$411, $$413] project: [$$436, $$450]
                                                                                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                                          exchange
                                                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                            replicate
                                                                                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                                              exchange
                                                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                                                -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                                                                                data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                                                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                                    empty-tuple-source
                                                                                                                                                                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                  replicate
                                                                                                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                    exchange
                                                                                                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$444]  |PARTITIONED|
+                                                                                                                                                                                                                      select (eq($$441.getField("to_u"), "aaaaa")) project: [$$438, $$443, $$444]
                                                                                                                                                                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                                                        assign [$$444, $$443, $$438] <- [$$441.getField("y_id"), $$441.getField("a"), $$441.getField("b")]
                                                                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                          exchange
                                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                            replicate
                                                                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                              exchange
                                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                assign [$$447, $$441] <- [$$411, $$413] project: [$$441]
                                                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                    replicate
                                                                                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                                      exchange
                                                                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                                        -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                                                                        data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                                                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                                          exchange
                                                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                            empty-tuple-source
                                                                                                                                                                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                                        exchange
                                                                                                                                                                                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                          unnest $$442 <- scan-collection(array: [ 66, 67, 26, 12, 13 ])
                                                                                                                                                                                                           -- UNNEST  |UNPARTITIONED|
+                                                                                                                                                                                                            empty-tuple-source
                                                                                                                                                                                                             -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                                                                                                                exchange
                                                                                                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                                                                  unnest $$406 <- scan-collection(array: [ 66, 67, 26, 12, 13 ])
                                                                                                                                                   -- UNNEST  |UNPARTITIONED|
+                                                                                                                                                    empty-tuple-source
                                                                                                                                                     -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                                                                                      exchange
                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$390]  |PARTITIONED|
+                                                                                                                        assign [$$397, $$392, $$390] <- [$$436, $$450, $$448] project: [$$397, $$390]
                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                          exchange
                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                            replicate
                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                              exchange
                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                assign [$$448] <- [$$450.getField("y_id")]
                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                  assign [$$436, $$450] <- [$$411, $$413] project: [$$436, $$450]
                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                    exchange
                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                      replicate
                                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                                        exchange
                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                          -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                          data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                            exchange
                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                              empty-tuple-source
                                                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                              exchange
                                                                                                               -- HASH_PARTITION_EXCHANGE [$$216]  |PARTITIONED|
+                                                                                                                assign [$$172, $$216, $$180] <- [$$L.getField("posi"), $$L.getField("y_id"), $$L.getField("b")] project: [$$180, $$172, $$216]
                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                  assign [$$L] <- [$$441] project: [$$L]
                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                      replicate
                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                        exchange
                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                          assign [$$447, $$441] <- [$$411, $$413] project: [$$441]
                                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                              replicate
                                                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                                                exchange
                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                  -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                  data-scan []<-[$$411, $$413] <- test.collection1
+                                                                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                    exchange
                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                      empty-tuple-source
                                                                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                        unnest $$200 <- scan-collection(array: [ "a", "b" ])
                                                                                                         -- UNNEST  |UNPARTITIONED|
+                                                                                                          empty-tuple-source
                                                                                                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                              exchange
                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                unnest $$201 <- scan-collection(array: [ "a", "b" ])
                                                 -- UNNEST  |UNPARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        unnest $$202 <- scan-collection(array: [ 66, 67, 12, 13 ])
                                         -- UNNEST  |UNPARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue849-2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue849-2.plan
index a73a314..3863ad7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue849-2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue849-2.plan
@@ -1,30 +1,28 @@
--- COMMIT  |PARTITIONED|
-  -- STREAM_PROJECT  |PARTITIONED|
-    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-      -- INSERT_DELETE  |PARTITIONED|
-        -- HASH_PARTITION_EXCHANGE [$$3]  |PARTITIONED|
-          -- ASSIGN  |UNPARTITIONED|
-            -- ASSIGN  |UNPARTITIONED|
-              -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
--- COMMIT  |PARTITIONED|
-  -- STREAM_PROJECT  |PARTITIONED|
-    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-      -- INSERT_DELETE  |PARTITIONED|
-        -- HASH_PARTITION_EXCHANGE [$$3]  |PARTITIONED|
-          -- ASSIGN  |UNPARTITIONED|
-            -- ASSIGN  |UNPARTITIONED|
-              -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+distribute result [$$46]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$46] <- [{"x": $$x, "y": $$43}] project: [$$46]
     -- ASSIGN  |PARTITIONED|
+      project ([$$x, $$43])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$47, $$49))
           -- HYBRID_HASH_JOIN [$$47][$$49]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.s)  |PARTITIONED|
+              data-scan []<-[$$47, $$x] <- test.s
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$49]  |PARTITIONED|
+              assign [$$43, $$49] <- [$$z.getField("c"), $$z.getField("a")] project: [$$43, $$49]
               -- ASSIGN  |UNPARTITIONED|
+                unnest $$z <- scan-collection(unordered-list-constructor({"a": 1, "c": 1}, {"a": 2, "c": 2}, {"a": 1, "c": null}))
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue849.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue849.plan
index 131d733..b2cb6eb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue849.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query_issue849.plan
@@ -1,32 +1,32 @@
--- COMMIT  |PARTITIONED|
-  -- STREAM_PROJECT  |PARTITIONED|
-    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-      -- INSERT_DELETE  |PARTITIONED|
-        -- HASH_PARTITION_EXCHANGE [$$3]  |PARTITIONED|
-          -- ASSIGN  |UNPARTITIONED|
-            -- ASSIGN  |UNPARTITIONED|
-              -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
--- COMMIT  |PARTITIONED|
-  -- STREAM_PROJECT  |PARTITIONED|
-    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-      -- INSERT_DELETE  |PARTITIONED|
-        -- HASH_PARTITION_EXCHANGE [$$3]  |PARTITIONED|
-          -- ASSIGN  |UNPARTITIONED|
-            -- ASSIGN  |UNPARTITIONED|
-              -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"x": $$x, "y": $$47}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      project ([$$x, $$47])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$48, $$47))
           -- HYBRID_HASH_JOIN [$$48][$$47]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+              assign [$$48] <- [$$x.getField(0)]
               -- ASSIGN  |UNPARTITIONED|
+                unnest $$x <- scan-collection(multiset: {{ { "a": 1 }, { "a": 2 } }})
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
+              project ([$$47])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.s)  |PARTITIONED|
+                  data-scan []<-[$$47, $$z] <- test.s
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/remove_listify.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/remove_listify.plan
index 0a88e9b..56a855c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/remove_listify.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/remove_listify.plan
@@ -1,33 +1,63 @@
+distribute result [$$137]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$137] <- [{"f1": $$146, "counts": get-item($$135, 0)}] project: [$$137]
     -- ASSIGN  |PARTITIONED|
+      project ([$$135, $$146])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- PRE_CLUSTERED_GROUP_BY[$$141]  |PARTITIONED|
-                  {
+          group by ([$$153 := $$141]) decor ([$$146]) {
+                    aggregate [$$135] <- [listify({"counts": $$143})]
                     -- AGGREGATE  |LOCAL|
+                      aggregate [$$143] <- [agg-sql-count(1)]
                       -- AGGREGATE  |LOCAL|
+                        select (and(ge($$139, numeric-subtract($$147, 5)), le($$139, $$147), not(is-missing($$152))))
                         -- STREAM_SELECT  |LOCAL|
+                          assign [$$139] <- [$$113.getField("f2")]
                           -- ASSIGN  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- PRE_CLUSTERED_GROUP_BY[$$141]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$141)
               -- STABLE_SORT [$$141(ASC)]  |PARTITIONED|
+                exchange
                 -- HASH_PARTITION_EXCHANGE [$$141]  |PARTITIONED|
+                  project ([$$146, $$147, $$152, $$113, $$141])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      left outer join (eq($$148, $$146))
                       -- HYBRID_HASH_JOIN [$$146][$$148]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$146]  |PARTITIONED|
+                          assign [$$147, $$146] <- [$$b.getField("f2"), $$b.getField("f1")] project: [$$146, $$147, $$141]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                              data-scan []<-[$$141, $$b] <- test.collection1
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$148]  |PARTITIONED|
+                          assign [$$152, $$113] <- [true, {"f1": $$148, "f2": $$b.getField("f2")}] project: [$$152, $$113, $$148]
                           -- ASSIGN  |PARTITIONED|
+                            assign [$$148] <- [$$b.getField("f1")]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$b])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                  data-scan []<-[$$142, $$b] <- test.collection1
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rightouterjoin/roj-01-core.1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rightouterjoin/roj-01-core.1.plan
index 09b9dbe..c7857e2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rightouterjoin/roj-01-core.1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rightouterjoin/roj-01-core.1.plan
@@ -1,24 +1,48 @@
+distribute result [$$89]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$89] <- [{"t0_unique1": $#1, "t1_unique1": $#2}] project: [$$89]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$#1(ASC), $#2(ASC) ]  |PARTITIONED|
+        order (ASC, $#1) (ASC, $#2)
         -- STABLE_SORT [$#1(ASC), $#2(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            assign [$#2, $#1] <- [if-missing($$96, null), if-missing($$98, null)] project: [$#1, $#2]
             -- ASSIGN  |PARTITIONED|
+              project ([$$96, $$98])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  left outer join (eq($$92, $$91))
                   -- HYBRID_HASH_JOIN [$$91][$$92]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$91]  |PARTITIONED|
+                      assign [$$96] <- [$$tenk.getField(0)] project: [$$96, $$91]
                       -- ASSIGN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                          unnest-map [$$91, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 0, 1, $$104, true, false, false)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$104] <- [4]
                               -- ASSIGN  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$92]  |PARTITIONED|
+                      assign [$$98] <- [{"unique1": $$tenk.getField(0), "unique2": $$92}.getField(0)] project: [$$98, $$92]
                       -- ASSIGN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                          unnest-map [$$92, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 0, 1, $$107, true, false, false)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$107] <- [2]
                               -- ASSIGN  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rightouterjoin/roj-01-core.2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rightouterjoin/roj-01-core.2.plan
index fdeccc1..e97c004 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rightouterjoin/roj-01-core.2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rightouterjoin/roj-01-core.2.plan
@@ -1,37 +1,74 @@
+distribute result [$$149]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$149] <- [{"t0_unique1": $#1, "t1_unique1": $#2, "t2_unique1": $#3}] project: [$$149]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$#1(ASC), $#2(ASC), $#3(ASC) ]  |PARTITIONED|
+        order (ASC, $#1) (ASC, $#2) (ASC, $#3)
         -- STABLE_SORT [$#1(ASC), $#2(ASC), $#3(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            assign [$#3, $#2, $#1] <- [if-missing($$160, null), if-missing($$164, null), if-missing($$163, null)] project: [$#1, $#2, $#3]
             -- ASSIGN  |PARTITIONED|
+              project ([$$160, $$164, $$163])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  left outer join (eq($$152, $$151))
                   -- HYBRID_HASH_JOIN [$$151][$$152]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$151]  |PARTITIONED|
+                      assign [$$160] <- [$$tenk.getField(0)] project: [$$160, $$151]
                       -- ASSIGN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                          unnest-map [$$151, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 0, 1, $$174, true, false, false)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$174] <- [6]
                               -- ASSIGN  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$163, $$164] <- [$$132.getField(1).getField(0), $$132.getField(0).getField(0)] project: [$$164, $$163, $$152]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$132] <- [{"$6": $$116, "$8": $$124}] project: [$$152, $$132]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$152, $$116, $$124])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              left outer join (eq($$153, $$152))
                               -- HYBRID_HASH_JOIN [$$152][$$153]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$152]  |PARTITIONED|
+                                  assign [$$116] <- [{"unique1": $$tenk.getField(0), "unique2": $$152}] project: [$$152, $$116]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                                      unnest-map [$$152, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 0, 1, $$177, true, false, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$177] <- [4]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$153]  |PARTITIONED|
+                                  assign [$$124] <- [{"unique1": $$tenk.getField(0), "unique2": $$153}] project: [$$124, $$153]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                                      unnest-map [$$153, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 0, 1, $$180, true, false, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$180] <- [2]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-01.plan
index 26f64fe..b02a1f2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-01.plan
@@ -1,14 +1,28 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-intersects($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BTREE_SEARCH (IndexGeoJSON.Geometries.Geometries)  |PARTITIONED|
+        unnest-map [$$18, $$geo] <- index-search("Geometries", 0, "Default", "IndexGeoJSON", "Geometries", false, false, 1, $$28, 1, $$28, true, true, true)
+        -- BTREE_SEARCH  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$28)
             -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$28])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- RTREE_SEARCH (IndexGeoJSON.Geometries.geomIndex)  |PARTITIONED|
+                    unnest-map [$$24, $$25, $$26, $$27, $$28] <- index-search("geomIndex", 1, "Default", "IndexGeoJSON", "Geometries", false, false, 4, $$20, $$21, $$22, $$23)
+                    -- RTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$20, $$21, $$22, $$23] <- [1.0, 1.0, 5.0, 5.0]
                         -- ASSIGN  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-02.plan
index 26f64fe..eae71cc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-02.plan
@@ -1,14 +1,28 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-contains($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BTREE_SEARCH (IndexGeoJSON.Geometries.Geometries)  |PARTITIONED|
+        unnest-map [$$18, $$geo] <- index-search("Geometries", 0, "Default", "IndexGeoJSON", "Geometries", false, false, 1, $$28, 1, $$28, true, true, true)
+        -- BTREE_SEARCH  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$28)
             -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$28])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- RTREE_SEARCH (IndexGeoJSON.Geometries.geomIndex)  |PARTITIONED|
+                    unnest-map [$$24, $$25, $$26, $$27, $$28] <- index-search("geomIndex", 1, "Default", "IndexGeoJSON", "Geometries", false, false, 4, $$20, $$21, $$22, $$23)
+                    -- RTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$20, $$21, $$22, $$23] <- [1.0, 1.0, 5.0, 5.0]
                         -- ASSIGN  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-03.plan
index 26f64fe..9b0022f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-03.plan
@@ -1,14 +1,28 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-crosses($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BTREE_SEARCH (IndexGeoJSON.Geometries.Geometries)  |PARTITIONED|
+        unnest-map [$$18, $$geo] <- index-search("Geometries", 0, "Default", "IndexGeoJSON", "Geometries", false, false, 1, $$28, 1, $$28, true, true, true)
+        -- BTREE_SEARCH  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$28)
             -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$28])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- RTREE_SEARCH (IndexGeoJSON.Geometries.geomIndex)  |PARTITIONED|
+                    unnest-map [$$24, $$25, $$26, $$27, $$28] <- index-search("geomIndex", 1, "Default", "IndexGeoJSON", "Geometries", false, false, 4, $$20, $$21, $$22, $$23)
+                    -- RTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$20, $$21, $$22, $$23] <- [1.0, 1.0, 5.0, 5.0]
                         -- ASSIGN  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-04.plan
index 26f64fe..d7305a8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-04.plan
@@ -1,14 +1,28 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-overlaps($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BTREE_SEARCH (IndexGeoJSON.Geometries.Geometries)  |PARTITIONED|
+        unnest-map [$$18, $$geo] <- index-search("Geometries", 0, "Default", "IndexGeoJSON", "Geometries", false, false, 1, $$28, 1, $$28, true, true, true)
+        -- BTREE_SEARCH  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$28)
             -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$28])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- RTREE_SEARCH (IndexGeoJSON.Geometries.geomIndex)  |PARTITIONED|
+                    unnest-map [$$24, $$25, $$26, $$27, $$28] <- index-search("geomIndex", 1, "Default", "IndexGeoJSON", "Geometries", false, false, 4, $$20, $$21, $$22, $$23)
+                    -- RTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$20, $$21, $$22, $$23] <- [1.0, 1.0, 5.0, 5.0]
                         -- ASSIGN  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-05.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-05.plan
index 26f64fe..3849b20 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-05.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-05.plan
@@ -1,14 +1,28 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-touches($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BTREE_SEARCH (IndexGeoJSON.Geometries.Geometries)  |PARTITIONED|
+        unnest-map [$$18, $$geo] <- index-search("Geometries", 0, "Default", "IndexGeoJSON", "Geometries", false, false, 1, $$28, 1, $$28, true, true, true)
+        -- BTREE_SEARCH  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$28)
             -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$28])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- RTREE_SEARCH (IndexGeoJSON.Geometries.geomIndex)  |PARTITIONED|
+                    unnest-map [$$24, $$25, $$26, $$27, $$28] <- index-search("geomIndex", 1, "Default", "IndexGeoJSON", "Geometries", false, false, 4, $$20, $$21, $$22, $$23)
+                    -- RTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$20, $$21, $$22, $$23] <- [1.0, 1.0, 5.0, 5.0]
                         -- ASSIGN  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-06.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-06.plan
index 26f64fe..93654cf 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-06.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-06.plan
@@ -1,14 +1,28 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-within($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BTREE_SEARCH (IndexGeoJSON.Geometries.Geometries)  |PARTITIONED|
+        unnest-map [$$18, $$geo] <- index-search("Geometries", 0, "Default", "IndexGeoJSON", "Geometries", false, false, 1, $$28, 1, $$28, true, true, true)
+        -- BTREE_SEARCH  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$28)
             -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$28])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- RTREE_SEARCH (IndexGeoJSON.Geometries.geomIndex)  |PARTITIONED|
+                    unnest-map [$$24, $$25, $$26, $$27, $$28] <- index-search("geomIndex", 1, "Default", "IndexGeoJSON", "Geometries", false, false, 4, $$20, $$21, $$22, $$23)
+                    -- RTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$20, $$21, $$22, $$23] <- [1.0, 1.0, 5.0, 5.0]
                         -- ASSIGN  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-07.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-07.plan
index 26f64fe..11f0d71 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-07.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/rtree-sidx-idxonly-07.plan
@@ -1,14 +1,28 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-disjoint($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BTREE_SEARCH (IndexGeoJSON.Geometries.Geometries)  |PARTITIONED|
+        unnest-map [$$18, $$geo] <- index-search("Geometries", 0, "Default", "IndexGeoJSON", "Geometries", false, false, 1, $$28, 1, $$28, true, true, true)
+        -- BTREE_SEARCH  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$28)
             -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$28])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- RTREE_SEARCH (IndexGeoJSON.Geometries.geomIndex)  |PARTITIONED|
+                    unnest-map [$$24, $$25, $$26, $$27, $$28] <- index-search("geomIndex", 1, "Default", "IndexGeoJSON", "Geometries", false, false, 4, $$20, $$21, $$22, $$23)
+                    -- RTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$20, $$21, $$22, $$23] <- [1.0, 1.0, 5.0, 5.0]
                         -- ASSIGN  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-01.plan
index e981647..c26f747 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-01.plan
@@ -1,7 +1,14 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-intersects($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- DATASOURCE_SCAN (IndexGeoJSON.Geometries)  |PARTITIONED|
+        data-scan []<-[$$18, $$geo] <- IndexGeoJSON.Geometries
+        -- DATASOURCE_SCAN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            empty-tuple-source
             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-02.plan
index e981647..529eaf3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-02.plan
@@ -1,7 +1,14 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-contains($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- DATASOURCE_SCAN (IndexGeoJSON.Geometries)  |PARTITIONED|
+        data-scan []<-[$$18, $$geo] <- IndexGeoJSON.Geometries
+        -- DATASOURCE_SCAN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            empty-tuple-source
             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-03.plan
index e981647..fee1931 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-03.plan
@@ -1,7 +1,14 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-crosses($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- DATASOURCE_SCAN (IndexGeoJSON.Geometries)  |PARTITIONED|
+        data-scan []<-[$$18, $$geo] <- IndexGeoJSON.Geometries
+        -- DATASOURCE_SCAN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            empty-tuple-source
             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-04.plan
index e981647..314baac 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-04.plan
@@ -1,7 +1,14 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-overlaps($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- DATASOURCE_SCAN (IndexGeoJSON.Geometries)  |PARTITIONED|
+        data-scan []<-[$$18, $$geo] <- IndexGeoJSON.Geometries
+        -- DATASOURCE_SCAN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            empty-tuple-source
             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-05.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-05.plan
index e981647..dfcdaf1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-05.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-05.plan
@@ -1,7 +1,14 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-touches($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- DATASOURCE_SCAN (IndexGeoJSON.Geometries)  |PARTITIONED|
+        data-scan []<-[$$18, $$geo] <- IndexGeoJSON.Geometries
+        -- DATASOURCE_SCAN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            empty-tuple-source
             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-06.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-06.plan
index e981647..45afdf2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-06.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-06.plan
@@ -1,7 +1,14 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-within($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- DATASOURCE_SCAN (IndexGeoJSON.Geometries)  |PARTITIONED|
+        data-scan []<-[$$18, $$geo] <- IndexGeoJSON.Geometries
+        -- DATASOURCE_SCAN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            empty-tuple-source
             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-07.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-07.plan
index e981647..c6e75b8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-07.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-geometry/skip-rtree-sidx-07.plan
@@ -1,7 +1,14 @@
+distribute result [$$18]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-disjoint($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- DATASOURCE_SCAN (IndexGeoJSON.Geometries)  |PARTITIONED|
+        data-scan []<-[$$18, $$geo] <- IndexGeoJSON.Geometries
+        -- DATASOURCE_SCAN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            empty-tuple-source
             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01_ps.plan
index 6323247..93871a6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01_ps.plan
@@ -1,120 +1,234 @@
+distribute result [$$53]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$53] <- [{"tweetid1": $$64, "loc1": $$96, "nearby-message": $$52}] project: [$$53]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$64)
         -- STABLE_SORT [$$64(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$64(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$100
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$97]  |PARTITIONED|
-                            {
+                    group by ([$$64 := $$97]) decor ([$$96]) {
+                              aggregate [$$52] <- [listify({"tweetid2": $$58, "loc2": $$59})]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$58)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$97]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$97) (ASC, $$58)
                         -- STABLE_SORT [$$97(ASC), $$58(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$97]  |PARTITIONED|
+                            union ($$93, $$76, $$58) ($$95, $$78, $$59) ($$56, $$56, $$96) ($$57, $$57, $$97)
                             -- UNION_ALL  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (spatial-intersect($$95, $$n)) retain-untrue ($$93 <- missing) project: [$$93, $$95, $$56, $$57]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$95] <- [$$94.getField(2)] project: [$$57, $$56, $$n, $$76, $$93, $$95]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                      left-outer-unnest-map [$$93, $$94] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$76, 1, $$76, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$57, $$56, $$n, $$76])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              split ($$77)
                                               -- SPLIT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  project ([$$57, $$56, $$n, $$72, $$73, $$76, $$77])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                      left-outer-unnest-map [$$72, $$73, $$74, $$75, $$76, $$77] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$68, $$69, $$70, $$71)
+                                                      -- RTREE_SEARCH  |PARTITIONED|
+                                                        exchange
                                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                          assign [$$68, $$69, $$70, $$71] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            assign [$$n] <- [create-circle($$56, 0.5)]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              assign [$$56] <- [$$t1.getField(2)] project: [$$57, $$56]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                  unnest-map [$$57, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$65, true, false, false)
+                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      assign [$$65] <- [10]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (spatial-intersect($$78, $$n)) retain-untrue ($$76 <- missing) project: [$$76, $$78, $$56, $$57]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$78] <- [create-point($$72, $$73)] project: [$$57, $$56, $$n, $$76, $$78]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$57, $$56, $$n, $$72, $$73, $$76])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        split ($$77)
                                         -- SPLIT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$57, $$56, $$n, $$72, $$73, $$76, $$77])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                left-outer-unnest-map [$$72, $$73, $$74, $$75, $$76, $$77] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$68, $$69, $$70, $$71)
+                                                -- RTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$68, $$69, $$70, $$71] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      assign [$$n] <- [create-circle($$56, 0.5)]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        assign [$$56] <- [$$t1.getField(2)] project: [$$57, $$56]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                            unnest-map [$$57, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$65, true, false, false)
+                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                assign [$$65] <- [10]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$100] <- [agg-range-map($$98, $$99)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$98, $$99] <- [agg-local-sampling($$64), agg-null-writer($$64)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$64])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$97]  |PARTITIONED|
-                                      {
+                              group by ([$$64 := $$97]) decor ([$$96]) {
+                                        aggregate [$$52] <- [listify({"tweetid2": $$58, "loc2": $$59})]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$58)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$97]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$97) (ASC, $$58)
                                   -- STABLE_SORT [$$97(ASC), $$58(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$97]  |PARTITIONED|
+                                      union ($$93, $$76, $$58) ($$95, $$78, $$59) ($$56, $$56, $$96) ($$57, $$57, $$97)
                                       -- UNION_ALL  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          select (spatial-intersect($$95, $$n)) retain-untrue ($$93 <- missing) project: [$$93, $$95, $$56, $$57]
                                           -- STREAM_SELECT  |PARTITIONED|
+                                            assign [$$95] <- [$$94.getField(2)] project: [$$57, $$56, $$n, $$76, $$93, $$95]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                left-outer-unnest-map [$$93, $$94] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$76, 1, $$76, true, true, true)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    project ([$$57, $$56, $$n, $$76])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        split ($$77)
                                                         -- SPLIT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            project ([$$57, $$56, $$n, $$72, $$73, $$76, $$77])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                                left-outer-unnest-map [$$72, $$73, $$74, $$75, $$76, $$77] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$68, $$69, $$70, $$71)
+                                                                -- RTREE_SEARCH  |PARTITIONED|
+                                                                  exchange
                                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                    assign [$$68, $$69, $$70, $$71] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      assign [$$n] <- [create-circle($$56, 0.5)]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        assign [$$56] <- [$$t1.getField(2)] project: [$$57, $$56]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                            unnest-map [$$57, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$65, true, false, false)
+                                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                assign [$$65] <- [10]
                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                  empty-tuple-source
                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          select (spatial-intersect($$78, $$n)) retain-untrue ($$76 <- missing) project: [$$76, $$78, $$56, $$57]
                                           -- STREAM_SELECT  |PARTITIONED|
+                                            assign [$$78] <- [create-point($$72, $$73)] project: [$$57, $$56, $$n, $$76, $$78]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$57, $$56, $$n, $$72, $$73, $$76])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  split ($$77)
                                                   -- SPLIT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      project ([$$57, $$56, $$n, $$72, $$73, $$76, $$77])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                          left-outer-unnest-map [$$72, $$73, $$74, $$75, $$76, $$77] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$68, $$69, $$70, $$71)
+                                                          -- RTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                              assign [$$68, $$69, $$70, $$71] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                assign [$$n] <- [create-circle($$56, 0.5)]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  assign [$$56] <- [$$t1.getField(2)] project: [$$57, $$56]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                      unnest-map [$$57, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$65, true, false, false)
+                                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          assign [$$65] <- [10]
                                                                           -- ASSIGN  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan
index d39aee0..3d86c89 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan
@@ -1,33 +1,63 @@
+distribute result [$$57]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$57] <- [{"tweetid1": $$69, "loc1": $$60, "nearby-message": $$56}] project: [$$57]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$69(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$61]  |PARTITIONED|
-                {
+        group by ([$$69 := $$61]) decor ([$$60]) {
+                  aggregate [$$56] <- [listify({"tweetid2": $$62, "loc2": $$64})]
                   -- AGGREGATE  |LOCAL|
+                    select (not(is-missing($$62)))
                     -- STREAM_SELECT  |LOCAL|
+                      nested tuple source
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$61]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$61) (ASC, $$62)
             -- STABLE_SORT [$$61(ASC), $$62(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$61]  |PARTITIONED|
+                select (and(spatial-intersect($$64, $$n), neq($$61, $$62))) retain-untrue ($$62 <- missing) project: [$$60, $$62, $$64, $$61]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$64] <- [$$t2.getField(2)] project: [$$60, $$61, $$n, $$62, $$64]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$60, $$61, $$n, $$62, $$t2])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                        left-outer-unnest-map [$$62, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$81, 1, $$81, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$81)
                             -- STABLE_SORT [$$81(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$60, $$61, $$n, $$81])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                    left-outer-unnest-map [$$77, $$78, $$79, $$80, $$81] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$73, $$74, $$75, $$76)
+                                    -- RTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        assign [$$73, $$74, $$75, $$76] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                         -- ASSIGN  |PARTITIONED|
+                                          assign [$$n] <- [create-circle($$60, 0.5)]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$60] <- [$$t1.getField(2)] project: [$$61, $$60]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                unnest-map [$$61, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$70, true, false, false)
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$70] <- [10]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02_ps.plan
index 4b2546a..676fd67 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02_ps.plan
@@ -1,76 +1,146 @@
+distribute result [$$57]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$57] <- [{"tweetid1": $$69, "loc1": $$60, "nearby-message": $$56}] project: [$$57]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$69)
         -- STABLE_SORT [$$69(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$69(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$84
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$61]  |PARTITIONED|
-                            {
+                    group by ([$$69 := $$61]) decor ([$$60]) {
+                              aggregate [$$56] <- [listify({"tweetid2": $$62, "loc2": $$64})]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$62)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$61]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$61) (ASC, $$62)
                         -- STABLE_SORT [$$61(ASC), $$62(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$61]  |PARTITIONED|
+                            select (and(spatial-intersect($$64, $$n), neq($$61, $$62))) retain-untrue ($$62 <- missing) project: [$$60, $$62, $$64, $$61]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$64] <- [$$t2.getField(2)] project: [$$60, $$61, $$n, $$62, $$64]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$60, $$61, $$n, $$62, $$t2])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                    left-outer-unnest-map [$$62, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$81, 1, $$81, true, true, true)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$81)
                                         -- STABLE_SORT [$$81(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$60, $$61, $$n, $$81])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                left-outer-unnest-map [$$77, $$78, $$79, $$80, $$81] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$73, $$74, $$75, $$76)
+                                                -- RTREE_SEARCH  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$73, $$74, $$75, $$76] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      assign [$$n] <- [create-circle($$60, 0.5)]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        assign [$$60] <- [$$t1.getField(2)] project: [$$61, $$60]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                            unnest-map [$$61, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$70, true, false, false)
+                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                assign [$$70] <- [10]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$84] <- [agg-range-map($$82, $$83)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$82, $$83] <- [agg-local-sampling($$69), agg-null-writer($$69)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$69])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$61]  |PARTITIONED|
-                                      {
+                              group by ([$$69 := $$61]) decor ([$$60]) {
+                                        aggregate [$$56] <- [listify({"tweetid2": $$62, "loc2": $$64})]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$62)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$61]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$61) (ASC, $$62)
                                   -- STABLE_SORT [$$61(ASC), $$62(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$61]  |PARTITIONED|
+                                      select (and(spatial-intersect($$64, $$n), neq($$61, $$62))) retain-untrue ($$62 <- missing) project: [$$60, $$62, $$64, $$61]
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        assign [$$64] <- [$$t2.getField(2)] project: [$$60, $$61, $$n, $$62, $$64]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$60, $$61, $$n, $$62, $$t2])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                              left-outer-unnest-map [$$62, $$t2] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", true, false, 1, $$81, 1, $$81, true, true, true)
+                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  order (ASC, $$81)
                                                   -- STABLE_SORT [$$81(ASC)]  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      project ([$$60, $$61, $$n, $$81])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- RTREE_SEARCH (test.TweetMessages.twmSndLocIx)  |PARTITIONED|
+                                                          left-outer-unnest-map [$$77, $$78, $$79, $$80, $$81] <- index-search("twmSndLocIx", 1, "Default", "test", "TweetMessages", true, true, 4, $$73, $$74, $$75, $$76)
+                                                          -- RTREE_SEARCH  |PARTITIONED|
+                                                            exchange
                                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                              assign [$$73, $$74, $$75, $$76] <- [create-mbr($$n, 2, 0), create-mbr($$n, 2, 1), create-mbr($$n, 2, 2), create-mbr($$n, 2, 3)]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                assign [$$n] <- [create-circle($$60, 0.5)]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  assign [$$60] <- [$$t1.getField(2)] project: [$$61, $$60]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- BTREE_SEARCH (test.TweetMessages.TweetMessages)  |PARTITIONED|
+                                                                      unnest-map [$$61, $$t1] <- index-search("TweetMessages", 0, "Default", "test", "TweetMessages", false, false, 0, 1, $$70, true, false, false)
+                                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          assign [$$70] <- [10]
                                                                           -- ASSIGN  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/spatial-intersect-point_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/spatial-intersect-point_02.plan
index 62ab9c9..d48b513 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/spatial-intersect-point_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/spatial-intersect-point_02.plan
@@ -1,21 +1,42 @@
+distribute result [$$29]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"a": $$a, "b": $$b}] project: [$$29]
     -- ASSIGN  |PARTITIONED|
+      select (spatial-intersect($$32, $$b.getField(1))) project: [$$a, $$b]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$a, $$32, $$b])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.MyData2.MyData2)  |PARTITIONED|
+            unnest-map [$$31, $$b] <- index-search("MyData2", 0, "Default", "test", "MyData2", true, false, 1, $$42, 1, $$42, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$42)
                 -- STABLE_SORT [$$42(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$a, $$32, $$42])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- RTREE_SEARCH (test.MyData2.rtree_index)  |PARTITIONED|
+                        unnest-map [$$38, $$39, $$40, $$41, $$42] <- index-search("rtree_index", 1, "Default", "test", "MyData2", true, true, 4, $$34, $$35, $$36, $$37)
+                        -- RTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$34, $$35, $$36, $$37] <- [create-mbr($$32, 2, 0), create-mbr($$32, 2, 1), create-mbr($$32, 2, 2), create-mbr($$32, 2, 3)]
                             -- ASSIGN  |PARTITIONED|
+                              assign [$$32] <- [$$a.getField(1)]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$a])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.MyData1)  |PARTITIONED|
+                                    data-scan []<-[$$30, $$a] <- test.MyData1
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/spatial-intersect-point_03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/spatial-intersect-point_03.plan
index cc41707..6921e26 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/spatial-intersect-point_03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/spatial-intersect-point_03.plan
@@ -1,21 +1,42 @@
+distribute result [$$29]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"a": $$a, "b": $$b}] project: [$$29]
     -- ASSIGN  |PARTITIONED|
+      select (spatial-intersect($$32, $$b.getField(1))) project: [$$a, $$b]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$a, $$32, $$b])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.MyData.MyData)  |PARTITIONED|
+            unnest-map [$$31, $$b] <- index-search("MyData", 0, "Default", "test", "MyData", true, false, 1, $$42, 1, $$42, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$42)
                 -- STABLE_SORT [$$42(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$a, $$32, $$42])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- RTREE_SEARCH (test.MyData.rtree_index)  |PARTITIONED|
+                        unnest-map [$$38, $$39, $$40, $$41, $$42] <- index-search("rtree_index", 1, "Default", "test", "MyData", true, true, 4, $$34, $$35, $$36, $$37)
+                        -- RTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$34, $$35, $$36, $$37] <- [create-mbr($$32, 2, 0), create-mbr($$32, 2, 1), create-mbr($$32, 2, 2), create-mbr($$32, 2, 3)]
                             -- ASSIGN  |PARTITIONED|
+                              assign [$$32] <- [$$a.getField(1)]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$a])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.MyData)  |PARTITIONED|
+                                    data-scan []<-[$$30, $$a] <- test.MyData
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index/rtree-sidx-idxonly-01-disable-idxonly.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index/rtree-sidx-idxonly-01-disable-idxonly.plan
index 7d4f008..8b44bf2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index/rtree-sidx-idxonly-01-disable-idxonly.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index/rtree-sidx-idxonly-01-disable-idxonly.plan
@@ -1,19 +1,38 @@
+distribute result [$$53]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$53] <- [{"$1": $$56}] project: [$$53]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$56] <- [agg-sql-sum($$57)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$57] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (spatial-intersect($$x.getField(8), polygon: [ point: { x: 0.0, y: 0.0 }, point: { x: 2.0, y: 2.0 }, point: { x: 0.0, y: 2.0 }, point: { x: 2.0, y: 0.0 } ]))
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$x])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.Fragile_raw.Fragile_raw)  |PARTITIONED|
+                  unnest-map [$$55, $$x] <- index-search("Fragile_raw", 0, "Default", "test", "Fragile_raw", false, false, 1, $$66, 1, $$66, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$66)
                       -- STABLE_SORT [$$66(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$66])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- RTREE_SEARCH (test.Fragile_raw.cfLocation)  |PARTITIONED|
+                              unnest-map [$$62, $$63, $$64, $$65, $$66] <- index-search("cfLocation", 1, "Default", "test", "Fragile_raw", false, false, 4, $$58, $$59, $$60, $$61)
+                              -- RTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$58, $$59, $$60, $$61] <- [0.0, 0.0, 2.0, 2.0]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index/rtree-sidx-idxonly-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index/rtree-sidx-idxonly-01.plan
index 36f14dd..0815577 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index/rtree-sidx-idxonly-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/rtree-index/rtree-sidx-idxonly-01.plan
@@ -1,34 +1,68 @@
+distribute result [$$53]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$53] <- [{"$1": $$56}] project: [$$53]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$56] <- [agg-sql-sum($$57)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$57] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              union
               -- UNION_ALL  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (spatial-intersect($$76.getField(8), polygon: [ point: { x: 0.0, y: 0.0 }, point: { x: 2.0, y: 2.0 }, point: { x: 0.0, y: 2.0 }, point: { x: 2.0, y: 0.0 } ])) project: []
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$76])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Fragile_raw.Fragile_raw)  |PARTITIONED|
+                        unnest-map [$$75, $$76] <- index-search("Fragile_raw", 0, "Default", "test", "Fragile_raw", false, false, 1, $$66, 1, $$66, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            split ($$67)
                             -- SPLIT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$62, $$63, $$66, $$67])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- RTREE_SEARCH (test.Fragile_raw.cfLocation)  |PARTITIONED|
+                                    unnest-map [$$62, $$63, $$64, $$65, $$66, $$67] <- index-search("cfLocation", 1, "Default", "test", "Fragile_raw", false, false, 4, $$58, $$59, $$60, $$61)
+                                    -- RTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$58, $$59, $$60, $$61] <- [0.0, 0.0, 2.0, 2.0]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (spatial-intersect(create-point($$62, $$63), polygon: [ point: { x: 0.0, y: 0.0 }, point: { x: 2.0, y: 2.0 }, point: { x: 0.0, y: 2.0 }, point: { x: 2.0, y: 0.0 } ])) project: []
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$62, $$63])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        split ($$67)
                         -- SPLIT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$62, $$63, $$66, $$67])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- RTREE_SEARCH (test.Fragile_raw.cfLocation)  |PARTITIONED|
+                                unnest-map [$$62, $$63, $$64, $$65, $$66, $$67] <- index-search("cfLocation", 1, "Default", "test", "Fragile_raw", false, false, 4, $$58, $$59, $$60, $$61)
+                                -- RTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$58, $$59, $$60, $$61] <- [0.0, 0.0, 2.0, 2.0]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/skip-index/skip-ngram-index_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/skip-index/skip-ngram-index_ps.plan
index 93ca5bd..d6a002c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/skip-index/skip-ngram-index_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/skip-index/skip-ngram-index_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$15)
         -- STABLE_SORT [$$15(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$15(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$20
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField(2), "Multimedia"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                        data-scan []<-[$$15, $$o] <- test.DBLP
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$20] <- [agg-range-map($$18, $$19)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$18, $$19] <- [agg-local-sampling($$15), agg-null-writer($$15)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$15])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField(2), "Multimedia"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                  data-scan []<-[$$15, $$o] <- test.DBLP
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/skip-index/skip-secondary-btree-index-2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/skip-index/skip-secondary-btree-index-2.plan
index 15424cd..31aa731 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/skip-index/skip-secondary-btree-index-2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/skip-index/skip-secondary-btree-index-2.plan
@@ -1,16 +1,32 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(ge($$18, "Max"), le($$18, "Roger"))) project: [$$emp]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$18] <- [$$emp.getField(1)]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.testdst.testdst)  |PARTITIONED|
+            unnest-map [$$19, $$emp] <- index-search("testdst", 0, "Default", "test", "testdst", false, false, 1, $$22, 1, $$22, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$22)
                 -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$22])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.testdst.sec_Idx)  |PARTITIONED|
+                        unnest-map [$$21, $$22] <- index-search("sec_Idx", 0, "Default", "test", "testdst", false, false, 0, 1, $$20, true, true, false)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$20] <- ["Roger"]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/skip-index/skip-secondary-btree-index-3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/skip-index/skip-secondary-btree-index-3.plan
index 4a65a41..1a1d2ec 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/skip-index/skip-secondary-btree-index-3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/skip-index/skip-secondary-btree-index-3.plan
@@ -1,15 +1,30 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$emp])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        join (eq($$18, $$15))
         -- HYBRID_HASH_JOIN [$$15][$$18]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            assign [$$15] <- [$$emp.getField(1)]
             -- ASSIGN  |PARTITIONED|
+              project ([$$emp])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+                  data-scan []<-[$$17, $$emp] <- test.testdst
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+          exchange
           -- BROADCAST_EXCHANGE  |PARTITIONED|
+            unnest $$18 <- scan-collection(array: [ "Roger", "Max" ])
             -- UNNEST  |UNPARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/skip-index/skip-secondary-btree-index-4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/skip-index/skip-secondary-btree-index-4.plan
index 1435e63..6b81116 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/skip-index/skip-secondary-btree-index-4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/skip-index/skip-secondary-btree-index-4.plan
@@ -1,10 +1,20 @@
+distribute result [$$19]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"c": $$c}] project: [$$19]
     -- ASSIGN  |PARTITIONED|
+      select (and(ge($$20, "abc"), lt($$20, "abd"))) project: [$$c]
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$20] <- [$$c.getField("f")]
         -- ASSIGN  |PARTITIONED|
+          project ([$$c])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.c)  |PARTITIONED|
+              data-scan []<-[$$21, $$c] <- test.c
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+                  empty-tuple-source
+                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/spatial_join/spatial_intersect_dynamic_partitioning.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/spatial_join/spatial_intersect_dynamic_partitioning.plan
index 423affb..6b5600d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/spatial_join/spatial_intersect_dynamic_partitioning.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/spatial_join/spatial_intersect_dynamic_partitioning.plan
@@ -1,140 +1,280 @@
+distribute result [$$49]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$49] <- [{"$1": $$54}] project: [$$49]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$54] <- [agg-sql-sum($$55)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$55] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$63, reference-tile($$52, $$53, $$60, 100, 100, $$64)))
               -- NESTED_LOOP  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (spatial-intersect($$52, $$53))
                   -- SPATIAL_JOIN [$$63, $$52] [$$64, $$53]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$63) (ASC, $$52)
                       -- STABLE_SORT [$$63(ASC), $$52(ASC)]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$63]  |PARTITIONED|
+                          unnest $$63 <- spatial-tile($$52, $$61, 100, 100) project: [$$52, $$63]
                           -- UNNEST  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              join (true)
                               -- NESTED_LOOP  |PARTITIONED|
+                                exchange
                                 -- RANDOM_PARTITION_EXCHANGE  |PARTITIONED|
+                                  replicate
                                   -- REPLICATE  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$52] <- [$$ps.getField(1)] project: [$$52]
                                       -- ASSIGN  |PARTITIONED|
+                                        project ([$$ps])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (test.ParkSet)  |PARTITIONED|
+                                            data-scan []<-[$$50, $$ps] <- test.ParkSet
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$61] <- [$$60] project: [$$61]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                      replicate
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$60] <- [get-intersection($$57, $$59)] project: [$$60]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                              join (true)
                                               -- NESTED_LOOP  |UNPARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                  aggregate [$$57] <- [agg-global-union_mbr($$56)]
                                                   -- AGGREGATE  |UNPARTITIONED|
+                                                    exchange
                                                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                      aggregate [$$56] <- [agg-local-union_mbr($$52)]
                                                       -- AGGREGATE  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          replicate
                                                           -- REPLICATE  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              assign [$$52] <- [$$ps.getField(1)] project: [$$52]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                project ([$$ps])
                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- DATASOURCE_SCAN (test.ParkSet)  |PARTITIONED|
+                                                                    data-scan []<-[$$50, $$ps] <- test.ParkSet
+                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                  aggregate [$$59] <- [agg-global-union_mbr($$58)]
                                                   -- AGGREGATE  |UNPARTITIONED|
+                                                    exchange
                                                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                      aggregate [$$58] <- [agg-local-union_mbr($$53)]
                                                       -- AGGREGATE  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          replicate
                                                           -- REPLICATE  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              assign [$$53] <- [$$ls.getField(1)] project: [$$53]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                project ([$$ls])
                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- DATASOURCE_SCAN (test.LakeSet)  |PARTITIONED|
+                                                                    data-scan []<-[$$51, $$ls] <- test.LakeSet
+                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$64) (ASC, $$53)
                       -- STABLE_SORT [$$64(ASC), $$53(ASC)]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$64]  |PARTITIONED|
+                          unnest $$64 <- spatial-tile($$53, $$62, 100, 100) project: [$$53, $$64]
                           -- UNNEST  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              join (true)
                               -- NESTED_LOOP  |PARTITIONED|
+                                exchange
                                 -- RANDOM_PARTITION_EXCHANGE  |PARTITIONED|
+                                  replicate
                                   -- REPLICATE  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$53] <- [$$ls.getField(1)] project: [$$53]
                                       -- ASSIGN  |PARTITIONED|
+                                        project ([$$ls])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (test.LakeSet)  |PARTITIONED|
+                                            data-scan []<-[$$51, $$ls] <- test.LakeSet
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$62] <- [$$60] project: [$$62]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                      replicate
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$60] <- [get-intersection($$57, $$59)] project: [$$60]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                              join (true)
                                               -- NESTED_LOOP  |UNPARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                  aggregate [$$57] <- [agg-global-union_mbr($$56)]
                                                   -- AGGREGATE  |UNPARTITIONED|
+                                                    exchange
                                                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                      aggregate [$$56] <- [agg-local-union_mbr($$52)]
                                                       -- AGGREGATE  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          replicate
                                                           -- REPLICATE  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              assign [$$52] <- [$$ps.getField(1)] project: [$$52]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                project ([$$ps])
                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- DATASOURCE_SCAN (test.ParkSet)  |PARTITIONED|
+                                                                    data-scan []<-[$$50, $$ps] <- test.ParkSet
+                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                  aggregate [$$59] <- [agg-global-union_mbr($$58)]
                                                   -- AGGREGATE  |UNPARTITIONED|
+                                                    exchange
                                                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                      aggregate [$$58] <- [agg-local-union_mbr($$53)]
                                                       -- AGGREGATE  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          replicate
                                                           -- REPLICATE  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              assign [$$53] <- [$$ls.getField(1)] project: [$$53]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                project ([$$ls])
                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- DATASOURCE_SCAN (test.LakeSet)  |PARTITIONED|
+                                                                    data-scan []<-[$$51, $$ls] <- test.LakeSet
+                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$60] <- [get-intersection($$57, $$59)] project: [$$60]
                       -- ASSIGN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                          join (true)
                           -- NESTED_LOOP  |UNPARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                              aggregate [$$57] <- [agg-global-union_mbr($$56)]
                               -- AGGREGATE  |UNPARTITIONED|
+                                exchange
                                 -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                  aggregate [$$56] <- [agg-local-union_mbr($$52)]
                                   -- AGGREGATE  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      replicate
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$52] <- [$$ps.getField(1)] project: [$$52]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$ps])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.ParkSet)  |PARTITIONED|
+                                                data-scan []<-[$$50, $$ps] <- test.ParkSet
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                              aggregate [$$59] <- [agg-global-union_mbr($$58)]
                               -- AGGREGATE  |UNPARTITIONED|
+                                exchange
                                 -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                  aggregate [$$58] <- [agg-local-union_mbr($$53)]
                                   -- AGGREGATE  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      replicate
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$53] <- [$$ls.getField(1)] project: [$$53]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$ls])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.LakeSet)  |PARTITIONED|
+                                                data-scan []<-[$$51, $$ls] <- test.LakeSet
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/spatial_join/spatial_intersect_static_partitioning.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/spatial_join/spatial_intersect_static_partitioning.plan
index dff157c..6aa6fa4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/spatial_join/spatial_intersect_static_partitioning.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/spatial_join/spatial_intersect_static_partitioning.plan
@@ -1,29 +1,58 @@
+distribute result [$$49]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$49] <- [{"$1": $$54}] project: [$$49]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$54] <- [agg-sql-sum($$55)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$55] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (eq($$56, reference-tile($$52, $$53, rectangle: { p1: point: { x: -180.0, y: -83.0 }, p2: point: { x: 180.0, y: 90.0 }}, 10, 10, $$57)))
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (spatial-intersect($$52, $$53))
                 -- SPATIAL_JOIN [$$56, $$52] [$$57, $$53]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$56) (ASC, $$52)
                     -- STABLE_SORT [$$56(ASC), $$52(ASC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$56]  |PARTITIONED|
+                        unnest $$56 <- spatial-tile($$52, rectangle: { p1: point: { x: -180.0, y: -83.0 }, p2: point: { x: 180.0, y: 90.0 }}, 10, 10)
                         -- UNNEST  |PARTITIONED|
+                          assign [$$52] <- [$$ps.getField(1)] project: [$$52]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$ps])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.ParkSet)  |PARTITIONED|
+                                data-scan []<-[$$50, $$ps] <- test.ParkSet
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$57) (ASC, $$53)
                     -- STABLE_SORT [$$57(ASC), $$53(ASC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
+                        unnest $$57 <- spatial-tile($$53, rectangle: { p1: point: { x: -180.0, y: -83.0 }, p2: point: { x: 180.0, y: 90.0 }}, 10, 10)
                         -- UNNEST  |PARTITIONED|
+                          assign [$$53] <- [$$ls.getField(1)] project: [$$53]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$ls])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.LakeSet)  |PARTITIONED|
+                                data-scan []<-[$$51, $$ls] <- test.LakeSet
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/spatial_join/st_distance_static_partitioning.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/spatial_join/st_distance_static_partitioning.plan
index a4b7aba..b337712 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/spatial_join/st_distance_static_partitioning.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/spatial_join/st_distance_static_partitioning.plan
@@ -1,31 +1,62 @@
+distribute result [$$50]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$50] <- [{"$1": $$54}] project: [$$50]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$54] <- [agg-sql-sum($$64)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$64] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(lt(st-distance($$57, $$58), 1), eq($$65, reference-tile($$59, $$60, rectangle: { p1: point: { x: -180.0, y: -83.0 }, p2: point: { x: 180.0, y: 90.0 }}, 10, 10, $$66))))
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (spatial-intersect($$59, $$60))
                 -- SPATIAL_JOIN [$$65, $$59] [$$66, $$60]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$65) (ASC, $$59)
                     -- STABLE_SORT [$$65(ASC), $$59(ASC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$65]  |PARTITIONED|
+                        unnest $$65 <- spatial-tile($$59, rectangle: { p1: point: { x: -180.0, y: -83.0 }, p2: point: { x: 180.0, y: 90.0 }}, 10, 10)
                         -- UNNEST  |PARTITIONED|
+                          assign [$$59] <- [st-mbr-enlarge($$57, 1)]
                           -- ASSIGN  |PARTITIONED|
+                            assign [$$57] <- [$$ps.getField(1)] project: [$$57]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$ps])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.ParkSet)  |PARTITIONED|
+                                  data-scan []<-[$$51, $$ps] <- test.ParkSet
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$66) (ASC, $$60)
                     -- STABLE_SORT [$$66(ASC), $$60(ASC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$66]  |PARTITIONED|
+                        unnest $$66 <- spatial-tile($$60, rectangle: { p1: point: { x: -180.0, y: -83.0 }, p2: point: { x: 180.0, y: 90.0 }}, 10, 10)
                         -- UNNEST  |PARTITIONED|
+                          assign [$$60] <- [st-mbr($$58)]
                           -- ASSIGN  |PARTITIONED|
+                            assign [$$58] <- [$$ls.getField(1)] project: [$$58]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$ls])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.LakeSet)  |PARTITIONED|
+                                  data-scan []<-[$$52, $$ls] <- test.LakeSet
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/spatial_join/st_intersects_static_partitioning.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/spatial_join/st_intersects_static_partitioning.plan
index fae5476..c5a3369 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/spatial_join/st_intersects_static_partitioning.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/spatial_join/st_intersects_static_partitioning.plan
@@ -1,31 +1,62 @@
+distribute result [$$49]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$49] <- [{"$1": $$52}] project: [$$49]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$52] <- [agg-sql-sum($$57)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$57] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            select (and(st-intersects($$53, $$54), eq($$58, reference-tile($$55, $$56, rectangle: { p1: point: { x: -180.0, y: -83.0 }, p2: point: { x: 180.0, y: 90.0 }}, 10, 10, $$59))))
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (spatial-intersect($$55, $$56))
                 -- SPATIAL_JOIN [$$58, $$55] [$$59, $$56]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$58) (ASC, $$55)
                     -- STABLE_SORT [$$58(ASC), $$55(ASC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$58]  |PARTITIONED|
+                        unnest $$58 <- spatial-tile($$55, rectangle: { p1: point: { x: -180.0, y: -83.0 }, p2: point: { x: 180.0, y: 90.0 }}, 10, 10)
                         -- UNNEST  |PARTITIONED|
+                          assign [$$55] <- [st-mbr($$53)]
                           -- ASSIGN  |PARTITIONED|
+                            assign [$$53] <- [$$ps.getField(1)] project: [$$53]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$ps])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.ParkSet)  |PARTITIONED|
+                                  data-scan []<-[$$50, $$ps] <- test.ParkSet
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$59) (ASC, $$56)
                     -- STABLE_SORT [$$59(ASC), $$56(ASC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$59]  |PARTITIONED|
+                        unnest $$59 <- spatial-tile($$56, rectangle: { p1: point: { x: -180.0, y: -83.0 }, p2: point: { x: 180.0, y: 90.0 }}, 10, 10)
                         -- UNNEST  |PARTITIONED|
+                          assign [$$56] <- [st-mbr($$54)]
                           -- ASSIGN  |PARTITIONED|
+                            assign [$$54] <- [$$ls.getField(1)] project: [$$54]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$ls])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.LakeSet)  |PARTITIONED|
+                                  data-scan []<-[$$51, $$ls] <- test.LakeSet
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/split-materialization.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/split-materialization.plan
index 6649f67..b97e68b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/split-materialization.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/split-materialization.plan
@@ -1,27 +1,54 @@
+distribute result [$$92]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$92] <- [{"user1": {"id": $$97, "name": $$103}, "user2": {"id": $$98, "name": $$104}}] project: [$$92]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$97(ASC), $$98(ASC) ]  |PARTITIONED|
+        order (ASC, $$97) (ASC, $$98)
         -- STABLE_SORT [$$97(ASC), $$98(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (lt($$97, $$98))
             -- NESTED_LOOP  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$97, $$103] <- [$$98, $$104] project: [$$97, $$103]
                 -- ASSIGN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    replicate
                     -- REPLICATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        select (lt(count($$d.getField(4)), 2)) project: [$$98, $$104]
                         -- STREAM_SELECT  |PARTITIONED|
+                          assign [$$104] <- [$$d.getField(2)]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+                              data-scan []<-[$$98, $$d] <- TinySocial.FacebookUsers
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (lt(count($$d.getField(4)), 2)) project: [$$98, $$104]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$104] <- [$$d.getField(2)]
                       -- ASSIGN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+                          data-scan []<-[$$98, $$d] <- TinySocial.FacebookUsers
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/split-materialization_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/split-materialization_ps.plan
index 979e707..17da00a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/split-materialization_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/split-materialization_ps.plan
@@ -1,60 +1,120 @@
+distribute result [$$92]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$92] <- [{"user1": {"id": $$97, "name": $$103}, "user2": {"id": $$98, "name": $$104}}] project: [$$92]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$97) (ASC, $$98)
         -- STABLE_SORT [$$97(ASC), $$98(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$97(ASC), $$98(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$108
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (lt($$97, $$98))
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$97, $$103] <- [$$98, $$104] project: [$$97, $$103]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (lt(count($$d.getField(4)), 2)) project: [$$98, $$104]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$104] <- [$$d.getField(2)]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+                                      data-scan []<-[$$98, $$d] <- TinySocial.FacebookUsers
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (lt(count($$d.getField(4)), 2)) project: [$$98, $$104]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$104] <- [$$d.getField(2)]
                               -- ASSIGN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+                                  data-scan []<-[$$98, $$d] <- TinySocial.FacebookUsers
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$108] <- [agg-range-map($$105, $$106, $$107)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$105, $$106, $$107] <- [agg-local-sampling($$97, $$98), agg-null-writer($$97), agg-null-writer($$98)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$97, $$98])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              join (lt($$97, $$98))
                               -- NESTED_LOOP  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$97, $$103] <- [$$98, $$104] project: [$$97, $$103]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      replicate
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          select (lt(count($$d.getField(4)), 2)) project: [$$98, $$104]
                                           -- STREAM_SELECT  |PARTITIONED|
+                                            assign [$$104] <- [$$d.getField(2)]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+                                                data-scan []<-[$$98, $$d] <- TinySocial.FacebookUsers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  replicate
                                   -- REPLICATE  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      select (lt(count($$d.getField(4)), 2)) project: [$$98, $$104]
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        assign [$$104] <- [$$d.getField(2)]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+                                            data-scan []<-[$$98, $$d] <- TinySocial.FacebookUsers
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-01.plan
index b87eeb5..1e74574 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-01.plan
@@ -1,15 +1,30 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"c_id": $$18}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$t.getField("c_s"), "hello")) project: [$$18]
       -- STREAM_SELECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+          unnest-map [$$18, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$24, 1, $$24, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$24)
               -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$24])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TestOpen.idx_s)  |PARTITIONED|
+                      unnest-map [$$23, $$24] <- index-search("idx_s", 0, "Default", "test", "TestOpen", false, false, 1, $$21, 1, $$22, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$21, $$22] <- ["hello", "hello"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-02.plan
index b87eeb5..1e74574 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-02.plan
@@ -1,15 +1,30 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"c_id": $$18}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$t.getField("c_s"), "hello")) project: [$$18]
       -- STREAM_SELECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+          unnest-map [$$18, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$24, 1, $$24, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$24)
               -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$24])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TestOpen.idx_s)  |PARTITIONED|
+                      unnest-map [$$23, $$24] <- index-search("idx_s", 0, "Default", "test", "TestOpen", false, false, 1, $$21, 1, $$22, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$21, $$22] <- ["hello", "hello"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-03.plan
index b87eeb5..1e74574 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-03.plan
@@ -1,15 +1,30 @@
+distribute result [$$17]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"c_id": $$18}] project: [$$17]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$t.getField("c_s"), "hello")) project: [$$18]
       -- STREAM_SELECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.TestOpen.TestOpen)  |PARTITIONED|
+          unnest-map [$$18, $$t] <- index-search("TestOpen", 0, "Default", "test", "TestOpen", false, false, 1, $$24, 1, $$24, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$24)
               -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$24])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TestOpen.idx_s)  |PARTITIONED|
+                      unnest-map [$$23, $$24] <- index-search("idx_s", 0, "Default", "test", "TestOpen", false, false, 1, $$21, 1, $$22, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$21, $$22] <- ["hello", "hello"]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-index-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-index-01.plan
index 164bc8c..62436f1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-index-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-index-01.plan
@@ -1,19 +1,38 @@
+distribute result [$$27]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$27] <- [{"id": $$30, "fname": $$29, "lname": $$33, "age": $$34}] project: [$$27]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$30(ASC) ]  |PARTITIONED|
+        order (ASC, $$30)
         -- STABLE_SORT [$$30(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$29, "Julio"))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$34, $$33, $$29] <- [$$l.getField(3), $$l.getField(2), $$l.getField(1)] project: [$$30, $$34, $$33, $$29]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.employee.employee)  |PARTITIONED|
+                  unnest-map [$$30, $$l] <- index-search("employee", 0, "Default", "test", "employee", false, false, 1, $$38, 1, $$38, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$38)
                       -- STABLE_SORT [$$38(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$38])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- BTREE_SEARCH (test.employee.idx_employee_fname)  |PARTITIONED|
+                              unnest-map [$$37, $$38] <- index-search("idx_employee_fname", 0, "Default", "test", "employee", false, false, 1, $$35, 1, $$36, true, true, true)
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$35, $$36] <- ["Julio", "Julio"]
                                   -- ASSIGN  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-index-02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-index-02.plan
index c044320..5814e9d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-index-02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/statement-params/statement-params-index-02.plan
@@ -1,30 +1,60 @@
+distribute result [$$27]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$27] <- [{"id": $$31, "fname": $$29, "lname": $$30, "age": $$34}] project: [$$27]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$31(ASC) ]  |PARTITIONED|
+        order (ASC, $$31)
         -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(eq($$30, "Isa"), eq($$29, "Julio")))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$34, $$29, $$30] <- [$$l.getField(3), $$l.getField(1), $$l.getField(2)] project: [$$31, $$34, $$29, $$30]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.employee.employee)  |PARTITIONED|
+                  unnest-map [$$31, $$l] <- index-search("employee", 0, "Default", "test", "employee", false, false, 1, $$43, 1, $$43, true, true, true)
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      intersect [$$43] <- [[$$38], [$$42]]
                       -- INTERSECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$38)
                           -- STABLE_SORT [$$38(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$38])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.employee.idx_employee_fname)  |PARTITIONED|
+                                  unnest-map [$$37, $$38] <- index-search("idx_employee_fname", 0, "Default", "test", "employee", false, false, 1, $$35, 1, $$36, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$35, $$36] <- ["Julio", "Julio"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$42)
                           -- STABLE_SORT [$$42(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$42])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.employee.idx_employee_lname)  |PARTITIONED|
+                                  unnest-map [$$41, $$42] <- index-search("idx_employee_lname", 0, "Default", "test", "employee", false, false, 1, $$39, 1, $$40, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$39, $$40] <- ["Isa", "Isa"]
                                       -- ASSIGN  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/exists.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/exists.plan
index f738e90..26805a8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/exists.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/exists.plan
@@ -1,68 +1,124 @@
+distribute result [$$170]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$170] <- [{"cntrycode": $$cntrycode, "numcust": $$173, "totacctbal": $$174}] project: [$$170]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$cntrycode(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$196]  |PARTITIONED|
-                {
+        group by ([$$cntrycode := $$196]) decor ([]) {
+                  aggregate [$$173, $$174] <- [agg-sql-sum($$194), agg-global-sql-sum($$195)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$196]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$196]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$171]  |PARTITIONED|
-                    {
+            group by ([$$196 := $$171]) decor ([]) {
+                      aggregate [$$194, $$195] <- [agg-sql-count($$131), agg-local-sql-sum($$182)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$171]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$171] <- [substring($$184, 0, 2)] project: [$$131, $$182, $$171]
                 -- ASSIGN  |PARTITIONED|
+                  select (neq($$172, 0)) project: [$$131, $$182, $$184]
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$172, $$131, $$182, $$184])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$193]  |PARTITIONED|
-                                {
+                        group by ([$$189 := $$193]) decor ([$$131; $$182; $$184]) {
+                                  aggregate [$$172] <- [agg-sum($$192)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$193]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$193]  |PARTITIONED|
-                            -- PRE_CLUSTERED_GROUP_BY[$$187]  |PARTITIONED|
-                                    {
+                            group by ([$$193 := $$187]) decor ([$$131; $$182; $$184]) {
+                                      aggregate [$$192] <- [agg-count({"o": $$o})]
                                       -- AGGREGATE  |LOCAL|
+                                        select (not(is-missing($$188)))
                                         -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- PRE_CLUSTERED_GROUP_BY[$$187]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$187)
                                 -- STABLE_SORT [$$187(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$131, $$182, $$184, $$o, $$188, $$187])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        left outer join (eq($$180, $$183))
                                         -- HYBRID_HASH_JOIN [$$183][$$180]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$183]  |PARTITIONED|
+                                            running-aggregate [$$187] <- [create-query-uid()]
                                             -- RUNNING_AGGREGATE  |PARTITIONED|
+                                              project ([$$131, $$182, $$184, $$183])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  join (gt($$182, $$179))
                                                   -- NESTED_LOOP  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      assign [$$131] <- [{"c_acctbal": $$182, "c_custkey": $$183, "cntrycode": substring($$184, 0, 2)}]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        assign [$$184, $$183, $$182] <- [$$Customer.getField(4), $$Customer.getField(0), $$Customer.getField(5)] project: [$$184, $$183, $$182]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.Customer)  |PARTITIONED|
+                                                            data-scan []<-[$$Customer] <- test.Customer
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                      assign [$$179] <- [get-item($$145, 0)] project: [$$179]
                                                       -- ASSIGN  |UNPARTITIONED|
+                                                        aggregate [$$145] <- [listify($$191)]
                                                         -- AGGREGATE  |UNPARTITIONED|
+                                                          aggregate [$$191] <- [agg-global-sql-avg($$197)]
                                                           -- AGGREGATE  |UNPARTITIONED|
+                                                            exchange
                                                             -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                              aggregate [$$197] <- [agg-local-sql-avg($$185)]
                                                               -- AGGREGATE  |PARTITIONED|
+                                                                select (gt($$185, 0.0))
                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                  assign [$$185] <- [$$177.getField(5)] project: [$$185]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- DATASOURCE_SCAN (test.Customer)  |PARTITIONED|
+                                                                      data-scan []<-[$$177] <- test.Customer
+                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$180]  |PARTITIONED|
+                                            assign [$$188, $$180] <- [true, $$o.getField(1)]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
+                                                data-scan []<-[$$o] <- test.Orders
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/exists_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/exists_ps.plan
index 274bc84..16bd503 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/exists_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/exists_ps.plan
@@ -1,146 +1,268 @@
+distribute result [$$170]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$170] <- [{"cntrycode": $$cntrycode, "numcust": $$173, "totacctbal": $$174}] project: [$$170]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$cntrycode)
         -- STABLE_SORT [$$cntrycode(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$cntrycode(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$201
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$196]  |PARTITIONED|
-                            {
+                    group by ([$$cntrycode := $$196]) decor ([]) {
+                              aggregate [$$173, $$174] <- [agg-sql-sum($$194), agg-global-sql-sum($$195)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$196]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$196]  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$171]  |PARTITIONED|
-                                {
+                        group by ([$$196 := $$171]) decor ([]) {
+                                  aggregate [$$194, $$195] <- [agg-sql-count($$131), agg-local-sql-sum($$182)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$171]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$171] <- [substring($$184, 0, 2)] project: [$$131, $$182, $$171]
                             -- ASSIGN  |PARTITIONED|
+                              select (neq($$172, 0)) project: [$$131, $$182, $$184]
                               -- STREAM_SELECT  |PARTITIONED|
+                                project ([$$172, $$131, $$182, $$184])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- SORT_GROUP_BY[$$193]  |PARTITIONED|
-                                            {
+                                    group by ([$$189 := $$193]) decor ([$$131; $$182; $$184]) {
+                                              aggregate [$$172] <- [agg-sum($$192)]
                                               -- AGGREGATE  |LOCAL|
+                                                nested tuple source
                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                           }
+                                    -- SORT_GROUP_BY[$$193]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$193]  |PARTITIONED|
-                                        -- PRE_CLUSTERED_GROUP_BY[$$187]  |PARTITIONED|
-                                                {
+                                        group by ([$$193 := $$187]) decor ([$$131; $$182; $$184]) {
+                                                  aggregate [$$192] <- [agg-count({"o": $$o})]
                                                   -- AGGREGATE  |LOCAL|
+                                                    select (not(is-missing($$188)))
                                                     -- STREAM_SELECT  |LOCAL|
+                                                      nested tuple source
                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                               }
+                                        -- PRE_CLUSTERED_GROUP_BY[$$187]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$187)
                                             -- STABLE_SORT [$$187(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$131, $$182, $$184, $$o, $$188, $$187])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    left outer join (eq($$180, $$183))
                                                     -- HYBRID_HASH_JOIN [$$183][$$180]  |PARTITIONED|
+                                                      exchange
                                                       -- HASH_PARTITION_EXCHANGE [$$183]  |PARTITIONED|
+                                                        running-aggregate [$$187] <- [create-query-uid()]
                                                         -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                          project ([$$131, $$182, $$184, $$183])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              join (gt($$182, $$179))
                                                               -- NESTED_LOOP  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$131] <- [{"c_acctbal": $$182, "c_custkey": $$183, "cntrycode": substring($$184, 0, 2)}]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    assign [$$184, $$183, $$182] <- [$$Customer.getField(4), $$Customer.getField(0), $$Customer.getField(5)] project: [$$184, $$183, $$182]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- DATASOURCE_SCAN (test.Customer)  |PARTITIONED|
+                                                                        data-scan []<-[$$Customer] <- test.Customer
+                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                exchange
                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$179] <- [get-item($$145, 0)] project: [$$179]
                                                                   -- ASSIGN  |UNPARTITIONED|
+                                                                    aggregate [$$145] <- [listify($$191)]
                                                                     -- AGGREGATE  |UNPARTITIONED|
+                                                                      aggregate [$$191] <- [agg-global-sql-avg($$197)]
                                                                       -- AGGREGATE  |UNPARTITIONED|
+                                                                        exchange
                                                                         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                                          aggregate [$$197] <- [agg-local-sql-avg($$185)]
                                                                           -- AGGREGATE  |PARTITIONED|
+                                                                            select (gt($$185, 0.0))
                                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                                              assign [$$185] <- [$$177.getField(5)] project: [$$185]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- DATASOURCE_SCAN (test.Customer)  |PARTITIONED|
+                                                                                  data-scan []<-[$$177] <- test.Customer
+                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      empty-tuple-source
                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                      exchange
                                                       -- HASH_PARTITION_EXCHANGE [$$180]  |PARTITIONED|
+                                                        assign [$$188, $$180] <- [true, $$o.getField(1)]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
+                                                            data-scan []<-[$$o] <- test.Orders
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$201] <- [agg-range-map($$199, $$200)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$199, $$200] <- [agg-local-sampling($$cntrycode), agg-null-writer($$cntrycode)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$cntrycode])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- SORT_GROUP_BY[$$196]  |PARTITIONED|
-                                      {
+                              group by ([$$cntrycode := $$196]) decor ([]) {
+                                        aggregate [$$173, $$174] <- [agg-sql-sum($$194), agg-global-sql-sum($$195)]
                                         -- AGGREGATE  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- SORT_GROUP_BY[$$196]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$196]  |PARTITIONED|
-                                  -- SORT_GROUP_BY[$$171]  |PARTITIONED|
-                                          {
+                                  group by ([$$196 := $$171]) decor ([]) {
+                                            aggregate [$$194, $$195] <- [agg-sql-count($$131), agg-local-sql-sum($$182)]
                                             -- AGGREGATE  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                          }
+                                         }
+                                  -- SORT_GROUP_BY[$$171]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$171] <- [substring($$184, 0, 2)] project: [$$131, $$182, $$171]
                                       -- ASSIGN  |PARTITIONED|
+                                        select (neq($$172, 0)) project: [$$131, $$182, $$184]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          project ([$$172, $$131, $$182, $$184])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- SORT_GROUP_BY[$$193]  |PARTITIONED|
-                                                      {
+                                              group by ([$$189 := $$193]) decor ([$$131; $$182; $$184]) {
+                                                        aggregate [$$172] <- [agg-sum($$192)]
                                                         -- AGGREGATE  |LOCAL|
+                                                          nested tuple source
                                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                      }
+                                                     }
+                                              -- SORT_GROUP_BY[$$193]  |PARTITIONED|
+                                                exchange
                                                 -- HASH_PARTITION_EXCHANGE [$$193]  |PARTITIONED|
-                                                  -- PRE_CLUSTERED_GROUP_BY[$$187]  |PARTITIONED|
-                                                          {
+                                                  group by ([$$193 := $$187]) decor ([$$131; $$182; $$184]) {
+                                                            aggregate [$$192] <- [agg-count({"o": $$o})]
                                                             -- AGGREGATE  |LOCAL|
+                                                              select (not(is-missing($$188)))
                                                               -- STREAM_SELECT  |LOCAL|
+                                                                nested tuple source
                                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                          }
+                                                         }
+                                                  -- PRE_CLUSTERED_GROUP_BY[$$187]  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      order (ASC, $$187)
                                                       -- STABLE_SORT [$$187(ASC)]  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          project ([$$131, $$182, $$184, $$o, $$188, $$187])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              left outer join (eq($$180, $$183))
                                                               -- HYBRID_HASH_JOIN [$$183][$$180]  |PARTITIONED|
+                                                                exchange
                                                                 -- HASH_PARTITION_EXCHANGE [$$183]  |PARTITIONED|
+                                                                  running-aggregate [$$187] <- [create-query-uid()]
                                                                   -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                                    project ([$$131, $$182, $$184, $$183])
                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        join (gt($$182, $$179))
                                                                         -- NESTED_LOOP  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            assign [$$131] <- [{"c_acctbal": $$182, "c_custkey": $$183, "cntrycode": substring($$184, 0, 2)}]
                                                                             -- ASSIGN  |PARTITIONED|
+                                                                              assign [$$184, $$183, $$182] <- [$$Customer.getField(4), $$Customer.getField(0), $$Customer.getField(5)] project: [$$184, $$183, $$182]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- DATASOURCE_SCAN (test.Customer)  |PARTITIONED|
+                                                                                  data-scan []<-[$$Customer] <- test.Customer
+                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      empty-tuple-source
                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                          exchange
                                                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                            assign [$$179] <- [get-item($$145, 0)] project: [$$179]
                                                                             -- ASSIGN  |UNPARTITIONED|
+                                                                              aggregate [$$145] <- [listify($$191)]
                                                                               -- AGGREGATE  |UNPARTITIONED|
+                                                                                aggregate [$$191] <- [agg-global-sql-avg($$197)]
                                                                                 -- AGGREGATE  |UNPARTITIONED|
+                                                                                  exchange
                                                                                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                                                    aggregate [$$197] <- [agg-local-sql-avg($$185)]
                                                                                     -- AGGREGATE  |PARTITIONED|
+                                                                                      select (gt($$185, 0.0))
                                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                                        assign [$$185] <- [$$177.getField(5)] project: [$$185]
                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                            -- DATASOURCE_SCAN (test.Customer)  |PARTITIONED|
+                                                                                            data-scan []<-[$$177] <- test.Customer
+                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                empty-tuple-source
                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                exchange
                                                                 -- HASH_PARTITION_EXCHANGE [$$180]  |PARTITIONED|
+                                                                  assign [$$188, $$180] <- [true, $$o.getField(1)]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
+                                                                      data-scan []<-[$$o] <- test.Orders
+                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in.plan
index 23197c9..b9e0186 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in.plan
@@ -1,31 +1,59 @@
+distribute result [$$47]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$47] <- [{"customer_name": $$53}] project: [$$47]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$53(ASC) ]  |PARTITIONED|
+        select ($$41) project: [$$53]
         -- STREAM_SELECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
-                    {
+            group by ([$$53 := $$48]) decor ([]) {
+                      aggregate [$$41] <- [non-empty-stream()]
                       -- AGGREGATE  |LOCAL|
+                        select (not(is-missing($$52)))
                         -- STREAM_SELECT  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$48)
                 -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$52, $$48])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        left outer join (eq($$48, $$37))
                         -- HYBRID_HASH_JOIN [$$48][$$37]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+                            select (eq($$c.getField("c_nationkey"), 5)) project: [$$48]
                             -- STREAM_SELECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                data-scan []<-[$$48, $$c] <- test.Customers
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                            assign [$$52, $$37] <- [true, $$o.getField("o_custkey")] project: [$$52, $$37]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$o])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
+                                  data-scan []<-[$$49, $$o] <- test.Orders
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_1.plan
index 0afd76c..bb0cc7a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_1.plan
@@ -1,16 +1,32 @@
+distribute result [$$21]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+    order (ASC, $$21)
     -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        project ([$$21])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$22, $$16))
             -- HYBRID_HASH_JOIN [$$16][$$22]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$16] <- [$$c.getField(1)] project: [$$21, $$16]
                 -- ASSIGN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                    data-scan []<-[$$21, $$c] <- tpch.Customer
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                unnest $$22 <- scan-collection(array: [ "Customer#000000003", "Customer#000000002", "Customer#000000001" ])
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_1_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_1_ps.plan
index d3629e5..b192ab7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_1_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_1_ps.plan
@@ -1,39 +1,78 @@
+distribute result [$$21]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    order (ASC, $$21)
     -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+      exchange
       -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+        forward: shared-variable = $$26
         -- FORWARD  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            replicate
             -- REPLICATE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$21])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$22, $$16))
                     -- HYBRID_HASH_JOIN [$$16][$$22]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$16] <- [$$c.getField(1)] project: [$$21, $$16]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                            data-scan []<-[$$21, $$c] <- tpch.Customer
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        unnest $$22 <- scan-collection(array: [ "Customer#000000003", "Customer#000000002", "Customer#000000001" ])
                         -- UNNEST  |UNPARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+          exchange
           -- BROADCAST_EXCHANGE  |PARTITIONED|
+            aggregate [$$26] <- [agg-range-map($$24, $$25)]
             -- AGGREGATE  |UNPARTITIONED|
+              exchange
               -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                aggregate [$$24, $$25] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                 -- AGGREGATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    replicate
                     -- REPLICATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$21])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (eq($$22, $$16))
                             -- HYBRID_HASH_JOIN [$$16][$$22]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$16] <- [$$c.getField(1)] project: [$$21, $$16]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                    data-scan []<-[$$21, $$c] <- tpch.Customer
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                unnest $$22 <- scan-collection(array: [ "Customer#000000003", "Customer#000000002", "Customer#000000001" ])
                                 -- UNNEST  |UNPARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_2.plan
index ed5067c..7869a45 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_2.plan
@@ -1,26 +1,49 @@
+distribute result [$$26]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$26(ASC) ]  |PARTITIONED|
+    select ($$18) project: [$$26]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
-                {
+        group by ([$$26 := $$22]) decor ([]) {
+                  aggregate [$$18] <- [non-empty-stream()]
                   -- AGGREGATE  |LOCAL|
+                    select (not(is-missing($$25)))
                     -- STREAM_SELECT  |LOCAL|
+                      nested tuple source
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$22)
             -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                project ([$$25, $$22])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    left outer join (eq($$23, $#1))
                     -- HYBRID_HASH_JOIN [$$23][$#1]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
+                        assign [$$23] <- [$$c.getField(1)] project: [$$22, $$23]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                            data-scan []<-[$$22, $$c] <- tpch.Customer
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                        assign [$$25] <- [true]
                         -- ASSIGN  |UNPARTITIONED|
+                          unnest $#1 <- scan-collection(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ])
                           -- UNNEST  |UNPARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_2_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_2_ps.plan
index d587010..22cc503 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_2_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_2_ps.plan
@@ -1,63 +1,120 @@
+distribute result [$$26]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    order (ASC, $$26)
     -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+      exchange
       -- RANGE_PARTITION_EXCHANGE [$$26(ASC)]  |PARTITIONED|
+        forward: shared-variable = $$29
         -- FORWARD  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            replicate
             -- REPLICATE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select ($$18) project: [$$26]
                 -- STREAM_SELECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
-                            {
+                    group by ([$$26 := $$22]) decor ([]) {
+                              aggregate [$$18] <- [non-empty-stream()]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$25)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$22)
                         -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                            project ([$$25, $$22])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                left outer join (eq($$23, $#1))
                                 -- HYBRID_HASH_JOIN [$$23][$#1]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
+                                    assign [$$23] <- [$$c.getField(1)] project: [$$22, $$23]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                        data-scan []<-[$$22, $$c] <- tpch.Customer
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                                    assign [$$25] <- [true]
                                     -- ASSIGN  |UNPARTITIONED|
+                                      unnest $#1 <- scan-collection(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ])
                                       -- UNNEST  |UNPARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+          exchange
           -- BROADCAST_EXCHANGE  |PARTITIONED|
+            aggregate [$$29] <- [agg-range-map($$27, $$28)]
             -- AGGREGATE  |UNPARTITIONED|
+              exchange
               -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                aggregate [$$27, $$28] <- [agg-local-sampling($$26), agg-null-writer($$26)]
                 -- AGGREGATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    replicate
                     -- REPLICATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        select ($$18) project: [$$26]
                         -- STREAM_SELECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
-                                    {
+                            group by ([$$26 := $$22]) decor ([]) {
+                                      aggregate [$$18] <- [non-empty-stream()]
                                       -- AGGREGATE  |LOCAL|
+                                        select (not(is-missing($$25)))
                                         -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$22)
                                 -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                                    project ([$$25, $$22])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        left outer join (eq($$23, $#1))
                                         -- HYBRID_HASH_JOIN [$$23][$#1]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
+                                            assign [$$23] <- [$$c.getField(1)] project: [$$22, $$23]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                                data-scan []<-[$$22, $$c] <- tpch.Customer
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                                            assign [$$25] <- [true]
                                             -- ASSIGN  |UNPARTITIONED|
+                                              unnest $#1 <- scan-collection(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ])
                                               -- UNNEST  |UNPARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_3.plan
index 0afd76c..bb0cc7a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_3.plan
@@ -1,16 +1,32 @@
+distribute result [$$21]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+    order (ASC, $$21)
     -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        project ([$$21])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$22, $$16))
             -- HYBRID_HASH_JOIN [$$16][$$22]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$16] <- [$$c.getField(1)] project: [$$21, $$16]
                 -- ASSIGN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                    data-scan []<-[$$21, $$c] <- tpch.Customer
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                unnest $$22 <- scan-collection(array: [ "Customer#000000003", "Customer#000000002", "Customer#000000001" ])
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_3_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_3_ps.plan
index d3629e5..b192ab7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_3_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_3_ps.plan
@@ -1,39 +1,78 @@
+distribute result [$$21]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    order (ASC, $$21)
     -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+      exchange
       -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+        forward: shared-variable = $$26
         -- FORWARD  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            replicate
             -- REPLICATE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$21])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$22, $$16))
                     -- HYBRID_HASH_JOIN [$$16][$$22]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$16] <- [$$c.getField(1)] project: [$$21, $$16]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                            data-scan []<-[$$21, $$c] <- tpch.Customer
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        unnest $$22 <- scan-collection(array: [ "Customer#000000003", "Customer#000000002", "Customer#000000001" ])
                         -- UNNEST  |UNPARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+          exchange
           -- BROADCAST_EXCHANGE  |PARTITIONED|
+            aggregate [$$26] <- [agg-range-map($$24, $$25)]
             -- AGGREGATE  |UNPARTITIONED|
+              exchange
               -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                aggregate [$$24, $$25] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                 -- AGGREGATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    replicate
                     -- REPLICATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$21])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (eq($$22, $$16))
                             -- HYBRID_HASH_JOIN [$$16][$$22]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$16] <- [$$c.getField(1)] project: [$$21, $$16]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                    data-scan []<-[$$21, $$c] <- tpch.Customer
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                unnest $$22 <- scan-collection(array: [ "Customer#000000003", "Customer#000000002", "Customer#000000001" ])
                                 -- UNNEST  |UNPARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_4.plan
index 0f33a1e..a4e3699 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_4.plan
@@ -1,26 +1,49 @@
+distribute result [$$25]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+    select ($$17) project: [$$25]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$21]  |PARTITIONED|
-                {
+        group by ([$$25 := $$21]) decor ([]) {
+                  aggregate [$$17] <- [non-empty-stream()]
                   -- AGGREGATE  |LOCAL|
+                    select (not(is-missing($$24)))
                     -- STREAM_SELECT  |LOCAL|
+                      nested tuple source
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$21]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$21)
             -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$21]  |PARTITIONED|
+                project ([$$24, $$21])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    left outer join (eq($$22, $#1))
                     -- HYBRID_HASH_JOIN [$$22][$#1]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                        assign [$$22] <- [$$c.getField(1)] project: [$$21, $$22]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                            data-scan []<-[$$21, $$c] <- tpch.Customer
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                        assign [$$24] <- [true]
                         -- ASSIGN  |UNPARTITIONED|
+                          unnest $#1 <- scan-collection(cast(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ]))
                           -- UNNEST  |UNPARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_4_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_4_ps.plan
index 55d6709..6c20d83 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_4_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_4_ps.plan
@@ -1,63 +1,120 @@
+distribute result [$$25]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    order (ASC, $$25)
     -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+      exchange
       -- RANGE_PARTITION_EXCHANGE [$$25(ASC)]  |PARTITIONED|
+        forward: shared-variable = $$28
         -- FORWARD  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            replicate
             -- REPLICATE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select ($$17) project: [$$25]
                 -- STREAM_SELECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$21]  |PARTITIONED|
-                            {
+                    group by ([$$25 := $$21]) decor ([]) {
+                              aggregate [$$17] <- [non-empty-stream()]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$24)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$21]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$21)
                         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$21]  |PARTITIONED|
+                            project ([$$24, $$21])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                left outer join (eq($$22, $#1))
                                 -- HYBRID_HASH_JOIN [$$22][$#1]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                                    assign [$$22] <- [$$c.getField(1)] project: [$$21, $$22]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                        data-scan []<-[$$21, $$c] <- tpch.Customer
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                                    assign [$$24] <- [true]
                                     -- ASSIGN  |UNPARTITIONED|
+                                      unnest $#1 <- scan-collection(cast(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ]))
                                       -- UNNEST  |UNPARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+          exchange
           -- BROADCAST_EXCHANGE  |PARTITIONED|
+            aggregate [$$28] <- [agg-range-map($$26, $$27)]
             -- AGGREGATE  |UNPARTITIONED|
+              exchange
               -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                aggregate [$$26, $$27] <- [agg-local-sampling($$25), agg-null-writer($$25)]
                 -- AGGREGATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    replicate
                     -- REPLICATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        select ($$17) project: [$$25]
                         -- STREAM_SELECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- PRE_CLUSTERED_GROUP_BY[$$21]  |PARTITIONED|
-                                    {
+                            group by ([$$25 := $$21]) decor ([]) {
+                                      aggregate [$$17] <- [non-empty-stream()]
                                       -- AGGREGATE  |LOCAL|
+                                        select (not(is-missing($$24)))
                                         -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- PRE_CLUSTERED_GROUP_BY[$$21]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$21)
                                 -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$21]  |PARTITIONED|
+                                    project ([$$24, $$21])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        left outer join (eq($$22, $#1))
                                         -- HYBRID_HASH_JOIN [$$22][$#1]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                                            assign [$$22] <- [$$c.getField(1)] project: [$$21, $$22]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                                data-scan []<-[$$21, $$c] <- tpch.Customer
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                                            assign [$$24] <- [true]
                                             -- ASSIGN  |UNPARTITIONED|
+                                              unnest $#1 <- scan-collection(cast(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ]))
                                               -- UNNEST  |UNPARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_5.plan
index 0afd76c..bb0cc7a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_5.plan
@@ -1,16 +1,32 @@
+distribute result [$$21]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+    order (ASC, $$21)
     -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        project ([$$21])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$22, $$16))
             -- HYBRID_HASH_JOIN [$$16][$$22]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$16] <- [$$c.getField(1)] project: [$$21, $$16]
                 -- ASSIGN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                    data-scan []<-[$$21, $$c] <- tpch.Customer
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                unnest $$22 <- scan-collection(array: [ "Customer#000000003", "Customer#000000002", "Customer#000000001" ])
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_5_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_5_ps.plan
index d3629e5..b192ab7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_5_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_5_ps.plan
@@ -1,39 +1,78 @@
+distribute result [$$21]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    order (ASC, $$21)
     -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+      exchange
       -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+        forward: shared-variable = $$26
         -- FORWARD  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            replicate
             -- REPLICATE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$21])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$22, $$16))
                     -- HYBRID_HASH_JOIN [$$16][$$22]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$16] <- [$$c.getField(1)] project: [$$21, $$16]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                            data-scan []<-[$$21, $$c] <- tpch.Customer
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        unnest $$22 <- scan-collection(array: [ "Customer#000000003", "Customer#000000002", "Customer#000000001" ])
                         -- UNNEST  |UNPARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+          exchange
           -- BROADCAST_EXCHANGE  |PARTITIONED|
+            aggregate [$$26] <- [agg-range-map($$24, $$25)]
             -- AGGREGATE  |UNPARTITIONED|
+              exchange
               -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                aggregate [$$24, $$25] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                 -- AGGREGATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    replicate
                     -- REPLICATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$21])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (eq($$22, $$16))
                             -- HYBRID_HASH_JOIN [$$16][$$22]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$16] <- [$$c.getField(1)] project: [$$21, $$16]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                    data-scan []<-[$$21, $$c] <- tpch.Customer
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                unnest $$22 <- scan-collection(array: [ "Customer#000000003", "Customer#000000002", "Customer#000000001" ])
                                 -- UNNEST  |UNPARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_6.plan
index ed5067c..7869a45 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_6.plan
@@ -1,26 +1,49 @@
+distribute result [$$26]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$26(ASC) ]  |PARTITIONED|
+    select ($$18) project: [$$26]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
-                {
+        group by ([$$26 := $$22]) decor ([]) {
+                  aggregate [$$18] <- [non-empty-stream()]
                   -- AGGREGATE  |LOCAL|
+                    select (not(is-missing($$25)))
                     -- STREAM_SELECT  |LOCAL|
+                      nested tuple source
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$22)
             -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                project ([$$25, $$22])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    left outer join (eq($$23, $#1))
                     -- HYBRID_HASH_JOIN [$$23][$#1]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
+                        assign [$$23] <- [$$c.getField(1)] project: [$$22, $$23]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                            data-scan []<-[$$22, $$c] <- tpch.Customer
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                        assign [$$25] <- [true]
                         -- ASSIGN  |UNPARTITIONED|
+                          unnest $#1 <- scan-collection(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ])
                           -- UNNEST  |UNPARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_6_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_6_ps.plan
index d587010..22cc503 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_6_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_as_or_6_ps.plan
@@ -1,63 +1,120 @@
+distribute result [$$26]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    order (ASC, $$26)
     -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+      exchange
       -- RANGE_PARTITION_EXCHANGE [$$26(ASC)]  |PARTITIONED|
+        forward: shared-variable = $$29
         -- FORWARD  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            replicate
             -- REPLICATE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select ($$18) project: [$$26]
                 -- STREAM_SELECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
-                            {
+                    group by ([$$26 := $$22]) decor ([]) {
+                              aggregate [$$18] <- [non-empty-stream()]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$25)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$22)
                         -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                            project ([$$25, $$22])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                left outer join (eq($$23, $#1))
                                 -- HYBRID_HASH_JOIN [$$23][$#1]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
+                                    assign [$$23] <- [$$c.getField(1)] project: [$$22, $$23]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                        data-scan []<-[$$22, $$c] <- tpch.Customer
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                                    assign [$$25] <- [true]
                                     -- ASSIGN  |UNPARTITIONED|
+                                      unnest $#1 <- scan-collection(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ])
                                       -- UNNEST  |UNPARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+          exchange
           -- BROADCAST_EXCHANGE  |PARTITIONED|
+            aggregate [$$29] <- [agg-range-map($$27, $$28)]
             -- AGGREGATE  |UNPARTITIONED|
+              exchange
               -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                aggregate [$$27, $$28] <- [agg-local-sampling($$26), agg-null-writer($$26)]
                 -- AGGREGATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    replicate
                     -- REPLICATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        select ($$18) project: [$$26]
                         -- STREAM_SELECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
-                                    {
+                            group by ([$$26 := $$22]) decor ([]) {
+                                      aggregate [$$18] <- [non-empty-stream()]
                                       -- AGGREGATE  |LOCAL|
+                                        select (not(is-missing($$25)))
                                         -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$22)
                                 -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                                    project ([$$25, $$22])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        left outer join (eq($$23, $#1))
                                         -- HYBRID_HASH_JOIN [$$23][$#1]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
+                                            assign [$$23] <- [$$c.getField(1)] project: [$$22, $$23]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                                data-scan []<-[$$22, $$c] <- tpch.Customer
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                                            assign [$$25] <- [true]
                                             -- ASSIGN  |UNPARTITIONED|
+                                              unnest $#1 <- scan-collection(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ])
                                               -- UNNEST  |UNPARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_correlated.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_correlated.plan
index c865744..47e9c74 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_correlated.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_correlated.plan
@@ -1,29 +1,55 @@
+distribute result [$$50]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$50] <- [{"customer_name": $$58}] project: [$$50]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$58(ASC) ]  |PARTITIONED|
+        select ($$44) project: [$$58]
         -- STREAM_SELECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- PRE_CLUSTERED_GROUP_BY[$$52]  |PARTITIONED|
-                    {
+            group by ([$$58 := $$52]) decor ([]) {
+                      aggregate [$$44] <- [non-empty-stream()]
                       -- AGGREGATE  |LOCAL|
+                        select (and(eq($$52, $$51), not(is-missing($$57))))
                         -- STREAM_SELECT  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- PRE_CLUSTERED_GROUP_BY[$$52]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$52)
                 -- STABLE_SORT [$$52(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    left outer join (eq($$52, $$51))
                     -- HYBRID_HASH_JOIN [$$52][$$51]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$52]  |PARTITIONED|
+                        select (eq($$c.getField("c_nationkey"), 5)) project: [$$52]
                         -- STREAM_SELECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                            data-scan []<-[$$52, $$c] <- test.Customers
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$51]  |PARTITIONED|
+                        assign [$$57, $$51] <- [true, $$o.getField("o_custkey")] project: [$$51, $$57]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$o])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
+                              data-scan []<-[$$53, $$o] <- test.Orders
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_correlated_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_correlated_ps.plan
index e53c8b9..ef475c2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_correlated_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_correlated_ps.plan
@@ -1,67 +1,128 @@
+distribute result [$$50]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$50] <- [{"customer_name": $$58}] project: [$$50]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$58)
         -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$58(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$61
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select ($$44) project: [$$58]
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- PRE_CLUSTERED_GROUP_BY[$$52]  |PARTITIONED|
-                                {
+                        group by ([$$58 := $$52]) decor ([]) {
+                                  aggregate [$$44] <- [non-empty-stream()]
                                   -- AGGREGATE  |LOCAL|
+                                    select (and(eq($$52, $$51), not(is-missing($$57))))
                                     -- STREAM_SELECT  |LOCAL|
+                                      nested tuple source
                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- PRE_CLUSTERED_GROUP_BY[$$52]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$52)
                             -- STABLE_SORT [$$52(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                left outer join (eq($$52, $$51))
                                 -- HYBRID_HASH_JOIN [$$52][$$51]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$52]  |PARTITIONED|
+                                    select (eq($$c.getField("c_nationkey"), 5)) project: [$$52]
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                        data-scan []<-[$$52, $$c] <- test.Customers
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$51]  |PARTITIONED|
+                                    assign [$$57, $$51] <- [true, $$o.getField("o_custkey")] project: [$$51, $$57]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$o])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
+                                          data-scan []<-[$$53, $$o] <- test.Orders
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$61] <- [agg-range-map($$59, $$60)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$59, $$60] <- [agg-local-sampling($$58), agg-null-writer($$58)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select ($$44) project: [$$58]
                             -- STREAM_SELECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- PRE_CLUSTERED_GROUP_BY[$$52]  |PARTITIONED|
-                                        {
+                                group by ([$$58 := $$52]) decor ([]) {
+                                          aggregate [$$44] <- [non-empty-stream()]
                                           -- AGGREGATE  |LOCAL|
+                                            select (and(eq($$52, $$51), not(is-missing($$57))))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- PRE_CLUSTERED_GROUP_BY[$$52]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$52)
                                     -- STABLE_SORT [$$52(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        left outer join (eq($$52, $$51))
                                         -- HYBRID_HASH_JOIN [$$52][$$51]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$52]  |PARTITIONED|
+                                            select (eq($$c.getField("c_nationkey"), 5)) project: [$$52]
                                             -- STREAM_SELECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                                data-scan []<-[$$52, $$c] <- test.Customers
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$51]  |PARTITIONED|
+                                            assign [$$57, $$51] <- [true, $$o.getField("o_custkey")] project: [$$51, $$57]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$o])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
+                                                  data-scan []<-[$$53, $$o] <- test.Orders
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_3.plan
index 2187811..3663e21 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_3.plan
@@ -1,64 +1,119 @@
+distribute result [$$96]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$96] <- [{"cid": $$107, "pid": $$103, "ts": $$99}] project: [$$96]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$107(ASC) ]  |PARTITIONED|
+        order (ASC, $$107)
         -- STABLE_SORT [$$107(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select ($$90) project: [$$107, $$103, $$99]
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$90, $$99, $$103, $$107])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- PRE_CLUSTERED_GROUP_BY[$$110]  |PARTITIONED|
-                          {
+                  group by ([$$112 := $$110]) decor ([$$99; $$103; $$107]) {
+                            aggregate [$$90] <- [non-empty-stream()]
                             -- AGGREGATE  |LOCAL|
+                              select (not(is-missing($$111)))
                               -- STREAM_SELECT  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                          }
+                         }
+                  -- PRE_CLUSTERED_GROUP_BY[$$110]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$110)
                       -- STABLE_SORT [$$110(ASC)]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$110]  |PARTITIONED|
+                          project ([$$107, $$103, $$99, $$111, $$110])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              left outer join (eq($$103, $$pid))
                               -- HYBRID_HASH_JOIN [$$103][$$pid]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$103]  |PARTITIONED|
+                                  select (ge($$99, 2000))
                                   -- STREAM_SELECT  |PARTITIONED|
+                                    running-aggregate [$$110] <- [create-query-uid()]
                                     -- RUNNING_AGGREGATE  |PARTITIONED|
+                                      assign [$$99, $$103] <- [$$i1.getField("ts"), $$i1.getField("pid")] project: [$$107, $$103, $$99]
                                       -- ASSIGN  |PARTITIONED|
+                                        unnest $$i1 <- scan-collection($$104) project: [$$107, $$i1]
                                         -- UNNEST  |PARTITIONED|
+                                          assign [$$107, $$104] <- [$$c1.getField("cid"), $$c1.getField("items")] project: [$$107, $$104]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$c1] <- [$$c2] project: [$$c1]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    project ([$$c2])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.cart)  |PARTITIONED|
+                                                        data-scan []<-[$$101, $$c2] <- test.cart
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$111] <- [true]
                                   -- ASSIGN  |PARTITIONED|
+                                    select (gt($$102, 1)) project: [$$pid]
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- SORT_GROUP_BY[$$114]  |PARTITIONED|
-                                                {
+                                        group by ([$$pid := $$114]) decor ([]) {
+                                                  aggregate [$$102] <- [agg-sql-sum($$113)]
                                                   -- AGGREGATE  |LOCAL|
+                                                    nested tuple source
                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                               }
+                                        -- SORT_GROUP_BY[$$114]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$114]  |PARTITIONED|
-                                            -- SORT_GROUP_BY[$$98]  |PARTITIONED|
-                                                    {
+                                            group by ([$$114 := $$98]) decor ([]) {
+                                                      aggregate [$$113] <- [agg-sql-count(1)]
                                                       -- AGGREGATE  |LOCAL|
+                                                        nested tuple source
                                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                    }
+                                                   }
+                                            -- SORT_GROUP_BY[$$98]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                select (ge($$i2.getField("ts"), 2000)) project: [$$98]
                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                  assign [$$98] <- [$$i2.getField("pid")]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    unnest $$i2 <- scan-collection($$105) project: [$$i2]
                                                     -- UNNEST  |PARTITIONED|
+                                                      assign [$$105] <- [$$c2.getField("items")] project: [$$105]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          replicate
                                                           -- REPLICATE  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              project ([$$c2])
                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- DATASOURCE_SCAN (test.cart)  |PARTITIONED|
+                                                                  data-scan []<-[$$101, $$c2] <- test.cart
+                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_4.plan
index ce56876..a684e10 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_4.plan
@@ -1,64 +1,119 @@
+distribute result [$$107]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$107] <- [{"cid": $$127, "pid": $$123, "ts": $$110}] project: [$$107]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$127(ASC) ]  |PARTITIONED|
+        order (ASC, $$127)
         -- STABLE_SORT [$$127(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select ($$101) project: [$$127, $$123, $$110]
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$101, $$123, $$110, $$127])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
-                          {
+                  group by ([$$132 := $$130]) decor ([$$123; $$110; $$127]) {
+                            aggregate [$$101] <- [non-empty-stream()]
                             -- AGGREGATE  |LOCAL|
+                              select (not(is-missing($$131)))
                               -- STREAM_SELECT  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                          }
+                         }
+                  -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$130)
                       -- STABLE_SORT [$$130(ASC)]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$130]  |PARTITIONED|
+                          project ([$$127, $$123, $$110, $$131, $$130])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              left outer join (eq($$123, $$115))
                               -- HYBRID_HASH_JOIN [$$123][$$115]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$123]  |PARTITIONED|
+                                  select (ge($$110, 2000))
                                   -- STREAM_SELECT  |PARTITIONED|
+                                    running-aggregate [$$130] <- [create-query-uid()]
                                     -- RUNNING_AGGREGATE  |PARTITIONED|
+                                      assign [$$110, $$123] <- [$$i1.getField("ts"), $$i1.getField("pid")] project: [$$127, $$123, $$110]
                                       -- ASSIGN  |PARTITIONED|
+                                        unnest $$i1 <- scan-collection($$124) project: [$$127, $$i1]
                                         -- UNNEST  |PARTITIONED|
+                                          assign [$$127, $$124] <- [$$c1.getField("cid"), $$c1.getField("items")] project: [$$127, $$124]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$c1] <- [$$120] project: [$$c1]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    project ([$$120])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.cart)  |PARTITIONED|
+                                                        data-scan []<-[$$121, $$120] <- test.cart
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$131] <- [true]
                                   -- ASSIGN  |PARTITIONED|
+                                    select (gt($$116, 1)) project: [$$115]
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- SORT_GROUP_BY[$$134]  |PARTITIONED|
-                                                {
+                                        group by ([$$115 := $$134]) decor ([]) {
+                                                  aggregate [$$116] <- [agg-sql-sum($$133)]
                                                   -- AGGREGATE  |LOCAL|
+                                                    nested tuple source
                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                               }
+                                        -- SORT_GROUP_BY[$$134]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$134]  |PARTITIONED|
-                                            -- SORT_GROUP_BY[$$117]  |PARTITIONED|
-                                                    {
+                                            group by ([$$134 := $$117]) decor ([]) {
+                                                      aggregate [$$133] <- [agg-sql-count(1)]
                                                       -- AGGREGATE  |LOCAL|
+                                                        nested tuple source
                                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                    }
+                                                   }
+                                            -- SORT_GROUP_BY[$$117]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                select (ge($$118.getField("ts"), 2000)) project: [$$117]
                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                  assign [$$117] <- [$$118.getField("pid")]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    unnest $$118 <- scan-collection($$125) project: [$$118]
                                                     -- UNNEST  |PARTITIONED|
+                                                      assign [$$125] <- [$$120.getField("items")] project: [$$125]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          replicate
                                                           -- REPLICATE  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              project ([$$120])
                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- DATASOURCE_SCAN (test.cart)  |PARTITIONED|
+                                                                  data-scan []<-[$$121, $$120] <- test.cart
+                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_5.plan
index ecaefdf..5cb2dce 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_5.plan
@@ -1,64 +1,119 @@
+distribute result [$$107]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$107] <- [{"cid": $$127, "pid": $$123, "ts": $$110}] project: [$$107]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$127(ASC) ]  |PARTITIONED|
+        order (ASC, $$127)
         -- STABLE_SORT [$$127(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select ($$101) project: [$$127, $$123, $$110]
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$101, $$123, $$110, $$127])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
-                          {
+                  group by ([$$132 := $$130]) decor ([$$123; $$110; $$127]) {
+                            aggregate [$$101] <- [non-empty-stream()]
                             -- AGGREGATE  |LOCAL|
+                              select (not(is-missing($$131)))
                               -- STREAM_SELECT  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                          }
+                         }
+                  -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$130)
                       -- STABLE_SORT [$$130(ASC)]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$130]  |PARTITIONED|
+                          project ([$$127, $$123, $$110, $$131, $$130])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              left outer join (eq($$123, $$115))
                               -- HYBRID_HASH_JOIN [$$123][$$115]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  select (ge($$110, 2000))
                                   -- STREAM_SELECT  |PARTITIONED|
+                                    running-aggregate [$$130] <- [create-query-uid()]
                                     -- RUNNING_AGGREGATE  |PARTITIONED|
+                                      assign [$$110, $$123] <- [$$i1.getField("ts"), $$i1.getField("pid")] project: [$$127, $$123, $$110]
                                       -- ASSIGN  |PARTITIONED|
+                                        unnest $$i1 <- scan-collection($$124) project: [$$127, $$i1]
                                         -- UNNEST  |PARTITIONED|
+                                          assign [$$127, $$124] <- [$$c1.getField("cid"), $$c1.getField("items")] project: [$$127, $$124]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$c1] <- [$$120] project: [$$c1]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    project ([$$120])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.cart)  |PARTITIONED|
+                                                        data-scan []<-[$$121, $$120] <- test.cart
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  assign [$$131] <- [true]
                                   -- ASSIGN  |PARTITIONED|
+                                    select (gt($$116, 1)) project: [$$115]
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- SORT_GROUP_BY[$$134]  |PARTITIONED|
-                                                {
+                                        group by ([$$115 := $$134]) decor ([]) {
+                                                  aggregate [$$116] <- [agg-sql-sum($$133)]
                                                   -- AGGREGATE  |LOCAL|
+                                                    nested tuple source
                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                               }
+                                        -- SORT_GROUP_BY[$$134]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$134]  |PARTITIONED|
-                                            -- SORT_GROUP_BY[$$117]  |PARTITIONED|
-                                                    {
+                                            group by ([$$134 := $$117]) decor ([]) {
+                                                      aggregate [$$133] <- [agg-sql-count(1)]
                                                       -- AGGREGATE  |LOCAL|
+                                                        nested tuple source
                                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                    }
+                                                   }
+                                            -- SORT_GROUP_BY[$$117]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                select (ge($$118.getField("ts"), 2000)) project: [$$117]
                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                  assign [$$117] <- [$$118.getField("pid")]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    unnest $$118 <- scan-collection($$125) project: [$$118]
                                                     -- UNNEST  |PARTITIONED|
+                                                      assign [$$125] <- [$$120.getField("items")] project: [$$125]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          replicate
                                                           -- REPLICATE  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              project ([$$120])
                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- DATASOURCE_SCAN (test.cart)  |PARTITIONED|
+                                                                  data-scan []<-[$$121, $$120] <- test.cart
+                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_6.plan
index 3febf26..44f61a1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_6.plan
@@ -1,60 +1,111 @@
+distribute result [$$107]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$107] <- [{"cid": $$118, "pid": $$117, "ts": $$110}] project: [$$107]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$118(ASC) ]  |PARTITIONED|
+        order (ASC, $$118)
         -- STABLE_SORT [$$118(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select ($$101) project: [$$118, $$117, $$110]
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$118, $$110, $$117, $$101])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$101] <- [non-empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select (eq($$117, $#3))
                             -- STREAM_SELECT  |LOCAL|
+                              unnest $#3 <- scan-collection($$96)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true)
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        select (ge($$110, 2000))
                         -- STREAM_SELECT  |PARTITIONED|
+                          assign [$$110, $$117] <- [$$i1.getField("ts"), $$i1.getField("pid")] project: [$$118, $$110, $$117]
                           -- ASSIGN  |PARTITIONED|
+                            unnest $$i1 <- scan-collection($$114) project: [$$118, $$i1]
                             -- UNNEST  |PARTITIONED|
+                              assign [$$118, $$114] <- [$$c1.getField("cid"), $$c1.getField("items")] project: [$$118, $$114]
                               -- ASSIGN  |PARTITIONED|
+                                assign [$$c1] <- [$$c2] project: [$$c1]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        project ([$$c2])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (test.cart)  |PARTITIONED|
+                                            data-scan []<-[$$112, $$c2] <- test.cart
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        aggregate [$$96] <- [listify($$pid)]
                         -- AGGREGATE  |UNPARTITIONED|
+                          exchange
                           -- SORT_MERGE_EXCHANGE [$$pid(ASC) ]  |PARTITIONED|
+                            select (gt($$113, 1)) project: [$$pid]
                             -- STREAM_SELECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- SORT_GROUP_BY[$$124]  |PARTITIONED|
-                                        {
+                                group by ([$$pid := $$124]) decor ([]) {
+                                          aggregate [$$113] <- [agg-sql-sum($$123)]
                                           -- AGGREGATE  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- SORT_GROUP_BY[$$124]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$124]  |PARTITIONED|
-                                    -- SORT_GROUP_BY[$$109]  |PARTITIONED|
-                                            {
+                                    group by ([$$124 := $$109]) decor ([]) {
+                                              aggregate [$$123] <- [agg-sql-count(1)]
                                               -- AGGREGATE  |LOCAL|
+                                                nested tuple source
                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                           }
+                                    -- SORT_GROUP_BY[$$109]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        select (ge($$i2.getField("ts"), 2000)) project: [$$109]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$109] <- [$$i2.getField("pid")]
                                           -- ASSIGN  |PARTITIONED|
+                                            unnest $$i2 <- scan-collection($$115) project: [$$i2]
                                             -- UNNEST  |PARTITIONED|
+                                              assign [$$115] <- [$$c2.getField("items")] project: [$$115]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  replicate
                                                   -- REPLICATE  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      project ([$$c2])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.cart)  |PARTITIONED|
+                                                          data-scan []<-[$$112, $$c2] <- test.cart
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_7.plan
index 3febf26..44f61a1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_7.plan
@@ -1,60 +1,111 @@
+distribute result [$$107]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$107] <- [{"cid": $$118, "pid": $$117, "ts": $$110}] project: [$$107]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$118(ASC) ]  |PARTITIONED|
+        order (ASC, $$118)
         -- STABLE_SORT [$$118(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select ($$101) project: [$$118, $$117, $$110]
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$118, $$110, $$117, $$101])
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$101] <- [non-empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select (eq($$117, $#3))
                             -- STREAM_SELECT  |LOCAL|
+                              unnest $#3 <- scan-collection($$96)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- SUBPLAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true)
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        select (ge($$110, 2000))
                         -- STREAM_SELECT  |PARTITIONED|
+                          assign [$$110, $$117] <- [$$i1.getField("ts"), $$i1.getField("pid")] project: [$$118, $$110, $$117]
                           -- ASSIGN  |PARTITIONED|
+                            unnest $$i1 <- scan-collection($$114) project: [$$118, $$i1]
                             -- UNNEST  |PARTITIONED|
+                              assign [$$118, $$114] <- [$$c1.getField("cid"), $$c1.getField("items")] project: [$$118, $$114]
                               -- ASSIGN  |PARTITIONED|
+                                assign [$$c1] <- [$$c2] project: [$$c1]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        project ([$$c2])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (test.cart)  |PARTITIONED|
+                                            data-scan []<-[$$112, $$c2] <- test.cart
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        aggregate [$$96] <- [listify($$pid)]
                         -- AGGREGATE  |UNPARTITIONED|
+                          exchange
                           -- SORT_MERGE_EXCHANGE [$$pid(ASC) ]  |PARTITIONED|
+                            select (gt($$113, 1)) project: [$$pid]
                             -- STREAM_SELECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- SORT_GROUP_BY[$$124]  |PARTITIONED|
-                                        {
+                                group by ([$$pid := $$124]) decor ([]) {
+                                          aggregate [$$113] <- [agg-sql-sum($$123)]
                                           -- AGGREGATE  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- SORT_GROUP_BY[$$124]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$124]  |PARTITIONED|
-                                    -- SORT_GROUP_BY[$$109]  |PARTITIONED|
-                                            {
+                                    group by ([$$124 := $$109]) decor ([]) {
+                                              aggregate [$$123] <- [agg-sql-count(1)]
                                               -- AGGREGATE  |LOCAL|
+                                                nested tuple source
                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                           }
+                                    -- SORT_GROUP_BY[$$109]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        select (ge($$i2.getField("ts"), 2000)) project: [$$109]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$109] <- [$$i2.getField("pid")]
                                           -- ASSIGN  |PARTITIONED|
+                                            unnest $$i2 <- scan-collection($$115) project: [$$i2]
                                             -- UNNEST  |PARTITIONED|
+                                              assign [$$115] <- [$$c2.getField("items")] project: [$$115]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  replicate
                                                   -- REPLICATE  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      project ([$$c2])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.cart)  |PARTITIONED|
+                                                          data-scan []<-[$$112, $$c2] <- test.cart
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_8.plan
index 4d5d792..61c6bfd 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_let_8.plan
@@ -1,63 +1,117 @@
+distribute result [$$96]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$96] <- [{"cid": $$107, "pid": $$114, "ts": $$115}] project: [$$96]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$107(ASC) ]  |PARTITIONED|
+        order (ASC, $$107)
         -- STABLE_SORT [$$107(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(ge($$115, 2000), $$90)) project: [$$107, $$114, $$115]
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$90, $$114, $$115, $$107])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- PRE_CLUSTERED_GROUP_BY[$$100, $$i1, $$103, $$99, $$110]  |PARTITIONED|
-                          {
+                  group by ([$$112 := $$100; $$113 := $$i1; $$114 := $$103; $$115 := $$99; $$116 := $$110]) decor ([$$107]) {
+                            aggregate [$$90] <- [non-empty-stream()]
                             -- AGGREGATE  |LOCAL|
+                              select (not(is-missing($$111)))
                               -- STREAM_SELECT  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                          }
+                         }
+                  -- PRE_CLUSTERED_GROUP_BY[$$100, $$i1, $$103, $$99, $$110]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$100) (ASC, $$i1) (ASC, $$103) (ASC, $$99) (ASC, $$110)
                       -- STABLE_SORT [$$100(ASC), $$i1(ASC), $$103(ASC), $$99(ASC), $$110(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$107, $$111, $$100, $$i1, $$103, $$99, $$110])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              left outer join (eq($$103, $$pid))
                               -- HYBRID_HASH_JOIN [$$103][$$pid]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$103]  |PARTITIONED|
+                                  window-aggregate [$$110] <- [row-number-impl()] partition [$$100, $$i1, $$103, $$99]
                                   -- WINDOW_STREAM  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$100) (ASC, $$i1) (ASC, $$103) (ASC, $$99)
                                       -- STABLE_SORT [$$100(ASC), $$i1(ASC), $$103(ASC), $$99(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$100, $$i1, $$103, $$99]  |PARTITIONED|
+                                          assign [$$99, $$103] <- [$$i1.getField("ts"), $$i1.getField("pid")]
                                           -- ASSIGN  |PARTITIONED|
+                                            unnest $$i1 <- scan-collection($$104) project: [$$100, $$107, $$i1]
                                             -- UNNEST  |PARTITIONED|
+                                              assign [$$107, $$104] <- [$$c1.getField("cid"), $$c1.getField("items")] project: [$$100, $$107, $$104]
                                               -- ASSIGN  |PARTITIONED|
+                                                assign [$$100, $$c1] <- [$$101, $$c2] project: [$$100, $$c1]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    replicate
                                                     -- REPLICATE  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.cart)  |PARTITIONED|
+                                                        data-scan []<-[$$101, $$c2] <- test.cart
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$111] <- [true]
                                   -- ASSIGN  |PARTITIONED|
+                                    select (gt($$102, 1)) project: [$$pid]
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- SORT_GROUP_BY[$$118]  |PARTITIONED|
-                                                {
+                                        group by ([$$pid := $$118]) decor ([]) {
+                                                  aggregate [$$102] <- [agg-sql-sum($$117)]
                                                   -- AGGREGATE  |LOCAL|
+                                                    nested tuple source
                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                               }
+                                        -- SORT_GROUP_BY[$$118]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$118]  |PARTITIONED|
-                                            -- SORT_GROUP_BY[$$98]  |PARTITIONED|
-                                                    {
+                                            group by ([$$118 := $$98]) decor ([]) {
+                                                      aggregate [$$117] <- [agg-sql-count(1)]
                                                       -- AGGREGATE  |LOCAL|
+                                                        nested tuple source
                                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                    }
+                                                   }
+                                            -- SORT_GROUP_BY[$$98]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                select (ge($$i2.getField("ts"), 2000)) project: [$$98]
                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                  assign [$$98] <- [$$i2.getField("pid")]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    unnest $$i2 <- scan-collection($$105) project: [$$i2]
                                                     -- UNNEST  |PARTITIONED|
+                                                      assign [$$105] <- [$$c2.getField("items")] project: [$$105]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$c2])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            replicate
                                                             -- REPLICATE  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.cart)  |PARTITIONED|
+                                                                data-scan []<-[$$101, $$c2] <- test.cart
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_ps.plan
index 1f34548..a09a030 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_ps.plan
@@ -1,71 +1,136 @@
+distribute result [$$47]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$47] <- [{"customer_name": $$53}] project: [$$47]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$53)
         -- STABLE_SORT [$$53(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$53(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$56
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select ($$41) project: [$$53]
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
-                                {
+                        group by ([$$53 := $$48]) decor ([]) {
+                                  aggregate [$$41] <- [non-empty-stream()]
                                   -- AGGREGATE  |LOCAL|
+                                    select (not(is-missing($$52)))
                                     -- STREAM_SELECT  |LOCAL|
+                                      nested tuple source
                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$48)
                             -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$52, $$48])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    left outer join (eq($$48, $$37))
                                     -- HYBRID_HASH_JOIN [$$48][$$37]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+                                        select (eq($$c.getField("c_nationkey"), 5)) project: [$$48]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                            data-scan []<-[$$48, $$c] <- test.Customers
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                                        assign [$$52, $$37] <- [true, $$o.getField("o_custkey")] project: [$$52, $$37]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$o])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
+                                              data-scan []<-[$$49, $$o] <- test.Orders
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$56] <- [agg-range-map($$54, $$55)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$54, $$55] <- [agg-local-sampling($$53), agg-null-writer($$53)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate
                         -- REPLICATE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select ($$41) project: [$$53]
                             -- STREAM_SELECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
-                                        {
+                                group by ([$$53 := $$48]) decor ([]) {
+                                          aggregate [$$41] <- [non-empty-stream()]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$52)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$48)
                                     -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        project ([$$52, $$48])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            left outer join (eq($$48, $$37))
                                             -- HYBRID_HASH_JOIN [$$48][$$37]  |PARTITIONED|
+                                              exchange
                                               -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+                                                select (eq($$c.getField("c_nationkey"), 5)) project: [$$48]
                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
+                                                    data-scan []<-[$$48, $$c] <- test.Customers
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              exchange
                                               -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                                                assign [$$52, $$37] <- [true, $$o.getField("o_custkey")] project: [$$52, $$37]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  project ([$$o])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
+                                                      data-scan []<-[$$49, $$o] <- test.Orders
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/not_exists.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/not_exists.plan
index baadb28..f7d776c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/not_exists.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/not_exists.plan
@@ -1,68 +1,124 @@
+distribute result [$$171]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$171] <- [{"cntrycode": $$cntrycode, "numcust": $$174, "totacctbal": $$175}] project: [$$171]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$cntrycode(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$197]  |PARTITIONED|
-                {
+        group by ([$$cntrycode := $$197]) decor ([]) {
+                  aggregate [$$174, $$175] <- [agg-sql-sum($$195), agg-global-sql-sum($$196)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$197]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$197]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$172]  |PARTITIONED|
-                    {
+            group by ([$$197 := $$172]) decor ([]) {
+                      aggregate [$$195, $$196] <- [agg-sql-count($$131), agg-local-sql-sum($$183)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$172]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$172] <- [substring($$185, 0, 2)] project: [$$131, $$183, $$172]
                 -- ASSIGN  |PARTITIONED|
+                  select (not(neq($$173, 0))) project: [$$131, $$183, $$185]
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$173, $$131, $$183, $$185])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$194]  |PARTITIONED|
-                                {
+                        group by ([$$190 := $$194]) decor ([$$131; $$183; $$185]) {
+                                  aggregate [$$173] <- [agg-sum($$193)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$194]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$194]  |PARTITIONED|
-                            -- PRE_CLUSTERED_GROUP_BY[$$188]  |PARTITIONED|
-                                    {
+                            group by ([$$194 := $$188]) decor ([$$131; $$183; $$185]) {
+                                      aggregate [$$193] <- [agg-count({"o": $$o})]
                                       -- AGGREGATE  |LOCAL|
+                                        select (not(is-missing($$189)))
                                         -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- PRE_CLUSTERED_GROUP_BY[$$188]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$188)
                                 -- STABLE_SORT [$$188(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$131, $$183, $$185, $$o, $$189, $$188])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        left outer join (eq($$181, $$184))
                                         -- HYBRID_HASH_JOIN [$$184][$$181]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$184]  |PARTITIONED|
+                                            running-aggregate [$$188] <- [create-query-uid()]
                                             -- RUNNING_AGGREGATE  |PARTITIONED|
+                                              project ([$$131, $$183, $$185, $$184])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  join (gt($$183, $$180))
                                                   -- NESTED_LOOP  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      assign [$$131] <- [{"c_acctbal": $$183, "c_custkey": $$184, "cntrycode": substring($$185, 0, 2)}]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        assign [$$185, $$184, $$183] <- [$$Customer.getField(4), $$Customer.getField(0), $$Customer.getField(5)] project: [$$185, $$184, $$183]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.Customer)  |PARTITIONED|
+                                                            data-scan []<-[$$Customer] <- test.Customer
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                      assign [$$180] <- [get-item($$145, 0)] project: [$$180]
                                                       -- ASSIGN  |UNPARTITIONED|
+                                                        aggregate [$$145] <- [listify($$192)]
                                                         -- AGGREGATE  |UNPARTITIONED|
+                                                          aggregate [$$192] <- [agg-global-sql-avg($$198)]
                                                           -- AGGREGATE  |UNPARTITIONED|
+                                                            exchange
                                                             -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                              aggregate [$$198] <- [agg-local-sql-avg($$186)]
                                                               -- AGGREGATE  |PARTITIONED|
+                                                                select (gt($$186, 0.0))
                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                  assign [$$186] <- [$$178.getField(5)] project: [$$186]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- DATASOURCE_SCAN (test.Customer)  |PARTITIONED|
+                                                                      data-scan []<-[$$178] <- test.Customer
+                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$181]  |PARTITIONED|
+                                            assign [$$189, $$181] <- [true, $$o.getField(1)]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
+                                                data-scan []<-[$$o] <- test.Orders
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/not_exists_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/not_exists_ps.plan
index 5a49132..46692e4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/not_exists_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/not_exists_ps.plan
@@ -1,146 +1,268 @@
+distribute result [$$171]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$171] <- [{"cntrycode": $$cntrycode, "numcust": $$174, "totacctbal": $$175}] project: [$$171]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$cntrycode)
         -- STABLE_SORT [$$cntrycode(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$cntrycode(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$202
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$197]  |PARTITIONED|
-                            {
+                    group by ([$$cntrycode := $$197]) decor ([]) {
+                              aggregate [$$174, $$175] <- [agg-sql-sum($$195), agg-global-sql-sum($$196)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$197]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$197]  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$172]  |PARTITIONED|
-                                {
+                        group by ([$$197 := $$172]) decor ([]) {
+                                  aggregate [$$195, $$196] <- [agg-sql-count($$131), agg-local-sql-sum($$183)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$172]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$172] <- [substring($$185, 0, 2)] project: [$$131, $$183, $$172]
                             -- ASSIGN  |PARTITIONED|
+                              select (not(neq($$173, 0))) project: [$$131, $$183, $$185]
                               -- STREAM_SELECT  |PARTITIONED|
+                                project ([$$173, $$131, $$183, $$185])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- SORT_GROUP_BY[$$194]  |PARTITIONED|
-                                            {
+                                    group by ([$$190 := $$194]) decor ([$$131; $$183; $$185]) {
+                                              aggregate [$$173] <- [agg-sum($$193)]
                                               -- AGGREGATE  |LOCAL|
+                                                nested tuple source
                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                           }
+                                    -- SORT_GROUP_BY[$$194]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$194]  |PARTITIONED|
-                                        -- PRE_CLUSTERED_GROUP_BY[$$188]  |PARTITIONED|
-                                                {
+                                        group by ([$$194 := $$188]) decor ([$$131; $$183; $$185]) {
+                                                  aggregate [$$193] <- [agg-count({"o": $$o})]
                                                   -- AGGREGATE  |LOCAL|
+                                                    select (not(is-missing($$189)))
                                                     -- STREAM_SELECT  |LOCAL|
+                                                      nested tuple source
                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                               }
+                                        -- PRE_CLUSTERED_GROUP_BY[$$188]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$188)
                                             -- STABLE_SORT [$$188(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$131, $$183, $$185, $$o, $$189, $$188])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    left outer join (eq($$181, $$184))
                                                     -- HYBRID_HASH_JOIN [$$184][$$181]  |PARTITIONED|
+                                                      exchange
                                                       -- HASH_PARTITION_EXCHANGE [$$184]  |PARTITIONED|
+                                                        running-aggregate [$$188] <- [create-query-uid()]
                                                         -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                          project ([$$131, $$183, $$185, $$184])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              join (gt($$183, $$180))
                                                               -- NESTED_LOOP  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$131] <- [{"c_acctbal": $$183, "c_custkey": $$184, "cntrycode": substring($$185, 0, 2)}]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    assign [$$185, $$184, $$183] <- [$$Customer.getField(4), $$Customer.getField(0), $$Customer.getField(5)] project: [$$185, $$184, $$183]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- DATASOURCE_SCAN (test.Customer)  |PARTITIONED|
+                                                                        data-scan []<-[$$Customer] <- test.Customer
+                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                exchange
                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$180] <- [get-item($$145, 0)] project: [$$180]
                                                                   -- ASSIGN  |UNPARTITIONED|
+                                                                    aggregate [$$145] <- [listify($$192)]
                                                                     -- AGGREGATE  |UNPARTITIONED|
+                                                                      aggregate [$$192] <- [agg-global-sql-avg($$198)]
                                                                       -- AGGREGATE  |UNPARTITIONED|
+                                                                        exchange
                                                                         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                                          aggregate [$$198] <- [agg-local-sql-avg($$186)]
                                                                           -- AGGREGATE  |PARTITIONED|
+                                                                            select (gt($$186, 0.0))
                                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                                              assign [$$186] <- [$$178.getField(5)] project: [$$186]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- DATASOURCE_SCAN (test.Customer)  |PARTITIONED|
+                                                                                  data-scan []<-[$$178] <- test.Customer
+                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      empty-tuple-source
                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                      exchange
                                                       -- HASH_PARTITION_EXCHANGE [$$181]  |PARTITIONED|
+                                                        assign [$$189, $$181] <- [true, $$o.getField(1)]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
+                                                            data-scan []<-[$$o] <- test.Orders
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$202] <- [agg-range-map($$200, $$201)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$200, $$201] <- [agg-local-sampling($$cntrycode), agg-null-writer($$cntrycode)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$cntrycode])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- SORT_GROUP_BY[$$197]  |PARTITIONED|
-                                      {
+                              group by ([$$cntrycode := $$197]) decor ([]) {
+                                        aggregate [$$174, $$175] <- [agg-sql-sum($$195), agg-global-sql-sum($$196)]
                                         -- AGGREGATE  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- SORT_GROUP_BY[$$197]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$197]  |PARTITIONED|
-                                  -- SORT_GROUP_BY[$$172]  |PARTITIONED|
-                                          {
+                                  group by ([$$197 := $$172]) decor ([]) {
+                                            aggregate [$$195, $$196] <- [agg-sql-count($$131), agg-local-sql-sum($$183)]
                                             -- AGGREGATE  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                          }
+                                         }
+                                  -- SORT_GROUP_BY[$$172]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$172] <- [substring($$185, 0, 2)] project: [$$131, $$183, $$172]
                                       -- ASSIGN  |PARTITIONED|
+                                        select (not(neq($$173, 0))) project: [$$131, $$183, $$185]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          project ([$$173, $$131, $$183, $$185])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- SORT_GROUP_BY[$$194]  |PARTITIONED|
-                                                      {
+                                              group by ([$$190 := $$194]) decor ([$$131; $$183; $$185]) {
+                                                        aggregate [$$173] <- [agg-sum($$193)]
                                                         -- AGGREGATE  |LOCAL|
+                                                          nested tuple source
                                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                      }
+                                                     }
+                                              -- SORT_GROUP_BY[$$194]  |PARTITIONED|
+                                                exchange
                                                 -- HASH_PARTITION_EXCHANGE [$$194]  |PARTITIONED|
-                                                  -- PRE_CLUSTERED_GROUP_BY[$$188]  |PARTITIONED|
-                                                          {
+                                                  group by ([$$194 := $$188]) decor ([$$131; $$183; $$185]) {
+                                                            aggregate [$$193] <- [agg-count({"o": $$o})]
                                                             -- AGGREGATE  |LOCAL|
+                                                              select (not(is-missing($$189)))
                                                               -- STREAM_SELECT  |LOCAL|
+                                                                nested tuple source
                                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                          }
+                                                         }
+                                                  -- PRE_CLUSTERED_GROUP_BY[$$188]  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      order (ASC, $$188)
                                                       -- STABLE_SORT [$$188(ASC)]  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          project ([$$131, $$183, $$185, $$o, $$189, $$188])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              left outer join (eq($$181, $$184))
                                                               -- HYBRID_HASH_JOIN [$$184][$$181]  |PARTITIONED|
+                                                                exchange
                                                                 -- HASH_PARTITION_EXCHANGE [$$184]  |PARTITIONED|
+                                                                  running-aggregate [$$188] <- [create-query-uid()]
                                                                   -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                                    project ([$$131, $$183, $$185, $$184])
                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        join (gt($$183, $$180))
                                                                         -- NESTED_LOOP  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            assign [$$131] <- [{"c_acctbal": $$183, "c_custkey": $$184, "cntrycode": substring($$185, 0, 2)}]
                                                                             -- ASSIGN  |PARTITIONED|
+                                                                              assign [$$185, $$184, $$183] <- [$$Customer.getField(4), $$Customer.getField(0), $$Customer.getField(5)] project: [$$185, $$184, $$183]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- DATASOURCE_SCAN (test.Customer)  |PARTITIONED|
+                                                                                  data-scan []<-[$$Customer] <- test.Customer
+                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      empty-tuple-source
                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                          exchange
                                                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                            assign [$$180] <- [get-item($$145, 0)] project: [$$180]
                                                                             -- ASSIGN  |UNPARTITIONED|
+                                                                              aggregate [$$145] <- [listify($$192)]
                                                                               -- AGGREGATE  |UNPARTITIONED|
+                                                                                aggregate [$$192] <- [agg-global-sql-avg($$198)]
                                                                                 -- AGGREGATE  |UNPARTITIONED|
+                                                                                  exchange
                                                                                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                                                    aggregate [$$198] <- [agg-local-sql-avg($$186)]
                                                                                     -- AGGREGATE  |PARTITIONED|
+                                                                                      select (gt($$186, 0.0))
                                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                                        assign [$$186] <- [$$178.getField(5)] project: [$$186]
                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                            -- DATASOURCE_SCAN (test.Customer)  |PARTITIONED|
+                                                                                            data-scan []<-[$$178] <- test.Customer
+                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                empty-tuple-source
                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                exchange
                                                                 -- HASH_PARTITION_EXCHANGE [$$181]  |PARTITIONED|
+                                                                  assign [$$189, $$181] <- [true, $$o.getField(1)]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
+                                                                      data-scan []<-[$$o] <- test.Orders
+                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-1572-2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-1572-2.plan
index 06af916..a5a5641 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-1572-2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-1572-2.plan
@@ -1,10 +1,20 @@
+distribute result [$$52]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$52] <- [{"st1": {"id": $$53}}] project: [$$52]
     -- ASSIGN  |PARTITIONED|
+      select (or(and(eq($$53, 0), $$55), and($$55, eq($$53, 2)))) project: [$$53]
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$55] <- [eq($$53, 1)]
         -- ASSIGN  |PARTITIONED|
+          project ([$$53])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- DATASOURCE_SCAN (sampdb.samptable)  |PARTITIONED|
+              data-scan []<-[$$53, $$samptable] <- sampdb.samptable
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-1572.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-1572.plan
index 27a4552..0826577 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-1572.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-1572.plan
@@ -1,27 +1,45 @@
+distribute result [$$56]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$56] <- [{"st1": {"id": $$57}}] project: [$$56]
     -- ASSIGN  |PARTITIONED|
+      select (or(and($$35, $$39), and($$44, $$48))) project: [$$57]
       -- STREAM_SELECT  |PARTITIONED|
-        -- SUBPLAN  |PARTITIONED|
-                {
+        subplan {
+                  aggregate [$$48] <- [non-empty-stream()]
                   -- AGGREGATE  |LOCAL|
+                    select (eq($$57, 2))
                     -- STREAM_SELECT  |LOCAL|
+                      nested tuple source
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-          -- SUBPLAN  |PARTITIONED|
-                  {
+               }
+        -- SUBPLAN  |PARTITIONED|
+          subplan {
+                    aggregate [$$39, $$44] <- [non-empty-stream(), non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (eq($$57, 1))
                       -- STREAM_SELECT  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
-            -- SUBPLAN  |PARTITIONED|
-                    {
+                 }
+          -- SUBPLAN  |PARTITIONED|
+            subplan {
+                      aggregate [$$35] <- [non-empty-stream()]
                       -- AGGREGATE  |LOCAL|
+                        select (eq($$57, 0))
                         -- STREAM_SELECT  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SUBPLAN  |PARTITIONED|
+              project ([$$57])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (sampdb.samptable)  |PARTITIONED|
+                  data-scan []<-[$$57, $$samptable] <- sampdb.samptable
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-2815-2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-2815-2.plan
index 9b70fb7..d0edd9f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-2815-2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-2815-2.plan
@@ -1,67 +1,131 @@
+distribute result [$$81]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$81] <- [{"id": $$87, "ranks": array-sort($$77)}] project: [$$81]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$87(ASC) ]  |PARTITIONED|
+        order (ASC, $$87)
         -- STABLE_SORT [$$87(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$87, $$77])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- PRE_CLUSTERED_GROUP_BY[$$83]  |PARTITIONED|
-                        {
+                group by ([$$96 := $$83]) decor ([$$87]) {
+                          aggregate [$$77] <- [listify($$74)]
                           -- AGGREGATE  |LOCAL|
+                            select (not(is-missing($$95)))
                             -- STREAM_SELECT  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- PRE_CLUSTERED_GROUP_BY[$$83]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$83)
                     -- STABLE_SORT [$$83(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$87, $$74, $$95, $$83])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            left outer join (eq($$83, $$94))
                             -- HYBRID_HASH_JOIN [$$83][$$94]  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$83]  |PARTITIONED|
+                                assign [$$83, $$87] <- [$$94, $$92] project: [$$83, $$87]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$92] <- [$$93.getField("id")] project: [$$94, $$92]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (test.RawTweet)  |PARTITIONED|
+                                            data-scan []<-[$$94, $$93] <- test.RawTweet
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$95] <- [true]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$94, $$74])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    window-aggregate [$$74] <- [rank-impl($$e.url)] partition [$$94] order (ASC, $$e.url)
                                     -- WINDOW_STREAM  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$94) (ASC, $$e.url)
                                         -- STABLE_SORT [$$94(ASC), $$e.url(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$94]  |PARTITIONED|
+                                            project ([$$94, $$e.url])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                join (eq($$ve, $$86))
                                                 -- HYBRID_HASH_JOIN [$$ve][$$86]  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$ve]  |PARTITIONED|
+                                                    unnest $$ve <- scan-collection($$89) project: [$$94, $$ve]
                                                     -- UNNEST  |PARTITIONED|
+                                                      project ([$$94, $$89])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          join (eq($$92, $$88))
                                                           -- HYBRID_HASH_JOIN [$$92][$$88]  |PARTITIONED|
+                                                            exchange
                                                             -- HASH_PARTITION_EXCHANGE [$$92]  |PARTITIONED|
+                                                              replicate
                                                               -- REPLICATE  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  assign [$$92] <- [$$93.getField("id")] project: [$$94, $$92]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- DATASOURCE_SCAN (test.RawTweet)  |PARTITIONED|
+                                                                      data-scan []<-[$$94, $$93] <- test.RawTweet
+                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                            exchange
                                                             -- HASH_PARTITION_EXCHANGE [$$88]  |PARTITIONED|
+                                                              assign [$$89, $$88] <- [$$v.getField("evidence"), $$v.getField("tweet_id")] project: [$$89, $$88]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                project ([$$v])
                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- DATASOURCE_SCAN (test.Verification)  |PARTITIONED|
+                                                                    data-scan []<-[$$84, $$v] <- test.Verification
+                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$86]  |PARTITIONED|
+                                                    assign [$$e.url, $$86] <- [$$e.getField("url"), $$e.getField("ev_id")] project: [$$e.url, $$86]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$e])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.Evidence)  |PARTITIONED|
+                                                          data-scan []<-[$$85, $$e] <- test.Evidence
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-2815-3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-2815-3.plan
index da70078..0ce602e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-2815-3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-2815-3.plan
@@ -1,68 +1,133 @@
+distribute result [$$86]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$86] <- [{"id": $$93, "ranks": array-sort($$82)}] project: [$$86]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$93(ASC) ]  |PARTITIONED|
+        order (ASC, $$93)
         -- STABLE_SORT [$$93(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$93, $$82])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- PRE_CLUSTERED_GROUP_BY[$$89]  |PARTITIONED|
-                        {
+                group by ([$$102 := $$89]) decor ([$$93]) {
+                          aggregate [$$82] <- [listify($$79)]
                           -- AGGREGATE  |LOCAL|
+                            select (not(is-missing($$101)))
                             -- STREAM_SELECT  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- PRE_CLUSTERED_GROUP_BY[$$89]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$89)
                     -- STABLE_SORT [$$89(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$93, $$79, $$101, $$89])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            left outer join (eq($$89, $$100))
                             -- HYBRID_HASH_JOIN [$$89][$$100]  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$89]  |PARTITIONED|
+                                assign [$$89, $$93] <- [$$100, $$98] project: [$$89, $$93]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$98] <- [$$99.getField("id")] project: [$$100, $$98]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (test.RawTweet)  |PARTITIONED|
+                                            data-scan []<-[$$100, $$99] <- test.RawTweet
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$100]  |PARTITIONED|
+                                assign [$$101] <- [true]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$100, $$79])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    window-aggregate [$$79] <- [rank-impl($$88)] partition [$$77, $$100] order (ASC, $$88)
                                     -- WINDOW_STREAM  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        order (ASC, $$77) (ASC, $$100) (ASC, $$88)
                                         -- STABLE_SORT [$$77(ASC), $$100(ASC), $$88(ASC)]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$77, $$100]  |PARTITIONED|
+                                            assign [$$77] <- [numeric-mod(to-bigint(substring($$88, -4)), 2)]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$100, $$88])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  join (eq($$ve, $$92))
                                                   -- HYBRID_HASH_JOIN [$$ve][$$92]  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$ve]  |PARTITIONED|
+                                                      unnest $$ve <- scan-collection($$95) project: [$$100, $$ve]
                                                       -- UNNEST  |PARTITIONED|
+                                                        project ([$$100, $$95])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            join (eq($$98, $$94))
                                                             -- HYBRID_HASH_JOIN [$$98][$$94]  |PARTITIONED|
+                                                              exchange
                                                               -- HASH_PARTITION_EXCHANGE [$$98]  |PARTITIONED|
+                                                                replicate
                                                                 -- REPLICATE  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    assign [$$98] <- [$$99.getField("id")] project: [$$100, $$98]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- DATASOURCE_SCAN (test.RawTweet)  |PARTITIONED|
+                                                                        data-scan []<-[$$100, $$99] <- test.RawTweet
+                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                              exchange
                                                               -- HASH_PARTITION_EXCHANGE [$$94]  |PARTITIONED|
+                                                                assign [$$95, $$94] <- [$$v.getField("evidence"), $$v.getField("tweet_id")] project: [$$95, $$94]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  project ([$$v])
                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- DATASOURCE_SCAN (test.Verification)  |PARTITIONED|
+                                                                      data-scan []<-[$$90, $$v] <- test.Verification
+                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$92]  |PARTITIONED|
+                                                      assign [$$88, $$92] <- [$$e.getField("url"), $$e.getField("ev_id")] project: [$$88, $$92]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$e])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.Evidence)  |PARTITIONED|
+                                                            data-scan []<-[$$91, $$e] <- test.Evidence
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-2815.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-2815.plan
index 74b9351..edd692d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-2815.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-2815.plan
@@ -1,68 +1,133 @@
+distribute result [$$73]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$73] <- [{"id": $$80, "urls": $$68}] project: [$$73]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$80(ASC) ]  |PARTITIONED|
+        order (ASC, $$80)
         -- STABLE_SORT [$$80(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$79, 2)) project: [$$80, $$68]
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$68, $$79, $$80])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- PRE_CLUSTERED_GROUP_BY[$$75]  |PARTITIONED|
-                          {
+                  group by ([$$89 := $$75]) decor ([$$80]) {
+                            aggregate [$$68, $$79] <- [listify($$67), agg-sql-count($$67)]
                             -- AGGREGATE  |LOCAL|
+                              select (not(is-missing($$88)))
                               -- STREAM_SELECT  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                          }
+                         }
+                  -- PRE_CLUSTERED_GROUP_BY[$$75]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$75)
                       -- STABLE_SORT [$$75(ASC)]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$80, $$67, $$88, $$75])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              left outer join (eq($$75, $$87))
                               -- HYBRID_HASH_JOIN [$$75][$$87]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$75]  |PARTITIONED|
+                                  assign [$$75, $$80] <- [$$87, $$85] project: [$$75, $$80]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      replicate
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$85] <- [$$86.getField("id")] project: [$$87, $$85]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.RawTweet)  |PARTITIONED|
+                                              data-scan []<-[$$87, $$86] <- test.RawTweet
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$87]  |PARTITIONED|
+                                  assign [$$88] <- [true]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      distinct ([$$67, $$87])
                                       -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          order (ASC, $$67) (ASC, $$87)
                                           -- STABLE_SORT [$$67(ASC), $$87(ASC)]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$67, $$87]  |PARTITIONED|
+                                              project ([$$67, $$87])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  join (eq($$ve, $$78))
                                                   -- HYBRID_HASH_JOIN [$$ve][$$78]  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$ve]  |PARTITIONED|
+                                                      unnest $$ve <- scan-collection($$82) project: [$$87, $$ve]
                                                       -- UNNEST  |PARTITIONED|
+                                                        project ([$$87, $$82])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            join (eq($$85, $$81))
                                                             -- HYBRID_HASH_JOIN [$$85][$$81]  |PARTITIONED|
+                                                              exchange
                                                               -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                                                                replicate
                                                                 -- REPLICATE  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    assign [$$85] <- [$$86.getField("id")] project: [$$87, $$85]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- DATASOURCE_SCAN (test.RawTweet)  |PARTITIONED|
+                                                                        data-scan []<-[$$87, $$86] <- test.RawTweet
+                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                              exchange
                                                               -- HASH_PARTITION_EXCHANGE [$$81]  |PARTITIONED|
+                                                                assign [$$82, $$81] <- [$$v.getField("evidence"), $$v.getField("tweet_id")] project: [$$82, $$81]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  project ([$$v])
                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- DATASOURCE_SCAN (test.Verification)  |PARTITIONED|
+                                                                      data-scan []<-[$$76, $$v] <- test.Verification
+                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$78]  |PARTITIONED|
+                                                      assign [$$67, $$78] <- [$$e.getField("url"), $$e.getField("ev_id")] project: [$$67, $$78]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$e])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.Evidence)  |PARTITIONED|
+                                                            data-scan []<-[$$77, $$e] <- test.Evidence
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-2845.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-2845.plan
index 757c420..a5ccde4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-2845.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-2845.plan
@@ -1,122 +1,226 @@
+distribute result [$$291]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$291] <- [{"j_jid": $$296, "j_a": $$304, "m1_jid": $$306, "m1_x": $#4, "m1_c1": $$309, "m2_jid": $#6, "m2_y": $#5, "m2_c2": $$310}] project: [$$291]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$296(ASC), $#4(ASC), $#5(ASC), $#6(ASC) ]  |PARTITIONED|
+        order (ASC, $$296) (ASC, $#4) (ASC, $#5) (ASC, $#6)
         -- STABLE_SORT [$$296(ASC), $#4(ASC), $#5(ASC), $#6(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$296, $$304, $$306, $#4, $$309, $#6, $#5, $$310])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                left outer join (and(eq($$296, $$322), eq($$259, $$327), eq($$309, $$317), eq($$306, $$318), eq($#4, $$319), eq($$314, $$320)))
                 -- HYBRID_HASH_JOIN [$$296, $$259, $$309, $$306, $#4, $$314][$$322, $$327, $$317, $$318, $$319, $$320]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    window-aggregate [$$314] <- [row-number-impl()] partition [$$296, $$259, $$309, $$306, $#4]
                     -- WINDOW_STREAM  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$296) (ASC, $$259) (ASC, $$309) (ASC, $$306) (ASC, $#4)
                         -- STABLE_SORT [$$296(ASC), $$259(ASC), $$309(ASC), $$306(ASC), $#4(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$296, $$304, $$306, $#4, $$309, $$259])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                left outer join (eq($$296, $$jid))
                                 -- HYBRID_HASH_JOIN [$$296][$$jid]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$296]  |PARTITIONED|
+                                    assign [$$304] <- [$$jds.getField("a")] project: [$$296, $$304]
                                     -- ASSIGN  |PARTITIONED|
+                                      assign [$$296, $$jds] <- [$$322, $$324] project: [$$296, $$jds]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.jds)  |PARTITIONED|
+                                              data-scan []<-[$$322, $$324] <- test.jds
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$jid]  |PARTITIONED|
+                                    assign [$$309, $#4, $$306] <- [$$259.getField(0), $$259.getField("x"), $$259.getField("jid")]
                                     -- ASSIGN  |PARTITIONED|
+                                      assign [$$259] <- [{"jid": $$jid, "x": $$x, "c1": $$299}] project: [$$jid, $$259]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- SORT_GROUP_BY[$$343, $$344]  |PARTITIONED|
-                                                  {
+                                          group by ([$$jid := $$343; $$x := $$344]) decor ([]) {
+                                                    aggregate [$$299] <- [agg-sql-sum($$342)]
                                                     -- AGGREGATE  |LOCAL|
+                                                      nested tuple source
                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                  }
+                                                 }
+                                          -- SORT_GROUP_BY[$$343, $$344]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$343, $$344]  |PARTITIONED|
-                                              -- SORT_GROUP_BY[$$292, $$293]  |PARTITIONED|
-                                                      {
+                                              group by ([$$343 := $$292; $$344 := $$293]) decor ([]) {
+                                                        aggregate [$$342] <- [agg-sql-count(1)]
                                                         -- AGGREGATE  |LOCAL|
+                                                          nested tuple source
                                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                      }
+                                                     }
+                                              -- SORT_GROUP_BY[$$292, $$293]  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  assign [$$293, $$292] <- [$$mds.getField("x"), $$mds.getField("jid")] project: [$$292, $$293]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    assign [$$mds] <- [$$332] project: [$$mds]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        replicate
                                                         -- REPLICATE  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            project ([$$332])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.mds)  |PARTITIONED|
+                                                                data-scan []<-[$$333, $$332] <- test.mds
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true)
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        select (eq($$322, $$318))
                         -- STREAM_SELECT  |PARTITIONED|
+                          window-aggregate [$$320] <- [row-number-impl()] partition [$$322, $$327, $$317, $$318, $$319]
                           -- WINDOW_STREAM  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$322) (ASC, $$327) (ASC, $$317) (ASC, $$318) (ASC, $$319)
                               -- STABLE_SORT [$$322(ASC), $$327(ASC), $$317(ASC), $$318(ASC), $$319(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$322, $$327, $$317, $$318, $$319])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      left outer join (eq($$322, $$325))
                                       -- HYBRID_HASH_JOIN [$$322][$$325]  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$322]  |PARTITIONED|
+                                          project ([$$322])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              replicate
                                               -- REPLICATE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.jds)  |PARTITIONED|
+                                                  data-scan []<-[$$322, $$324] <- test.jds
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$325]  |PARTITIONED|
+                                          assign [$$319, $$318, $$317] <- [$$327.getField("x"), $$327.getField("jid"), $$327.getField(0)]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$327] <- [{"jid": $$325, "x": $$328, "c1": $$329}] project: [$$325, $$327]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- SORT_GROUP_BY[$$346, $$347]  |PARTITIONED|
-                                                        {
+                                                group by ([$$325 := $$346; $$328 := $$347]) decor ([]) {
+                                                          aggregate [$$329] <- [agg-sql-sum($$345)]
                                                           -- AGGREGATE  |LOCAL|
+                                                            nested tuple source
                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                        }
+                                                       }
+                                                -- SORT_GROUP_BY[$$346, $$347]  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$346, $$347]  |PARTITIONED|
-                                                    -- SORT_GROUP_BY[$$330, $$331]  |PARTITIONED|
-                                                            {
+                                                    group by ([$$346 := $$330; $$347 := $$331]) decor ([]) {
+                                                              aggregate [$$345] <- [agg-sql-count(1)]
                                                               -- AGGREGATE  |LOCAL|
+                                                                nested tuple source
                                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                            }
+                                                           }
+                                                    -- SORT_GROUP_BY[$$330, $$331]  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        assign [$$330, $$331] <- [$$332.getField("jid"), $$332.getField("x")] project: [$$330, $$331]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            replicate
                                                             -- REPLICATE  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                project ([$$332])
                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- DATASOURCE_SCAN (test.mds)  |PARTITIONED|
+                                                                    data-scan []<-[$$333, $$332] <- test.mds
+                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        assign [$$310, $#6, $#5] <- [$$275.getField(0), $$275.getField("jid"), $$275.getField("y")] project: [$#6, $#5, $$310]
                         -- ASSIGN  |PARTITIONED|
+                          assign [$$275] <- [{"jid": $$jid, "y": $$y, "c2": $$300}] project: [$$275]
                           -- ASSIGN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- SORT_GROUP_BY[$$349, $$350]  |PARTITIONED|
-                                      {
+                              group by ([$$jid := $$349; $$y := $$350]) decor ([]) {
+                                        aggregate [$$300] <- [agg-sql-sum($$348)]
                                         -- AGGREGATE  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- SORT_GROUP_BY[$$349, $$350]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$349, $$350]  |PARTITIONED|
-                                  -- SORT_GROUP_BY[$$294, $$295]  |PARTITIONED|
-                                          {
+                                  group by ([$$349 := $$294; $$350 := $$295]) decor ([]) {
+                                            aggregate [$$348] <- [agg-sql-count(1)]
                                             -- AGGREGATE  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                          }
+                                         }
+                                  -- SORT_GROUP_BY[$$294, $$295]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$295, $$294] <- [$$mds.getField("y"), $$mds.getField("jid")] project: [$$294, $$295]
                                       -- ASSIGN  |PARTITIONED|
+                                        assign [$$mds] <- [$$332] project: [$$mds]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            replicate
                                             -- REPLICATE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$332])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (test.mds)  |PARTITIONED|
+                                                    data-scan []<-[$$333, $$332] <- test.mds
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-3006.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-3006.plan
index 0abba86..f4c8eb0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-3006.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/query-ASTERIXDB-3006.plan
@@ -1,38 +1,70 @@
+distribute result [$$ds1]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$ds1])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$58(ASC) ]  |PARTITIONED|
+        select (neq($$52, 0)) project: [$$ds1, $$58]
         -- STREAM_SELECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- SORT_GROUP_BY[$$68]  |PARTITIONED|
-                    {
+            group by ([$$58 := $$68]) decor ([$$ds1]) {
+                      aggregate [$$52] <- [agg-sum($$67)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$68]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$68]  |PARTITIONED|
-                -- PRE_CLUSTERED_GROUP_BY[$$49]  |PARTITIONED|
-                        {
+                group by ([$$68 := $$49]) decor ([$$ds1]) {
+                          aggregate [$$67] <- [agg-count({ "$1": 1 })]
                           -- AGGREGATE  |LOCAL|
+                            select (not(is-missing($$57)))
                             -- STREAM_SELECT  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- PRE_CLUSTERED_GROUP_BY[$$49]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$49)
                     -- STABLE_SORT [$$49(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$ds1, $$57, $$49])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            left outer join (eq($$51, $$b))
                             -- HYBRID_HASH_JOIN [$$b][$$51]  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$b]  |PARTITIONED|
+                                unnest $$b <- scan-collection($$53) project: [$$ds1, $$49, $$b]
                                 -- UNNEST  |PARTITIONED|
+                                  assign [$$53] <- [array-star($$ds1.getField("a")).getField("b")]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.ds1)  |PARTITIONED|
+                                      data-scan []<-[$$49, $$ds1] <- test.ds1
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$51]  |PARTITIONED|
+                                assign [$$57, $$51] <- [true, get-item($$ds2.getField("x"), 0).getField("y")] project: [$$57, $$51]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$ds2])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.ds2)  |PARTITIONED|
+                                      data-scan []<-[$$50, $$ds2] <- test.ds2
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_after/interval_after.3.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_after/interval_after.3.query.plan
index dcb2808..040a77c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_after/interval_after.3.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_after/interval_after.3.query.plan
@@ -1,28 +1,56 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"staff": $$32, "student": $$33}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      project ([$$32, $$33])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (interval-after($$34, $$35))
           -- INTERVAL_MERGE_JOIN [$$34] [$$35]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$34)
               -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$32, $$34])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- RANGE_PARTITION_EXCHANGE [$$38(ASC)] RANGE_MAP:{SPLIT:3}  |PARTITIONED|
+                      assign [$$38] <- [get-interval-start($$34)]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$34] <- [$$f.getField(2)] project: [$$32, $$34]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (TinyCollege.Staff)  |PARTITIONED|
+                            data-scan []<-[$$32, $$f] <- TinyCollege.Staff
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$35)
               -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$33, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- PARTIAL_BROADCAST_RANGE_FOLLOWING_EXCHANGE [$$40(ASC)] RANGE_MAP:{SPLIT:3}  |PARTITIONED|
+                      assign [$$40] <- [get-interval-start($$35)]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$35] <- [$$d.getField(2)] project: [$$33, $$35]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (TinyCollege.Students)  |PARTITIONED|
+                            data-scan []<-[$$33, $$d] <- TinyCollege.Students
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_before/interval_before.3.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_before/interval_before.3.query.plan
index b2b55dc..338fbf2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_before/interval_before.3.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_before/interval_before.3.query.plan
@@ -1,28 +1,56 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"staff": $$32, "student": $$33}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      project ([$$32, $$33])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (interval-before($$34, $$35))
           -- INTERVAL_MERGE_JOIN [$$34] [$$35]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$34)
               -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$32, $$34])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- PARTIAL_BROADCAST_RANGE_FOLLOWING_EXCHANGE [$$38(ASC)] RANGE_MAP:{SPLIT:3}  |PARTITIONED|
+                      assign [$$38] <- [get-interval-start($$34)]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$34] <- [$$f.getField(2)] project: [$$32, $$34]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (TinyCollege.Staff)  |PARTITIONED|
+                            data-scan []<-[$$32, $$f] <- TinyCollege.Staff
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$35)
               -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$33, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- RANGE_PARTITION_EXCHANGE [$$40(ASC)] RANGE_MAP:{SPLIT:3}  |PARTITIONED|
+                      assign [$$40] <- [get-interval-start($$35)]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$35] <- [$$d.getField(2)] project: [$$33, $$35]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (TinyCollege.Students)  |PARTITIONED|
+                            data-scan []<-[$$33, $$d] <- TinyCollege.Students
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_covered_by/interval_covered_by.3.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_covered_by/interval_covered_by.3.query.plan
index 1be636a..7cb3085 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_covered_by/interval_covered_by.3.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_covered_by/interval_covered_by.3.query.plan
@@ -1,28 +1,56 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"staff": $$32, "student": $$33}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      project ([$$32, $$33])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (interval-covered-by($$34, $$35))
           -- INTERVAL_MERGE_JOIN [$$34] [$$35]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$34)
               -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$32, $$34])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- RANGE_PARTITION_EXCHANGE [$$38(ASC)] RANGE_MAP:{SPLIT:3}  |PARTITIONED|
+                      assign [$$38] <- [get-interval-start($$34)]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$34] <- [$$f.getField(2)] project: [$$32, $$34]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (TinyCollege.Staff)  |PARTITIONED|
+                            data-scan []<-[$$32, $$f] <- TinyCollege.Staff
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$35)
               -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$33, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- PARTIAL_BROADCAST_RANGE_INTERSECT_EXCHANGE [{$$40,$$41,ASC}] RANGE_MAP:{SPLIT:3}  |PARTITIONED|
+                      assign [$$40, $$41] <- [get-interval-start($$35), get-interval-end($$35)]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$35] <- [$$d.getField(2)] project: [$$33, $$35]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (TinyCollege.Students)  |PARTITIONED|
+                            data-scan []<-[$$33, $$d] <- TinyCollege.Students
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_covers/interval_covers.3.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_covers/interval_covers.3.query.plan
index 5fed08f..ab5dba2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_covers/interval_covers.3.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_covers/interval_covers.3.query.plan
@@ -1,28 +1,56 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"staff": $$32, "student": $$33}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      project ([$$32, $$33])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (interval-covers($$34, $$35))
           -- INTERVAL_MERGE_JOIN [$$34] [$$35]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$34)
               -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$32, $$34])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- PARTIAL_BROADCAST_RANGE_INTERSECT_EXCHANGE [{$$38,$$39,ASC}] RANGE_MAP:{SPLIT:3}  |PARTITIONED|
+                      assign [$$38, $$39] <- [get-interval-start($$34), get-interval-end($$34)]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$34] <- [$$f.getField(2)] project: [$$32, $$34]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (TinyCollege.Staff)  |PARTITIONED|
+                            data-scan []<-[$$32, $$f] <- TinyCollege.Staff
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$35)
               -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$33, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- RANGE_PARTITION_EXCHANGE [$$40(ASC)] RANGE_MAP:{SPLIT:3}  |PARTITIONED|
+                      assign [$$40] <- [get-interval-start($$35)]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$35] <- [$$d.getField(2)] project: [$$33, $$35]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (TinyCollege.Students)  |PARTITIONED|
+                            data-scan []<-[$$33, $$d] <- TinyCollege.Students
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_ended_by/interval_ended_by.3.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_ended_by/interval_ended_by.3.query.plan
index 96456f1..7e091b3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_ended_by/interval_ended_by.3.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_ended_by/interval_ended_by.3.query.plan
@@ -1,21 +1,42 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"staff": $$34, "student": $$35}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      select (le($$36, $$37)) project: [$$34, $$35]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$34, $$37, $$35, $$36])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$38, $$39))
             -- HYBRID_HASH_JOIN [$$38][$$39]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+                assign [$$38, $$37] <- [get-interval-end($$33), get-interval-start($$33)] project: [$$34, $$37, $$38]
                 -- ASSIGN  |PARTITIONED|
+                  assign [$$33] <- [$$f.getField(2)] project: [$$34, $$33]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TinyCollege.Staff)  |PARTITIONED|
+                      data-scan []<-[$$34, $$f] <- TinyCollege.Staff
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$39]  |PARTITIONED|
+                assign [$$39, $$36] <- [get-interval-end($$32), get-interval-start($$32)] project: [$$35, $$36, $$39]
                 -- ASSIGN  |PARTITIONED|
+                  assign [$$32] <- [$$d.getField(2)] project: [$$35, $$32]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TinyCollege.Students)  |PARTITIONED|
+                      data-scan []<-[$$35, $$d] <- TinyCollege.Students
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_ends/interval_ends.3.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_ends/interval_ends.3.query.plan
index 96456f1..f14b06a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_ends/interval_ends.3.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_ends/interval_ends.3.query.plan
@@ -1,21 +1,42 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"staff": $$34, "student": $$35}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      select (le($$36, $$37)) project: [$$34, $$35]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$34, $$36, $$35, $$37])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$38, $$39))
             -- HYBRID_HASH_JOIN [$$38][$$39]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+                assign [$$38, $$36] <- [get-interval-end($$32), get-interval-start($$32)] project: [$$34, $$36, $$38]
                 -- ASSIGN  |PARTITIONED|
+                  assign [$$32] <- [$$f.getField(2)] project: [$$34, $$32]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TinyCollege.Staff)  |PARTITIONED|
+                      data-scan []<-[$$34, $$f] <- TinyCollege.Staff
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$39]  |PARTITIONED|
+                assign [$$39, $$37] <- [get-interval-end($$33), get-interval-start($$33)] project: [$$35, $$37, $$39]
                 -- ASSIGN  |PARTITIONED|
+                  assign [$$33] <- [$$d.getField(2)] project: [$$35, $$33]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TinyCollege.Students)  |PARTITIONED|
+                      data-scan []<-[$$35, $$d] <- TinyCollege.Students
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_meets/interval_meets.3.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_meets/interval_meets.3.query.plan
index c9ecb47..34bbe14 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_meets/interval_meets.3.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_meets/interval_meets.3.query.plan
@@ -1,18 +1,36 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"staff": $$32, "student": $$33}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      project ([$$32, $$33])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$34, $$35))
           -- HYBRID_HASH_JOIN [$$34][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
+              assign [$$34] <- [get-interval-end($$f.getField(2))] project: [$$32, $$34]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TinyCollege.Staff)  |PARTITIONED|
+                  data-scan []<-[$$32, $$f] <- TinyCollege.Staff
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              assign [$$35] <- [get-interval-start($$d.getField(2))] project: [$$33, $$35]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TinyCollege.Students)  |PARTITIONED|
+                  data-scan []<-[$$33, $$d] <- TinyCollege.Students
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_met_by/interval_met_by.3.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_met_by/interval_met_by.3.query.plan
index c9ecb47..1fc0818 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_met_by/interval_met_by.3.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_met_by/interval_met_by.3.query.plan
@@ -1,18 +1,36 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"staff": $$32, "student": $$33}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      project ([$$32, $$33])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$34, $$35))
           -- HYBRID_HASH_JOIN [$$34][$$35]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
+              assign [$$34] <- [get-interval-start($$f.getField(2))] project: [$$32, $$34]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TinyCollege.Staff)  |PARTITIONED|
+                  data-scan []<-[$$32, $$f] <- TinyCollege.Staff
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
+              assign [$$35] <- [get-interval-end($$d.getField(2))] project: [$$33, $$35]
               -- ASSIGN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TinyCollege.Students)  |PARTITIONED|
+                  data-scan []<-[$$33, $$d] <- TinyCollege.Students
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_overlapped_by/interval_overlapped_by.3.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_overlapped_by/interval_overlapped_by.3.query.plan
index 1be636a..b24f18b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_overlapped_by/interval_overlapped_by.3.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_overlapped_by/interval_overlapped_by.3.query.plan
@@ -1,28 +1,56 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"staff": $$32, "student": $$33}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      project ([$$32, $$33])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (interval-overlapped-by($$34, $$35))
           -- INTERVAL_MERGE_JOIN [$$34] [$$35]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$34)
               -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$32, $$34])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- RANGE_PARTITION_EXCHANGE [$$38(ASC)] RANGE_MAP:{SPLIT:3}  |PARTITIONED|
+                      assign [$$38] <- [get-interval-start($$34)]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$34] <- [$$f.getField(2)] project: [$$32, $$34]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (TinyCollege.Staff)  |PARTITIONED|
+                            data-scan []<-[$$32, $$f] <- TinyCollege.Staff
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$35)
               -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$33, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- PARTIAL_BROADCAST_RANGE_INTERSECT_EXCHANGE [{$$40,$$41,ASC}] RANGE_MAP:{SPLIT:3}  |PARTITIONED|
+                      assign [$$40, $$41] <- [get-interval-start($$35), get-interval-end($$35)]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$35] <- [$$d.getField(2)] project: [$$33, $$35]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (TinyCollege.Students)  |PARTITIONED|
+                            data-scan []<-[$$33, $$d] <- TinyCollege.Students
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_overlapping/interval_overlapping.3.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_overlapping/interval_overlapping.3.query.plan
index 6f42f1f..1e1d97b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_overlapping/interval_overlapping.3.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_overlapping/interval_overlapping.3.query.plan
@@ -1,28 +1,56 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"staff": $$32, "student": $$33}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      project ([$$32, $$33])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (interval-overlapping($$34, $$35))
           -- INTERVAL_MERGE_JOIN [$$34] [$$35]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$34)
               -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$32, $$34])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- PARTIAL_BROADCAST_RANGE_INTERSECT_EXCHANGE [{$$38,$$39,ASC}] RANGE_MAP:{SPLIT:3}  |PARTITIONED|
+                      assign [$$38, $$39] <- [get-interval-start($$34), get-interval-end($$34)]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$34] <- [$$f.getField(2)] project: [$$32, $$34]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (TinyCollege.Staff)  |PARTITIONED|
+                            data-scan []<-[$$32, $$f] <- TinyCollege.Staff
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$35)
               -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$33, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- PARTIAL_BROADCAST_RANGE_INTERSECT_EXCHANGE [{$$40,$$41,ASC}] RANGE_MAP:{SPLIT:3}  |PARTITIONED|
+                      assign [$$40, $$41] <- [get-interval-start($$35), get-interval-end($$35)]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$35] <- [$$d.getField(2)] project: [$$33, $$35]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (TinyCollege.Students)  |PARTITIONED|
+                            data-scan []<-[$$33, $$d] <- TinyCollege.Students
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_overlaps/interval_overlaps.3.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_overlaps/interval_overlaps.3.query.plan
index 5fed08f..6c63b33 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_overlaps/interval_overlaps.3.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_overlaps/interval_overlaps.3.query.plan
@@ -1,28 +1,56 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"staff": $$32, "student": $$33}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      project ([$$32, $$33])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (interval-overlaps($$34, $$35))
           -- INTERVAL_MERGE_JOIN [$$34] [$$35]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$34)
               -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$32, $$34])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- PARTIAL_BROADCAST_RANGE_INTERSECT_EXCHANGE [{$$38,$$39,ASC}] RANGE_MAP:{SPLIT:3}  |PARTITIONED|
+                      assign [$$38, $$39] <- [get-interval-start($$34), get-interval-end($$34)]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$34] <- [$$f.getField(2)] project: [$$32, $$34]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (TinyCollege.Staff)  |PARTITIONED|
+                            data-scan []<-[$$32, $$f] <- TinyCollege.Staff
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$35)
               -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$33, $$35])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- RANGE_PARTITION_EXCHANGE [$$40(ASC)] RANGE_MAP:{SPLIT:3}  |PARTITIONED|
+                      assign [$$40] <- [get-interval-start($$35)]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$35] <- [$$d.getField(2)] project: [$$33, $$35]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (TinyCollege.Students)  |PARTITIONED|
+                            data-scan []<-[$$33, $$d] <- TinyCollege.Students
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_started_by/interval_started_by.3.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_started_by/interval_started_by.3.query.plan
index de9130d..7e13e56 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_started_by/interval_started_by.3.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_started_by/interval_started_by.3.query.plan
@@ -1,21 +1,42 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"staff": $$34, "student": $$35}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      select (le($$38, $$39)) project: [$$34, $$35]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$34, $$39, $$35, $$38])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$36, $$37))
             -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                assign [$$39, $$36] <- [get-interval-end($$32), get-interval-start($$32)] project: [$$34, $$36, $$39]
                 -- ASSIGN  |PARTITIONED|
+                  assign [$$32] <- [$$f.getField(2)] project: [$$34, $$32]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TinyCollege.Staff)  |PARTITIONED|
+                      data-scan []<-[$$34, $$f] <- TinyCollege.Staff
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                assign [$$38, $$37] <- [get-interval-end($$33), get-interval-start($$33)] project: [$$35, $$37, $$38]
                 -- ASSIGN  |PARTITIONED|
+                  assign [$$33] <- [$$d.getField(2)] project: [$$35, $$33]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TinyCollege.Students)  |PARTITIONED|
+                      data-scan []<-[$$35, $$d] <- TinyCollege.Students
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_starts/interval_starts.3.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_starts/interval_starts.3.query.plan
index de9130d..e0a5afa 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_starts/interval_starts.3.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/temporal/interval_joins/interval_starts/interval_starts.3.query.plan
@@ -1,21 +1,42 @@
+distribute result [$$31]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"staff": $$34, "student": $$35}] project: [$$31]
     -- ASSIGN  |PARTITIONED|
+      select (le($$38, $$39)) project: [$$34, $$35]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$34, $$38, $$35, $$39])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$36, $$37))
             -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                assign [$$38, $$36] <- [get-interval-end($$32), get-interval-start($$32)] project: [$$34, $$36, $$38]
                 -- ASSIGN  |PARTITIONED|
+                  assign [$$32] <- [$$f.getField(2)] project: [$$34, $$32]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TinyCollege.Staff)  |PARTITIONED|
+                      data-scan []<-[$$34, $$f] <- TinyCollege.Staff
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                assign [$$39, $$37] <- [get-interval-end($$33), get-interval-start($$33)] project: [$$35, $$37, $$39]
                 -- ASSIGN  |PARTITIONED|
+                  assign [$$33] <- [$$d.getField(2)] project: [$$35, $$33]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TinyCollege.Students)  |PARTITIONED|
+                      data-scan []<-[$$35, $$d] <- TinyCollege.Students
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1580.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1580.plan
index 329988f..1e968a7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1580.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1580.plan
@@ -1,69 +1,132 @@
+distribute result [$$125]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 100
     -- STREAM_LIMIT  |UNPARTITIONED|
+      assign [$$125] <- [{"state": $$ca_state, "cnt": $$136}] project: [$$125]
       -- ASSIGN  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$136(ASC) ]  |PARTITIONED|
+          limit 100
           -- STREAM_LIMIT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (topK: 100) (ASC, $$136)
               -- STABLE_SORT [topK: 100] [$$136(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (ge($$135, 10)) project: [$$ca_state, $$136]
                   -- STREAM_SELECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- SORT_GROUP_BY[$$145]  |PARTITIONED|
-                              {
+                      group by ([$$ca_state := $$145]) decor ([]) {
+                                aggregate [$$135, $$136] <- [agg-sql-sum($$143), agg-sql-sum($$144)]
                                 -- AGGREGATE  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- SORT_GROUP_BY[$$145]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$145]  |PARTITIONED|
-                          -- SORT_GROUP_BY[$$126]  |PARTITIONED|
-                                  {
+                          group by ([$$145 := $$126]) decor ([]) {
+                                    aggregate [$$143, $$144] <- [agg-sql-count($$a), agg-sql-count($$a)]
                                     -- AGGREGATE  |LOCAL|
+                                      nested tuple source
                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
+                                 }
+                          -- SORT_GROUP_BY[$$126]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$a, $$126])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  join (eq($$129, $$132))
                                   -- HYBRID_HASH_JOIN [$$129][$$132]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$129]  |PARTITIONED|
+                                      project ([$$a, $$126, $$129])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          join (eq($$137, $$131))
                                           -- HYBRID_HASH_JOIN [$$137][$$131]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$137]  |PARTITIONED|
+                                              project ([$$a, $$126, $$129, $$137])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  join (eq($$128, $$142))
                                                   -- HYBRID_HASH_JOIN [$$128][$$142]  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$128]  |PARTITIONED|
+                                                      project ([$$a, $$126, $$128])
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          join (eq($$127, $$140))
                                                           -- HYBRID_HASH_JOIN [$$127][$$140]  |PARTITIONED|
+                                                            exchange
                                                             -- HASH_PARTITION_EXCHANGE [$$127]  |PARTITIONED|
+                                                              assign [$$126] <- [$$a.getField(8)]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- DATASOURCE_SCAN (tpcds.customer_address)  |PARTITIONED|
+                                                                  data-scan []<-[$$127, $$a] <- tpcds.customer_address
+                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                            exchange
                                                             -- HASH_PARTITION_EXCHANGE [$$140]  |PARTITIONED|
+                                                              assign [$$140] <- [$$c.getField(4)] project: [$$128, $$140]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- DATASOURCE_SCAN (tpcds.customer)  |PARTITIONED|
+                                                                  data-scan []<-[$$128, $$c] <- tpcds.customer
+                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$142]  |PARTITIONED|
+                                                      assign [$$137, $$142] <- [$$s.getField(0), $$s.getField(3)] project: [$$129, $$137, $$142]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$129, $$s])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                            data-scan []<-[$$129, $$130, $$s] <- tpcds.store_sales
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$131]  |PARTITIONED|
+                                              project ([$$131])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (tpcds.date_dim)  |PARTITIONED|
+                                                  data-scan []<-[$$131, $$d] <- tpcds.date_dim
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$132]  |PARTITIONED|
+                                      project ([$$132])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (tpcds.item)  |PARTITIONED|
+                                          data-scan []<-[$$132, $$i] <- tpcds.item
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581-2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581-2.plan
index 1daf3a5..20ee0a4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581-2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581-2.plan
@@ -1,121 +1,242 @@
+distribute result [$$149]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$149] <- [{"bucket1": $$147}] project: [$$149]
     -- ASSIGN  |PARTITIONED|
+      unnest $$147 <- scan-collection($$146) project: [$$147]
       -- UNNEST  |PARTITIONED|
+        assign [$$146] <- [switch-case(true, lt(get-item($$109, 0), 25437), cast($$128), cast($$145))] project: [$$146]
         -- ASSIGN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (true)
             -- NESTED_LOOP  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (true)
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true)
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (tpcds.item.item)  |PARTITIONED|
+                            unnest-map [$$153, $$item] <- index-search("item", 0, "Default", "tpcds", "item", false, false, 1, $$212, 1, $$213, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$212, $$213] <- [1, 1]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        aggregate [$$145] <- [listify($$144)]
                         -- AGGREGATE  |UNPARTITIONED|
+                          aggregate [$$144] <- [listify($$143)]
                           -- AGGREGATE  |UNPARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                              join (true)
                               -- NESTED_LOOP  |UNPARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                  select (not(or(and($$216, not(is-unknown($$216)))))) project: []
                                   -- STREAM_SELECT  |UNPARTITIONED|
+                                    assign [$$216] <- [lt(get-item($$192, 0), 25437)] project: [$$216]
                                     -- ASSIGN  |UNPARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        replicate
                                         -- REPLICATE  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            aggregate [$$192] <- [listify($$194)]
                                             -- AGGREGATE  |UNPARTITIONED|
+                                              aggregate [$$194] <- [agg-sql-sum($$207)]
                                               -- AGGREGATE  |UNPARTITIONED|
+                                                exchange
                                                 -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                  aggregate [$$207] <- [agg-sql-count(1)]
                                                   -- AGGREGATE  |PARTITIONED|
+                                                    select (and(le($$200, 20), ge($$200, 1)))
                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                      assign [$$200] <- [$$199.getField(10)] project: [$$200]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        assign [$$199] <- [$$165] project: [$$199]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            replicate
                                                             -- REPLICATE  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                project ([$$165])
                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                    data-scan []<-[$$167, $$168, $$165] <- tpcds.store_sales
+                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                  assign [$$143] <- [{"$2": $$162}] project: [$$143]
                                   -- ASSIGN  |UNPARTITIONED|
+                                    aggregate [$$162] <- [agg-global-sql-avg($$208)]
                                     -- AGGREGATE  |UNPARTITIONED|
+                                      exchange
                                       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                        aggregate [$$208] <- [agg-local-sql-avg($$141)]
                                         -- AGGREGATE  |PARTITIONED|
+                                          select (and(le($$166, 20), ge($$166, 1))) project: [$$141]
                                           -- STREAM_SELECT  |PARTITIONED|
+                                            assign [$$141, $$166] <- [$$165.getField(22), $$165.getField(10)] project: [$$141, $$166]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    project ([$$165])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                        data-scan []<-[$$167, $$168, $$165] <- tpcds.store_sales
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    aggregate [$$128] <- [listify($$127)]
                     -- AGGREGATE  |UNPARTITIONED|
+                      aggregate [$$127] <- [listify($$126)]
                       -- AGGREGATE  |UNPARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                          join (true)
                           -- NESTED_LOOP  |UNPARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                              select (lt(get-item($$181, 0), 25437)) project: []
                               -- STREAM_SELECT  |UNPARTITIONED|
+                                assign [$$181] <- [$$192] project: [$$181]
                                 -- ASSIGN  |UNPARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                    replicate
                                     -- REPLICATE  |UNPARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        aggregate [$$192] <- [listify($$194)]
                                         -- AGGREGATE  |UNPARTITIONED|
+                                          aggregate [$$194] <- [agg-sql-sum($$207)]
                                           -- AGGREGATE  |UNPARTITIONED|
+                                            exchange
                                             -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                              aggregate [$$207] <- [agg-sql-count(1)]
                                               -- AGGREGATE  |PARTITIONED|
+                                                select (and(le($$200, 20), ge($$200, 1)))
                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                  assign [$$200] <- [$$199.getField(10)] project: [$$200]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    assign [$$199] <- [$$165] project: [$$199]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        replicate
                                                         -- REPLICATE  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            project ([$$165])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                data-scan []<-[$$167, $$168, $$165] <- tpcds.store_sales
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                              assign [$$126] <- [{"$1": $$161}] project: [$$126]
                               -- ASSIGN  |UNPARTITIONED|
+                                aggregate [$$161] <- [agg-global-sql-avg($$210)]
                                 -- AGGREGATE  |UNPARTITIONED|
+                                  exchange
                                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                    aggregate [$$210] <- [agg-local-sql-avg($$124)]
                                     -- AGGREGATE  |PARTITIONED|
+                                      select (and(le($$172, 20), ge($$172, 1))) project: [$$124]
                                       -- STREAM_SELECT  |PARTITIONED|
+                                        assign [$$124, $$172] <- [$$171.getField(14), $$171.getField(10)] project: [$$124, $$172]
                                         -- ASSIGN  |PARTITIONED|
+                                          assign [$$171] <- [$$165] project: [$$171]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              replicate
                                               -- REPLICATE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  project ([$$165])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                      data-scan []<-[$$167, $$168, $$165] <- tpcds.store_sales
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                assign [$$109] <- [$$192] project: [$$109]
                 -- ASSIGN  |UNPARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                    replicate
                     -- REPLICATE  |UNPARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                        aggregate [$$192] <- [listify($$194)]
                         -- AGGREGATE  |UNPARTITIONED|
+                          aggregate [$$194] <- [agg-sql-sum($$207)]
                           -- AGGREGATE  |UNPARTITIONED|
+                            exchange
                             -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                              aggregate [$$207] <- [agg-sql-count(1)]
                               -- AGGREGATE  |PARTITIONED|
+                                select (and(le($$200, 20), ge($$200, 1)))
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$200] <- [$$199.getField(10)] project: [$$200]
                                   -- ASSIGN  |PARTITIONED|
+                                    assign [$$199] <- [$$165] project: [$$199]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$165])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                data-scan []<-[$$167, $$168, $$165] <- tpcds.store_sales
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581-correlated-2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581-correlated-2.plan
index e0a721d..32968f9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581-correlated-2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581-correlated-2.plan
@@ -1,320 +1,601 @@
+distribute result [$$143]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$143] <- [{"bucket1": $$141}] project: [$$143]
     -- ASSIGN  |PARTITIONED|
+      unnest $$141 <- scan-collection($$140) project: [$$141]
       -- UNNEST  |PARTITIONED|
+        assign [$$140] <- [switch-case(true, lt(get-item($$107, 0), 25437), cast($$124), cast($$139))] project: [$$140]
         -- ASSIGN  |PARTITIONED|
+          project ([$$107, $$139, $$124])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- PRE_CLUSTERED_GROUP_BY[$$234]  |PARTITIONED|
-                      {
+              group by ([$$236 := $$234]) decor ([$$139; $$124]) {
+                        aggregate [$$107] <- [listify($$151)]
                         -- AGGREGATE  |LOCAL|
+                          aggregate [$$151] <- [agg-sql-count(1)]
                           -- AGGREGATE  |LOCAL|
+                            select (not(is-missing($$235)))
                             -- STREAM_SELECT  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                      }
+                     }
+              -- PRE_CLUSTERED_GROUP_BY[$$234]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$234)
                   -- STABLE_SORT [$$234(ASC)]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$124, $$139, $$235, $$234])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          left outer join (eq($$182, $$234))
                           -- HYBRID_HASH_JOIN [$$234][$$182]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$196]  |PARTITIONED|
-                                      {
+                              group by ([$$234 := $$196]) decor ([$$139]) {
+                                        aggregate [$$124] <- [listify($$123)]
                                         -- AGGREGATE  |LOCAL|
+                                          aggregate [$$123] <- [listify($$122)]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$233)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$196]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$139, $$122, $$233, $$196])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      left outer join (eq($$196, $$232))
                                       -- HYBRID_HASH_JOIN [$$196][$$232]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- PRE_CLUSTERED_GROUP_BY[$$144]  |PARTITIONED|
-                                                  {
+                                          group by ([$$196 := $$144]) decor ([]) {
+                                                    aggregate [$$139] <- [listify($$138)]
                                                     -- AGGREGATE  |LOCAL|
+                                                      aggregate [$$138] <- [listify($$137)]
                                                       -- AGGREGATE  |LOCAL|
+                                                        select (not(is-missing($$195)))
                                                         -- STREAM_SELECT  |LOCAL|
+                                                          nested tuple source
                                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                  }
+                                                 }
+                                          -- PRE_CLUSTERED_GROUP_BY[$$144]  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              order (ASC, $$144)
                                               -- STABLE_SORT [$$144(ASC)]  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  project ([$$137, $$195, $$144])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      left outer join (eq($$144, $$194))
                                                       -- HYBRID_HASH_JOIN [$$144][$$194]  |PARTITIONED|
+                                                        exchange
                                                         -- HASH_PARTITION_EXCHANGE [$$144]  |PARTITIONED|
+                                                          project ([$$144])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              assign [$$144, $$item] <- [$$215, $$212] project: [$$144, $$item]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  replicate
                                                                   -- REPLICATE  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- BTREE_SEARCH (tpcds.item.item)  |PARTITIONED|
+                                                                      unnest-map [$$215, $$212] <- index-search("item", 0, "Default", "tpcds", "item", false, false, 1, $$260, 1, $$261, true, true, true)
+                                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          assign [$$260, $$261] <- [1, 1]
                                                                           -- ASSIGN  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                        exchange
                                                         -- HASH_PARTITION_EXCHANGE [$$194]  |PARTITIONED|
+                                                          assign [$$195, $$137] <- [true, {"$2": $$153}] project: [$$137, $$195, $$194]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            project ([$$153, $$194])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- SORT_GROUP_BY[$$240, $$241]  |PARTITIONED|
-                                                                        {
+                                                                group by ([$$190 := $$240; $$194 := $$241]) decor ([]) {
+                                                                          aggregate [$$153] <- [agg-global-sql-avg($$239)]
                                                                           -- AGGREGATE  |LOCAL|
+                                                                            nested tuple source
                                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                        }
+                                                                       }
+                                                                -- SORT_GROUP_BY[$$240, $$241]  |PARTITIONED|
+                                                                  exchange
                                                                   -- HASH_PARTITION_EXCHANGE [$$240, $$241]  |PARTITIONED|
-                                                                    -- PRE_CLUSTERED_GROUP_BY[$$188, $$193]  |PARTITIONED|
-                                                                            {
+                                                                    group by ([$$240 := $$188; $$241 := $$193]) decor ([]) {
+                                                                              aggregate [$$239] <- [agg-local-sql-avg($$135)]
                                                                               -- AGGREGATE  |LOCAL|
+                                                                                select (not(is-missing($$189)))
                                                                                 -- STREAM_SELECT  |LOCAL|
+                                                                                  nested tuple source
                                                                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                            }
+                                                                           }
+                                                                    -- PRE_CLUSTERED_GROUP_BY[$$188, $$193]  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        order (ASC, $$188) (ASC, $$193)
                                                                         -- STABLE_SORT [$$188(ASC), $$193(ASC)]  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            project ([$$135, $$189, $$188, $$193])
                                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                left outer join (eq($$176, $$177))
                                                                                 -- HYBRID_HASH_JOIN [$$177][$$176]  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    assign [$$193, $$177, $$188] <- [$$210, $$211, $$209] project: [$$193, $$177, $$188]
                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        replicate
                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- HASH_PARTITION_EXCHANGE [$$211]  |PARTITIONED|
+                                                                                            running-aggregate [$$209] <- [create-query-uid()]
                                                                                             -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                                                              assign [$$211] <- [$$212.getField(0)] project: [$$210, $$211]
                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                select (not(or(and($$265, not(is-unknown($$265)))))) project: [$$210, $$212]
                                                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                                                  assign [$$265] <- [lt(get-item($$213, 0), 25437)] project: [$$210, $$212, $$265]
                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$215]  |PARTITIONED|
-                                                                                                              {
+                                                                                                      group by ([$$210 := $$215]) decor ([$$212]) {
+                                                                                                                aggregate [$$213] <- [listify($$221)]
                                                                                                                 -- AGGREGATE  |LOCAL|
+                                                                                                                  aggregate [$$221] <- [agg-sql-count(1)]
                                                                                                                   -- AGGREGATE  |LOCAL|
+                                                                                                                    select (not(is-missing($$217)))
                                                                                                                     -- STREAM_SELECT  |LOCAL|
+                                                                                                                      nested tuple source
                                                                                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                              }
+                                                                                                             }
+                                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$215]  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                          order (ASC, $$215)
                                                                                                           -- STABLE_SORT [$$215(ASC)]  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                              project ([$$212, $$217, $$215])
                                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                exchange
                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                  left outer join (eq($$216, $$215))
                                                                                                                   -- HYBRID_HASH_JOIN [$$215][$$216]  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                      replicate
                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                        exchange
                                                                                                                         -- HASH_PARTITION_EXCHANGE [$$215]  |PARTITIONED|
+                                                                                                                          replicate
                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                              -- BTREE_SEARCH (tpcds.item.item)  |PARTITIONED|
+                                                                                                                              unnest-map [$$215, $$212] <- index-search("item", 0, "Default", "tpcds", "item", false, false, 1, $$260, 1, $$261, true, true, true)
+                                                                                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                                                                                exchange
                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                  assign [$$260, $$261] <- [1, 1]
                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                    empty-tuple-source
                                                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                      assign [$$217, $$216] <- [$$222, $$214] project: [$$217, $$216]
                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                        exchange
                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                          replicate
                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$214]  |PARTITIONED|
+                                                                                                                              assign [$$222, $$214] <- [true, $$223.getField(10)] project: [$$222, $$214]
                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                assign [$$223] <- [$$store_sales] project: [$$223]
                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                  exchange
                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                    replicate
                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                      exchange
                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                        project ([$$store_sales])
                                                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                          exchange
                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                            -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                                                                            data-scan []<-[$$149, $$150, $$store_sales] <- tpcds.store_sales
+                                                                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                              exchange
                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                empty-tuple-source
                                                                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- HASH_PARTITION_EXCHANGE [$$176]  |PARTITIONED|
+                                                                                    assign [$$189, $$135, $$176] <- [true, $$store_sales.getField(22), $$store_sales.getField(10)] project: [$$135, $$189, $$176]
                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        replicate
                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            project ([$$store_sales])
                                                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                                data-scan []<-[$$149, $$150, $$store_sales] <- tpcds.store_sales
+                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    empty-tuple-source
                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$232]  |PARTITIONED|
+                                          assign [$$233, $$122] <- [true, {"$1": $$152}] project: [$$122, $$233, $$232]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$152, $$232])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- SORT_GROUP_BY[$$246, $$247]  |PARTITIONED|
-                                                        {
+                                                group by ([$$200 := $$246; $$232 := $$247]) decor ([]) {
+                                                          aggregate [$$152] <- [agg-global-sql-avg($$245)]
                                                           -- AGGREGATE  |LOCAL|
+                                                            nested tuple source
                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                        }
+                                                       }
+                                                -- SORT_GROUP_BY[$$246, $$247]  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$246, $$247]  |PARTITIONED|
-                                                    -- PRE_CLUSTERED_GROUP_BY[$$198, $$231]  |PARTITIONED|
-                                                            {
+                                                    group by ([$$246 := $$198; $$247 := $$231]) decor ([]) {
+                                                              aggregate [$$245] <- [agg-local-sql-avg($$120)]
                                                               -- AGGREGATE  |LOCAL|
+                                                                select (not(is-missing($$199)))
                                                                 -- STREAM_SELECT  |LOCAL|
+                                                                  nested tuple source
                                                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                            }
+                                                           }
+                                                    -- PRE_CLUSTERED_GROUP_BY[$$198, $$231]  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        order (ASC, $$198) (ASC, $$231)
                                                         -- STABLE_SORT [$$198(ASC), $$231(ASC)]  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            project ([$$120, $$199, $$198, $$231])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                left outer join (eq($$180, $$181))
                                                                 -- HYBRID_HASH_JOIN [$$181][$$180]  |PARTITIONED|
+                                                                  exchange
                                                                   -- HASH_PARTITION_EXCHANGE [$$181]  |PARTITIONED|
+                                                                    running-aggregate [$$198] <- [create-query-uid()]
                                                                     -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                                      assign [$$181] <- [$$203.getField(0)] project: [$$231, $$181]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        select (lt(get-item($$154, 0), 25437)) project: [$$231, $$203]
                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- PRE_CLUSTERED_GROUP_BY[$$201]  |PARTITIONED|
-                                                                                    {
+                                                                            group by ([$$231 := $$201]) decor ([$$203]) {
+                                                                                      aggregate [$$154] <- [listify($$156)]
                                                                                       -- AGGREGATE  |LOCAL|
+                                                                                        aggregate [$$156] <- [agg-sql-count(1)]
                                                                                         -- AGGREGATE  |LOCAL|
+                                                                                          select (not(is-missing($$197)))
                                                                                           -- STREAM_SELECT  |LOCAL|
+                                                                                            nested tuple source
                                                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                    }
+                                                                                   }
+                                                                            -- PRE_CLUSTERED_GROUP_BY[$$201]  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                project ([$$203, $$197, $$201])
                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    left outer join (eq($$178, $$201))
                                                                                     -- HYBRID_HASH_JOIN [$$201][$$178]  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$202]  |PARTITIONED|
-                                                                                                {
+                                                                                        group by ([$$201 := $$202]) decor ([$$203]) {
+                                                                                                  aggregate [] <- []
                                                                                                   -- AGGREGATE  |LOCAL|
+                                                                                                    aggregate [] <- []
                                                                                                     -- AGGREGATE  |LOCAL|
+                                                                                                      select (not(is-missing($$205)))
                                                                                                       -- STREAM_SELECT  |LOCAL|
+                                                                                                        nested tuple source
                                                                                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                }
+                                                                                               }
+                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$202]  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            order (ASC, $$202)
                                                                                             -- STABLE_SORT [$$202(ASC)]  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                project ([$$203, $$205, $$202])
                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    left outer join (eq($$202, $$204))
                                                                                                     -- HYBRID_HASH_JOIN [$$202][$$204]  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                        assign [$$202, $$203] <- [$$215, $$212] project: [$$202, $$203]
                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                          exchange
                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                            replicate
                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                              exchange
                                                                                                               -- HASH_PARTITION_EXCHANGE [$$215]  |PARTITIONED|
+                                                                                                                replicate
                                                                                                                 -- REPLICATE  |PARTITIONED|
+                                                                                                                  exchange
                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                    -- BTREE_SEARCH (tpcds.item.item)  |PARTITIONED|
+                                                                                                                    unnest-map [$$215, $$212] <- index-search("item", 0, "Default", "tpcds", "item", false, false, 1, $$260, 1, $$261, true, true, true)
+                                                                                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                                                                                      exchange
                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                        assign [$$260, $$261] <- [1, 1]
                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                          empty-tuple-source
                                                                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- HASH_PARTITION_EXCHANGE [$$204]  |PARTITIONED|
+                                                                                                        assign [$$205] <- [true]
                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                          project ([$$204])
                                                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                              -- SORT_GROUP_BY[$$243, $$244]  |PARTITIONED|
-                                                                                                                      {
+                                                                                                              group by ([$$208 := $$243; $$204 := $$244]) decor ([]) {
+                                                                                                                        aggregate [] <- []
                                                                                                                         -- AGGREGATE  |LOCAL|
+                                                                                                                          nested tuple source
                                                                                                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                      }
+                                                                                                                     }
+                                                                                                              -- SORT_GROUP_BY[$$243, $$244]  |PARTITIONED|
+                                                                                                                exchange
                                                                                                                 -- HASH_PARTITION_EXCHANGE [$$243, $$244]  |PARTITIONED|
-                                                                                                                  -- PRE_CLUSTERED_GROUP_BY[$$209, $$210]  |PARTITIONED|
-                                                                                                                          {
+                                                                                                                  group by ([$$243 := $$209; $$244 := $$210]) decor ([]) {
+                                                                                                                            aggregate [] <- []
                                                                                                                             -- AGGREGATE  |LOCAL|
+                                                                                                                              select (not(is-missing($$222)))
                                                                                                                               -- STREAM_SELECT  |LOCAL|
+                                                                                                                                nested tuple source
                                                                                                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                          }
+                                                                                                                         }
+                                                                                                                  -- PRE_CLUSTERED_GROUP_BY[$$209, $$210]  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                      order (ASC, $$209) (ASC, $$210)
                                                                                                                       -- STABLE_SORT [$$209(ASC), $$210(ASC)]  |PARTITIONED|
+                                                                                                                        exchange
                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                          project ([$$222, $$209, $$210])
                                                                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                              left outer join (eq($$214, $$211))
                                                                                                                               -- HYBRID_HASH_JOIN [$$211][$$214]  |PARTITIONED|
+                                                                                                                                exchange
                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                  replicate
                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                    exchange
                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$211]  |PARTITIONED|
+                                                                                                                                      running-aggregate [$$209] <- [create-query-uid()]
                                                                                                                                       -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                                                                                                        assign [$$211] <- [$$212.getField(0)] project: [$$210, $$211]
                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                          select (not(or(and($$265, not(is-unknown($$265)))))) project: [$$210, $$212]
                                                                                                                                           -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                            assign [$$265] <- [lt(get-item($$213, 0), 25437)] project: [$$210, $$212, $$265]
                                                                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                                                                              exchange
                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                -- PRE_CLUSTERED_GROUP_BY[$$215]  |PARTITIONED|
-                                                                                                                                                        {
+                                                                                                                                                group by ([$$210 := $$215]) decor ([$$212]) {
+                                                                                                                                                          aggregate [$$213] <- [listify($$221)]
                                                                                                                                                           -- AGGREGATE  |LOCAL|
+                                                                                                                                                            aggregate [$$221] <- [agg-sql-count(1)]
                                                                                                                                                             -- AGGREGATE  |LOCAL|
+                                                                                                                                                              select (not(is-missing($$217)))
                                                                                                                                                               -- STREAM_SELECT  |LOCAL|
+                                                                                                                                                                nested tuple source
                                                                                                                                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                                                        }
+                                                                                                                                                       }
+                                                                                                                                                -- PRE_CLUSTERED_GROUP_BY[$$215]  |PARTITIONED|
+                                                                                                                                                  exchange
                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                    order (ASC, $$215)
                                                                                                                                                     -- STABLE_SORT [$$215(ASC)]  |PARTITIONED|
+                                                                                                                                                      exchange
                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                        project ([$$212, $$217, $$215])
                                                                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                          exchange
                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                            left outer join (eq($$216, $$215))
                                                                                                                                                             -- HYBRID_HASH_JOIN [$$215][$$216]  |PARTITIONED|
+                                                                                                                                                              exchange
                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                replicate
                                                                                                                                                                 -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                  exchange
                                                                                                                                                                   -- HASH_PARTITION_EXCHANGE [$$215]  |PARTITIONED|
+                                                                                                                                                                    replicate
                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                      exchange
                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                        -- BTREE_SEARCH (tpcds.item.item)  |PARTITIONED|
+                                                                                                                                                                        unnest-map [$$215, $$212] <- index-search("item", 0, "Default", "tpcds", "item", false, false, 1, $$260, 1, $$261, true, true, true)
+                                                                                                                                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                                                                                                                                          exchange
                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                            assign [$$260, $$261] <- [1, 1]
                                                                                                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                              empty-tuple-source
                                                                                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                              exchange
                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                assign [$$217, $$216] <- [$$222, $$214] project: [$$217, $$216]
                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                  exchange
                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                    replicate
                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                      exchange
                                                                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$214]  |PARTITIONED|
+                                                                                                                                                                        assign [$$222, $$214] <- [true, $$223.getField(10)] project: [$$222, $$214]
                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                          assign [$$223] <- [$$store_sales] project: [$$223]
                                                                                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                            exchange
                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                              replicate
                                                                                                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                exchange
                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                  project ([$$store_sales])
                                                                                                                                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                    exchange
                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                      -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                                                                                                                      data-scan []<-[$$149, $$150, $$store_sales] <- tpcds.store_sales
+                                                                                                                                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                        exchange
                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                          empty-tuple-source
                                                                                                                                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                exchange
                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                  replicate
                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                    exchange
                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$214]  |PARTITIONED|
+                                                                                                                                      assign [$$222, $$214] <- [true, $$223.getField(10)] project: [$$222, $$214]
                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                        assign [$$223] <- [$$store_sales] project: [$$223]
                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                          exchange
                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                            replicate
                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                              exchange
                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                project ([$$store_sales])
                                                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                  exchange
                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                    -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                                                                                    data-scan []<-[$$149, $$150, $$store_sales] <- tpcds.store_sales
+                                                                                                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                      exchange
                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                        empty-tuple-source
                                                                                                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        assign [$$197, $$178] <- [$$222, $$214] project: [$$197, $$178]
                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            replicate
                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- HASH_PARTITION_EXCHANGE [$$214]  |PARTITIONED|
+                                                                                                assign [$$222, $$214] <- [true, $$223.getField(10)] project: [$$222, $$214]
                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                  assign [$$223] <- [$$store_sales] project: [$$223]
                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                      replicate
                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                          project ([$$store_sales])
                                                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                              -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                                              data-scan []<-[$$149, $$150, $$store_sales] <- tpcds.store_sales
+                                                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                exchange
                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                  empty-tuple-source
                                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                  exchange
                                                                   -- HASH_PARTITION_EXCHANGE [$$180]  |PARTITIONED|
+                                                                    assign [$$199, $$120, $$180] <- [true, $$store_sales.getField(14), $$store_sales.getField(10)] project: [$$120, $$199, $$180]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      assign [$$store_sales] <- [$$store_sales] project: [$$store_sales]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          replicate
                                                                           -- REPLICATE  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              project ([$$store_sales])
                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                  data-scan []<-[$$149, $$150, $$store_sales] <- tpcds.store_sales
+                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      empty-tuple-source
                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$235, $$182] <- [$$222, $$214] project: [$$235, $$182]
                               -- ASSIGN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  replicate
                                   -- REPLICATE  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$214]  |PARTITIONED|
+                                      assign [$$222, $$214] <- [true, $$223.getField(10)] project: [$$222, $$214]
                                       -- ASSIGN  |PARTITIONED|
+                                        assign [$$223] <- [$$store_sales] project: [$$223]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            replicate
                                             -- REPLICATE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$store_sales])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                    data-scan []<-[$$149, $$150, $$store_sales] <- tpcds.store_sales
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581-correlated.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581-correlated.plan
index 1a8fb37..f06b823 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581-correlated.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581-correlated.plan
@@ -1,319 +1,599 @@
+distribute result [$$143]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$143] <- [{"bucket1": $$141}] project: [$$143]
     -- ASSIGN  |PARTITIONED|
+      unnest $$141 <- scan-collection($$140) project: [$$141]
       -- UNNEST  |PARTITIONED|
+        assign [$$140] <- [switch-case(true, lt(get-item($$107, 0), 25437), cast($$124), cast($$139))] project: [$$140]
         -- ASSIGN  |PARTITIONED|
+          project ([$$139, $$107, $$124])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- PRE_CLUSTERED_GROUP_BY[$$180]  |PARTITIONED|
-                      {
+              group by ([$$224 := $$180]) decor ([$$107; $$124]) {
+                        aggregate [$$139] <- [listify($$138)]
                         -- AGGREGATE  |LOCAL|
+                          aggregate [$$138] <- [listify($$137)]
                           -- AGGREGATE  |LOCAL|
+                            select (not(is-missing($$223)))
                             -- STREAM_SELECT  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                      }
+                     }
+              -- PRE_CLUSTERED_GROUP_BY[$$180]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$180)
                   -- STABLE_SORT [$$180(ASC)]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$107, $$124, $$137, $$223, $$180])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          left outer join (eq($$180, $$222))
                           -- HYBRID_HASH_JOIN [$$180][$$222]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$164]  |PARTITIONED|
-                                      {
+                              group by ([$$180 := $$164]) decor ([$$107]) {
+                                        aggregate [$$124] <- [listify($$123)]
                                         -- AGGREGATE  |LOCAL|
+                                          aggregate [$$123] <- [listify($$122)]
                                           -- AGGREGATE  |LOCAL|
+                                            select (not(is-missing($$179)))
                                             -- STREAM_SELECT  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$164]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$107, $$122, $$179, $$164])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      left outer join (eq($$164, $$178))
                                       -- HYBRID_HASH_JOIN [$$164][$$178]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- PRE_CLUSTERED_GROUP_BY[$$144]  |PARTITIONED|
-                                                  {
+                                          group by ([$$164 := $$144]) decor ([]) {
+                                                    aggregate [$$107] <- [listify($$151)]
                                                     -- AGGREGATE  |LOCAL|
+                                                      aggregate [$$151] <- [agg-sql-count(1)]
                                                       -- AGGREGATE  |LOCAL|
+                                                        select (not(is-missing($$163)))
                                                         -- STREAM_SELECT  |LOCAL|
+                                                          nested tuple source
                                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                  }
+                                                 }
+                                          -- PRE_CLUSTERED_GROUP_BY[$$144]  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              order (ASC, $$144)
                                               -- STABLE_SORT [$$144(ASC)]  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  project ([$$163, $$144])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      left outer join (eq($$154, $$144))
                                                       -- HYBRID_HASH_JOIN [$$144][$$154]  |PARTITIONED|
+                                                        exchange
                                                         -- HASH_PARTITION_EXCHANGE [$$144]  |PARTITIONED|
+                                                          project ([$$144])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              assign [$$144, $$item] <- [$$206, $$202] project: [$$144, $$item]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  replicate
                                                                   -- REPLICATE  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- BTREE_SEARCH (tpcds.item.item)  |PARTITIONED|
+                                                                      unnest-map [$$206, $$202] <- index-search("item", 0, "Default", "tpcds", "item", false, false, 1, $$247, 1, $$248, true, true, true)
+                                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          assign [$$247, $$248] <- [1, 1]
                                                                           -- ASSIGN  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          assign [$$163, $$154] <- [$$213, $$205] project: [$$163, $$154]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              replicate
                                                               -- REPLICATE  |PARTITIONED|
+                                                                exchange
                                                                 -- HASH_PARTITION_EXCHANGE [$$205]  |PARTITIONED|
+                                                                  assign [$$213, $$205] <- [true, $$214.getField(10)] project: [$$213, $$205]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    assign [$$214] <- [$$store_sales] project: [$$214]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        replicate
                                                                         -- REPLICATE  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            project ([$$store_sales])
                                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                data-scan []<-[$$147, $$148, $$store_sales] <- tpcds.store_sales
+                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    empty-tuple-source
                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$178]  |PARTITIONED|
+                                          assign [$$179, $$122] <- [true, {"$1": $$152}] project: [$$122, $$179, $$178]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$152, $$178])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- SORT_GROUP_BY[$$227, $$228]  |PARTITIONED|
-                                                        {
+                                                group by ([$$167 := $$227; $$178 := $$228]) decor ([]) {
+                                                          aggregate [$$152] <- [agg-global-sql-avg($$226)]
                                                           -- AGGREGATE  |LOCAL|
+                                                            nested tuple source
                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                        }
+                                                       }
+                                                -- SORT_GROUP_BY[$$227, $$228]  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$227, $$228]  |PARTITIONED|
-                                                    -- PRE_CLUSTERED_GROUP_BY[$$165, $$168]  |PARTITIONED|
-                                                            {
+                                                    group by ([$$227 := $$165; $$228 := $$168]) decor ([]) {
+                                                              aggregate [$$226] <- [agg-local-sql-avg($$120)]
                                                               -- AGGREGATE  |LOCAL|
+                                                                select (not(is-missing($$166)))
                                                                 -- STREAM_SELECT  |LOCAL|
+                                                                  nested tuple source
                                                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                            }
+                                                           }
+                                                    -- PRE_CLUSTERED_GROUP_BY[$$165, $$168]  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        order (ASC, $$165) (ASC, $$168)
                                                         -- STABLE_SORT [$$165(ASC), $$168(ASC)]  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            project ([$$120, $$166, $$165, $$168])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                left outer join (eq($$156, $$157))
                                                                 -- HYBRID_HASH_JOIN [$$157][$$156]  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    assign [$$168, $$157, $$165] <- [$$201, $$204, $$200] project: [$$168, $$157, $$165]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        replicate
                                                                         -- REPLICATE  |PARTITIONED|
+                                                                          exchange
                                                                           -- HASH_PARTITION_EXCHANGE [$$204]  |PARTITIONED|
+                                                                            running-aggregate [$$200] <- [create-query-uid()]
                                                                             -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                                              assign [$$204] <- [$$202.getField(0)] project: [$$201, $$204]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                select (lt(get-item($$203, 0), 25437)) project: [$$201, $$202]
                                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    replicate
                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$206]  |PARTITIONED|
-                                                                                                {
+                                                                                        group by ([$$201 := $$206]) decor ([$$202]) {
+                                                                                                  aggregate [$$203] <- [listify($$212)]
                                                                                                   -- AGGREGATE  |LOCAL|
+                                                                                                    aggregate [$$212] <- [agg-sql-count(1)]
                                                                                                     -- AGGREGATE  |LOCAL|
+                                                                                                      select (not(is-missing($$208)))
                                                                                                       -- STREAM_SELECT  |LOCAL|
+                                                                                                        nested tuple source
                                                                                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                }
+                                                                                               }
+                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$206]  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            order (ASC, $$206)
                                                                                             -- STABLE_SORT [$$206(ASC)]  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                project ([$$202, $$208, $$206])
                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    left outer join (eq($$207, $$206))
                                                                                                     -- HYBRID_HASH_JOIN [$$206][$$207]  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- HASH_PARTITION_EXCHANGE [$$206]  |PARTITIONED|
+                                                                                                        replicate
                                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                                          exchange
                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                            -- BTREE_SEARCH (tpcds.item.item)  |PARTITIONED|
+                                                                                                            unnest-map [$$206, $$202] <- index-search("item", 0, "Default", "tpcds", "item", false, false, 1, $$247, 1, $$248, true, true, true)
+                                                                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                                                                              exchange
                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                assign [$$247, $$248] <- [1, 1]
                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                  empty-tuple-source
                                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                        assign [$$208, $$207] <- [$$213, $$205] project: [$$208, $$207]
                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                          exchange
                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                            replicate
                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                              exchange
                                                                                                               -- HASH_PARTITION_EXCHANGE [$$205]  |PARTITIONED|
+                                                                                                                assign [$$213, $$205] <- [true, $$214.getField(10)] project: [$$213, $$205]
                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                  assign [$$214] <- [$$store_sales] project: [$$214]
                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                      replicate
                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                        exchange
                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                          project ([$$store_sales])
                                                                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                              -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                                                              data-scan []<-[$$147, $$148, $$store_sales] <- tpcds.store_sales
+                                                                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                exchange
                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                  empty-tuple-source
                                                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                  exchange
                                                                   -- HASH_PARTITION_EXCHANGE [$$156]  |PARTITIONED|
+                                                                    assign [$$166, $$120, $$156] <- [true, $$store_sales.getField(14), $$store_sales.getField(10)] project: [$$120, $$166, $$156]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        replicate
                                                                         -- REPLICATE  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            project ([$$store_sales])
                                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                data-scan []<-[$$147, $$148, $$store_sales] <- tpcds.store_sales
+                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    empty-tuple-source
                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$222]  |PARTITIONED|
+                              assign [$$223, $$137] <- [true, {"$2": $$153}] project: [$$137, $$223, $$222]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$153, $$222])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- SORT_GROUP_BY[$$233, $$234]  |PARTITIONED|
-                                            {
+                                    group by ([$$183 := $$233; $$222 := $$234]) decor ([]) {
+                                              aggregate [$$153] <- [agg-global-sql-avg($$232)]
                                               -- AGGREGATE  |LOCAL|
+                                                nested tuple source
                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                           }
+                                    -- SORT_GROUP_BY[$$233, $$234]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$233, $$234]  |PARTITIONED|
-                                        -- PRE_CLUSTERED_GROUP_BY[$$181, $$184]  |PARTITIONED|
-                                                {
+                                        group by ([$$233 := $$181; $$234 := $$184]) decor ([]) {
+                                                  aggregate [$$232] <- [agg-local-sql-avg($$135)]
                                                   -- AGGREGATE  |LOCAL|
+                                                    select (not(is-missing($$182)))
                                                     -- STREAM_SELECT  |LOCAL|
+                                                      nested tuple source
                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                               }
+                                        -- PRE_CLUSTERED_GROUP_BY[$$181, $$184]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            order (ASC, $$181) (ASC, $$184)
                                             -- STABLE_SORT [$$181(ASC), $$184(ASC)]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                project ([$$135, $$182, $$181, $$184])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    left outer join (eq($$158, $$159))
                                                     -- HYBRID_HASH_JOIN [$$159][$$158]  |PARTITIONED|
+                                                      exchange
                                                       -- HASH_PARTITION_EXCHANGE [$$159]  |PARTITIONED|
+                                                        running-aggregate [$$181] <- [create-query-uid()]
                                                         -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                          assign [$$159] <- [$$186.getField(0)] project: [$$184, $$159]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            select (not(or(and($$251, not(is-unknown($$251)))))) project: [$$184, $$186]
                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                              assign [$$251] <- [lt(get-item($$187, 0), 25437)] project: [$$184, $$186, $$251]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- PRE_CLUSTERED_GROUP_BY[$$185]  |PARTITIONED|
-                                                                          {
+                                                                  group by ([$$184 := $$185]) decor ([$$186; $$187]) {
+                                                                            aggregate [] <- []
                                                                             -- AGGREGATE  |LOCAL|
+                                                                              aggregate [] <- []
                                                                               -- AGGREGATE  |LOCAL|
+                                                                                select (not(is-missing($$196)))
                                                                                 -- STREAM_SELECT  |LOCAL|
+                                                                                  nested tuple source
                                                                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                          }
+                                                                         }
+                                                                  -- PRE_CLUSTERED_GROUP_BY[$$185]  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      project ([$$186, $$187, $$196, $$185])
                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          left outer join (eq($$185, $$188))
                                                                           -- HYBRID_HASH_JOIN [$$185][$$188]  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              assign [$$187, $$185, $$186] <- [$$203, $$201, $$202] project: [$$187, $$185, $$186]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  replicate
                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$206]  |PARTITIONED|
-                                                                                              {
+                                                                                      group by ([$$201 := $$206]) decor ([$$202]) {
+                                                                                                aggregate [$$203] <- [listify($$212)]
                                                                                                 -- AGGREGATE  |LOCAL|
+                                                                                                  aggregate [$$212] <- [agg-sql-count(1)]
                                                                                                   -- AGGREGATE  |LOCAL|
+                                                                                                    select (not(is-missing($$208)))
                                                                                                     -- STREAM_SELECT  |LOCAL|
+                                                                                                      nested tuple source
                                                                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                              }
+                                                                                             }
+                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$206]  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                          order (ASC, $$206)
                                                                                           -- STABLE_SORT [$$206(ASC)]  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              project ([$$202, $$208, $$206])
                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                  left outer join (eq($$207, $$206))
                                                                                                   -- HYBRID_HASH_JOIN [$$206][$$207]  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- HASH_PARTITION_EXCHANGE [$$206]  |PARTITIONED|
+                                                                                                      replicate
                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                          -- BTREE_SEARCH (tpcds.item.item)  |PARTITIONED|
+                                                                                                          unnest-map [$$206, $$202] <- index-search("item", 0, "Default", "tpcds", "item", false, false, 1, $$247, 1, $$248, true, true, true)
+                                                                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                              assign [$$247, $$248] <- [1, 1]
                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                empty-tuple-source
                                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                      assign [$$208, $$207] <- [$$213, $$205] project: [$$208, $$207]
                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                          replicate
                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- HASH_PARTITION_EXCHANGE [$$205]  |PARTITIONED|
+                                                                                                              assign [$$213, $$205] <- [true, $$214.getField(10)] project: [$$213, $$205]
                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                assign [$$214] <- [$$store_sales] project: [$$214]
                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                  exchange
                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                    replicate
                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                      exchange
                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                        project ([$$store_sales])
                                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                          exchange
                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                            -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                                                            data-scan []<-[$$147, $$148, $$store_sales] <- tpcds.store_sales
+                                                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                              exchange
                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                empty-tuple-source
                                                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                            exchange
                                                                             -- HASH_PARTITION_EXCHANGE [$$188]  |PARTITIONED|
+                                                                              assign [$$196] <- [true]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                project ([$$188])
                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                    -- SORT_GROUP_BY[$$230, $$231]  |PARTITIONED|
-                                                                                            {
+                                                                                    group by ([$$199 := $$230; $$188 := $$231]) decor ([]) {
+                                                                                              aggregate [] <- []
                                                                                               -- AGGREGATE  |LOCAL|
+                                                                                                nested tuple source
                                                                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                            }
+                                                                                           }
+                                                                                    -- SORT_GROUP_BY[$$230, $$231]  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- HASH_PARTITION_EXCHANGE [$$230, $$231]  |PARTITIONED|
-                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$200, $$201]  |PARTITIONED|
-                                                                                                {
+                                                                                        group by ([$$230 := $$200; $$231 := $$201]) decor ([]) {
+                                                                                                  aggregate [] <- []
                                                                                                   -- AGGREGATE  |LOCAL|
+                                                                                                    select (not(is-missing($$213)))
                                                                                                     -- STREAM_SELECT  |LOCAL|
+                                                                                                      nested tuple source
                                                                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                }
+                                                                                               }
+                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$200, $$201]  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            order (ASC, $$200) (ASC, $$201)
                                                                                             -- STABLE_SORT [$$200(ASC), $$201(ASC)]  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                project ([$$213, $$200, $$201])
                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    left outer join (eq($$205, $$204))
                                                                                                     -- HYBRID_HASH_JOIN [$$204][$$205]  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                        replicate
                                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                                          exchange
                                                                                                           -- HASH_PARTITION_EXCHANGE [$$204]  |PARTITIONED|
+                                                                                                            running-aggregate [$$200] <- [create-query-uid()]
                                                                                                             -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                                                                              assign [$$204] <- [$$202.getField(0)] project: [$$201, $$204]
                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                select (lt(get-item($$203, 0), 25437)) project: [$$201, $$202]
                                                                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                  exchange
                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                    replicate
                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                      exchange
                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$206]  |PARTITIONED|
-                                                                                                                                {
+                                                                                                                        group by ([$$201 := $$206]) decor ([$$202]) {
+                                                                                                                                  aggregate [$$203] <- [listify($$212)]
                                                                                                                                   -- AGGREGATE  |LOCAL|
+                                                                                                                                    aggregate [$$212] <- [agg-sql-count(1)]
                                                                                                                                     -- AGGREGATE  |LOCAL|
+                                                                                                                                      select (not(is-missing($$208)))
                                                                                                                                       -- STREAM_SELECT  |LOCAL|
+                                                                                                                                        nested tuple source
                                                                                                                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                                }
+                                                                                                                               }
+                                                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$206]  |PARTITIONED|
+                                                                                                                          exchange
                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                            order (ASC, $$206)
                                                                                                                             -- STABLE_SORT [$$206(ASC)]  |PARTITIONED|
+                                                                                                                              exchange
                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                project ([$$202, $$208, $$206])
                                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                  exchange
                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                    left outer join (eq($$207, $$206))
                                                                                                                                     -- HYBRID_HASH_JOIN [$$206][$$207]  |PARTITIONED|
+                                                                                                                                      exchange
                                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$206]  |PARTITIONED|
+                                                                                                                                        replicate
                                                                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                                                                          exchange
                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                            -- BTREE_SEARCH (tpcds.item.item)  |PARTITIONED|
+                                                                                                                                            unnest-map [$$206, $$202] <- index-search("item", 0, "Default", "tpcds", "item", false, false, 1, $$247, 1, $$248, true, true, true)
+                                                                                                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                                                                                                              exchange
                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                assign [$$247, $$248] <- [1, 1]
                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                  empty-tuple-source
                                                                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                      exchange
                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                        assign [$$208, $$207] <- [$$213, $$205] project: [$$208, $$207]
                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                          exchange
                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                            replicate
                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                              exchange
                                                                                                                                               -- HASH_PARTITION_EXCHANGE [$$205]  |PARTITIONED|
+                                                                                                                                                assign [$$213, $$205] <- [true, $$214.getField(10)] project: [$$213, $$205]
                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                  assign [$$214] <- [$$store_sales] project: [$$214]
                                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                                    exchange
                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                      replicate
                                                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                                                        exchange
                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                          project ([$$store_sales])
                                                                                                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                            exchange
                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                              -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                                                                                              data-scan []<-[$$147, $$148, $$store_sales] <- tpcds.store_sales
+                                                                                                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                exchange
                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                  empty-tuple-source
                                                                                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                        replicate
                                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                                          exchange
                                                                                                           -- HASH_PARTITION_EXCHANGE [$$205]  |PARTITIONED|
+                                                                                                            assign [$$213, $$205] <- [true, $$214.getField(10)] project: [$$213, $$205]
                                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                                              assign [$$214] <- [$$store_sales] project: [$$214]
                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                exchange
                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                  replicate
                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                      project ([$$store_sales])
                                                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                        exchange
                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                          -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                                                          data-scan []<-[$$147, $$148, $$store_sales] <- tpcds.store_sales
+                                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                              empty-tuple-source
                                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                      exchange
                                                       -- HASH_PARTITION_EXCHANGE [$$158]  |PARTITIONED|
+                                                        assign [$$182, $$135, $$158] <- [true, $$store_sales.getField(22), $$store_sales.getField(10)] project: [$$135, $$182, $$158]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          assign [$$store_sales] <- [$$store_sales] project: [$$store_sales]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              replicate
                                                               -- REPLICATE  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  project ([$$store_sales])
                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                      data-scan []<-[$$147, $$148, $$store_sales] <- tpcds.store_sales
+                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581.plan
index 6b377c1..45c34fe 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1581.plan
@@ -1,184 +1,359 @@
+distribute result [$$149]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    join (true)
     -- NESTED_LOOP  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        project ([])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (tpcds.item.item)  |PARTITIONED|
+            unnest-map [$$153, $$item] <- index-search("item", 0, "Default", "tpcds", "item", false, false, 1, $$208, 1, $$209, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$208, $$209] <- [1, 1]
                 -- ASSIGN  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+      exchange
       -- BROADCAST_EXCHANGE  |LOCAL|
+        assign [$$149] <- [{"bucket1": $$147}] project: [$$149]
         -- ASSIGN  |LOCAL|
+          unnest $$147 <- scan-collection($$146) project: [$$147]
           -- UNNEST  |LOCAL|
+            assign [$$146] <- [switch-case(true, lt(get-item($$200, 0), 25437), cast($$128), cast($$145))] project: [$$146]
             -- ASSIGN  |LOCAL|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |LOCAL|
-                -- PRE_CLUSTERED_GROUP_BY[$$173]  |LOCAL|
-                        {
+                group by ([$$200 := $$173]) decor ([$$128]) {
+                          aggregate [$$145] <- [listify($$144)]
                           -- AGGREGATE  |LOCAL|
+                            aggregate [$$144] <- [listify($$143)]
                             -- AGGREGATE  |LOCAL|
+                              select (not(is-missing($$199)))
                               -- STREAM_SELECT  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       }
+                -- PRE_CLUSTERED_GROUP_BY[$$173]  |LOCAL|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                    project ([$$128, $$143, $$199, $$173])
                     -- STREAM_PROJECT  |LOCAL|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                        left outer join (eq($$173, $$174))
                         -- HYBRID_HASH_JOIN [$$173][$$174]  |LOCAL|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |LOCAL|
-                            -- PRE_CLUSTERED_GROUP_BY[$$109]  |LOCAL|
-                                    {
+                            group by ([$$173 := $$109]) decor ([]) {
+                                      aggregate [$$128] <- [listify($$127)]
                                       -- AGGREGATE  |LOCAL|
+                                        aggregate [$$127] <- [listify($$126)]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$172)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- PRE_CLUSTERED_GROUP_BY[$$109]  |LOCAL|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                                order (ASC, $$109)
                                 -- STABLE_SORT [$$109(ASC)]  |LOCAL|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                    project ([$$126, $$172, $$109])
                                     -- STREAM_PROJECT  |UNPARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        left outer join (eq($$109, $$166))
                                         -- HYBRID_HASH_JOIN [$$109][$$166]  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            assign [$$109] <- [$$175] project: [$$109]
                                             -- ASSIGN  |UNPARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |UNPARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                    assign [$$175] <- [$$176] project: [$$175]
                                                     -- ASSIGN  |UNPARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                        replicate
                                                         -- REPLICATE  |UNPARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                            aggregate [$$176] <- [listify($$183)]
                                                             -- AGGREGATE  |UNPARTITIONED|
+                                                              aggregate [$$183] <- [agg-sql-sum($$206)]
                                                               -- AGGREGATE  |UNPARTITIONED|
+                                                                exchange
                                                                 -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                                  aggregate [$$206] <- [agg-sql-count(1)]
                                                                   -- AGGREGATE  |PARTITIONED|
+                                                                    select (and(ge($$185, 1), le($$185, 20)))
                                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                                      assign [$$185] <- [$$184.getField(10)] project: [$$185]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          replicate
                                                                           -- REPLICATE  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              project ([$$184])
                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                  data-scan []<-[$$186, $$187, $$184] <- tpcds.store_sales
+                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      empty-tuple-source
                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            join (true)
                                             -- NESTED_LOOP  |UNPARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                assign [$$166, $$172] <- [$$176, $$182] project: [$$166, $$172]
                                                 -- ASSIGN  |UNPARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                    replicate
                                                     -- REPLICATE  |UNPARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                        assign [$$182] <- [true]
                                                         -- ASSIGN  |UNPARTITIONED|
+                                                          select (lt(get-item($$176, 0), 25437))
                                                           -- STREAM_SELECT  |UNPARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                              replicate
                                                               -- REPLICATE  |UNPARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                                  aggregate [$$176] <- [listify($$183)]
                                                                   -- AGGREGATE  |UNPARTITIONED|
+                                                                    aggregate [$$183] <- [agg-sql-sum($$206)]
                                                                     -- AGGREGATE  |UNPARTITIONED|
+                                                                      exchange
                                                                       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                                        aggregate [$$206] <- [agg-sql-count(1)]
                                                                         -- AGGREGATE  |PARTITIONED|
+                                                                          select (and(ge($$185, 1), le($$185, 20)))
                                                                           -- STREAM_SELECT  |PARTITIONED|
+                                                                            assign [$$185] <- [$$184.getField(10)] project: [$$185]
                                                                             -- ASSIGN  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                replicate
                                                                                 -- REPLICATE  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    project ([$$184])
                                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                        -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                        data-scan []<-[$$186, $$187, $$184] <- tpcds.store_sales
+                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            empty-tuple-source
                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                assign [$$126] <- [{"$1": $$161}] project: [$$126]
                                                 -- ASSIGN  |UNPARTITIONED|
+                                                  aggregate [$$161] <- [agg-global-sql-avg($$204)]
                                                   -- AGGREGATE  |UNPARTITIONED|
+                                                    exchange
                                                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                      aggregate [$$204] <- [agg-local-sql-avg($$124)]
                                                       -- AGGREGATE  |PARTITIONED|
+                                                        select (and(ge($$151, 1), le($$151, 20))) project: [$$124]
                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                          assign [$$124, $$151] <- [$$store_sales.getField(14), $$store_sales.getField(10)] project: [$$124, $$151]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            assign [$$store_sales] <- [$$184] project: [$$store_sales]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                replicate
                                                                 -- REPLICATE  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    project ([$$184])
                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                        data-scan []<-[$$186, $$187, $$184] <- tpcds.store_sales
+                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                            join (true)
                             -- NESTED_LOOP  |LOCAL|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                                assign [$$199] <- [true]
                                 -- ASSIGN  |LOCAL|
+                                  select (not(or(and($$212, not(is-unknown($$212)))))) project: [$$174]
                                   -- STREAM_SELECT  |LOCAL|
+                                    assign [$$212] <- [lt(get-item($$174, 0), 25437)]
                                     -- ASSIGN  |LOCAL|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |LOCAL|
-                                        -- PRE_CLUSTERED_GROUP_BY[$$175]  |LOCAL|
-                                                {
+                                        group by ([$$174 := $$175]) decor ([]) {
+                                                  aggregate [] <- []
                                                   -- AGGREGATE  |LOCAL|
+                                                    aggregate [] <- []
                                                     -- AGGREGATE  |LOCAL|
+                                                      select (not(is-missing($$182)))
                                                       -- STREAM_SELECT  |LOCAL|
+                                                        nested tuple source
                                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                               }
+                                        -- PRE_CLUSTERED_GROUP_BY[$$175]  |LOCAL|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                                            order (ASC, $$175)
                                             -- STABLE_SORT [$$175(ASC)]  |LOCAL|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                project ([$$182, $$175])
                                                 -- STREAM_PROJECT  |UNPARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                    left outer join (eq($$175, $$176))
                                                     -- HYBRID_HASH_JOIN [$$175][$$176]  |UNPARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                        replicate
                                                         -- REPLICATE  |UNPARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                            assign [$$175] <- [$$176] project: [$$175]
                                                             -- ASSIGN  |UNPARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                                replicate
                                                                 -- REPLICATE  |UNPARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                                    aggregate [$$176] <- [listify($$183)]
                                                                     -- AGGREGATE  |UNPARTITIONED|
+                                                                      aggregate [$$183] <- [agg-sql-sum($$206)]
                                                                       -- AGGREGATE  |UNPARTITIONED|
+                                                                        exchange
                                                                         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                                          aggregate [$$206] <- [agg-sql-count(1)]
                                                                           -- AGGREGATE  |PARTITIONED|
+                                                                            select (and(ge($$185, 1), le($$185, 20)))
                                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                                              assign [$$185] <- [$$184.getField(10)] project: [$$185]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  replicate
                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      project ([$$184])
                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                          -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                          data-scan []<-[$$186, $$187, $$184] <- tpcds.store_sales
+                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              empty-tuple-source
                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                        replicate
                                                         -- REPLICATE  |UNPARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                            assign [$$182] <- [true]
                                                             -- ASSIGN  |UNPARTITIONED|
+                                                              select (lt(get-item($$176, 0), 25437))
                                                               -- STREAM_SELECT  |UNPARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                                  replicate
                                                                   -- REPLICATE  |UNPARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                                      aggregate [$$176] <- [listify($$183)]
                                                                       -- AGGREGATE  |UNPARTITIONED|
+                                                                        aggregate [$$183] <- [agg-sql-sum($$206)]
                                                                         -- AGGREGATE  |UNPARTITIONED|
+                                                                          exchange
                                                                           -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                                            aggregate [$$206] <- [agg-sql-count(1)]
                                                                             -- AGGREGATE  |PARTITIONED|
+                                                                              select (and(ge($$185, 1), le($$185, 20)))
                                                                               -- STREAM_SELECT  |PARTITIONED|
+                                                                                assign [$$185] <- [$$184.getField(10)] project: [$$185]
                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    replicate
                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        project ([$$184])
                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                            -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                            data-scan []<-[$$186, $$187, $$184] <- tpcds.store_sales
+                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                empty-tuple-source
                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                assign [$$143] <- [{"$2": $$162}] project: [$$143]
                                 -- ASSIGN  |UNPARTITIONED|
+                                  aggregate [$$162] <- [agg-global-sql-avg($$207)]
                                   -- AGGREGATE  |UNPARTITIONED|
+                                    exchange
                                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                      aggregate [$$207] <- [agg-local-sql-avg($$141)]
                                       -- AGGREGATE  |PARTITIONED|
+                                        select (and(ge($$152, 1), le($$152, 20))) project: [$$141]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$141, $$152] <- [$$store_sales.getField(22), $$store_sales.getField(10)] project: [$$141, $$152]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$store_sales] <- [$$184] project: [$$store_sales]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    project ([$$184])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                        data-scan []<-[$$186, $$187, $$184] <- tpcds.store_sales
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1591.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1591.plan
index 0d83d24..f0a76d2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1591.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1591.plan
@@ -1,146 +1,274 @@
+distribute result [$$148]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 100
     -- STREAM_LIMIT  |UNPARTITIONED|
+      assign [$$148] <- [{"c": $$c, "ca": $$ca}] project: [$$148]
       -- ASSIGN  |PARTITIONED|
+        project ([$$c, $$ca])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- SORT_MERGE_EXCHANGE [$$192(ASC) ]  |PARTITIONED|
+            limit 100
             -- STREAM_LIMIT  |PARTITIONED|
+              select (or(neq($$163, 0), neq($$164, 0))) project: [$$192, $$c, $$ca]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$164, $$192, $$c, $$ca, $$163])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$201, $$202]  |PARTITIONED|
-                            {
+                    group by ([$$192 := $$201; $$193 := $$202]) decor ([$$c; $$ca; $$163]) {
+                              aggregate [$$164] <- [agg-sum($$200)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$201, $$202]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$201, $$202]  |PARTITIONED|
-                        -- PRE_CLUSTERED_GROUP_BY[$$189, $$190]  |PARTITIONED|
-                                {
+                        group by ([$$201 := $$189; $$202 := $$190]) decor ([$$c; $$ca; $$163]) {
+                                  aggregate [$$200] <- [agg-count({"cs1": $$cs1, "dd1": $$dd1})]
                                   -- AGGREGATE  |LOCAL|
+                                    select (not(is-missing($$191)))
                                     -- STREAM_SELECT  |LOCAL|
+                                      nested tuple source
                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- PRE_CLUSTERED_GROUP_BY[$$189, $$190]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$189) (ASC, $$190)
                             -- STABLE_SORT [$$189(ASC), $$190(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$c, $$ca, $$163, $$cs1, $$dd1, $$191, $$189, $$190])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    left outer join (eq($$189, $$171))
                                     -- HYBRID_HASH_JOIN [$$189][$$171]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$189]  |PARTITIONED|
-                                        -- SORT_GROUP_BY[$$198, $$199]  |PARTITIONED|
-                                                {
+                                        group by ([$$189 := $$198; $$190 := $$199]) decor ([$$c; $$ca]) {
+                                                  aggregate [$$163] <- [agg-sum($$197)]
                                                   -- AGGREGATE  |LOCAL|
+                                                    nested tuple source
                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                               }
+                                        -- SORT_GROUP_BY[$$198, $$199]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$198, $$199]  |PARTITIONED|
-                                            -- PRE_CLUSTERED_GROUP_BY[$$186, $$187]  |PARTITIONED|
-                                                    {
+                                            group by ([$$198 := $$186; $$199 := $$187]) decor ([$$c; $$ca]) {
+                                                      aggregate [$$197] <- [agg-count({"ws1": $$ws1, "dd1": $$dd1})]
                                                       -- AGGREGATE  |LOCAL|
+                                                        select (not(is-missing($$188)))
                                                         -- STREAM_SELECT  |LOCAL|
+                                                          nested tuple source
                                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                    }
+                                                   }
+                                            -- PRE_CLUSTERED_GROUP_BY[$$186, $$187]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                order (ASC, $$186) (ASC, $$187)
                                                 -- STABLE_SORT [$$186(ASC), $$187(ASC)]  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    project ([$$c, $$ca, $$ws1, $$dd1, $$188, $$186, $$187])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        left outer join (eq($$186, $$169))
                                                         -- HYBRID_HASH_JOIN [$$186][$$169]  |PARTITIONED|
+                                                          exchange
                                                           -- HASH_PARTITION_EXCHANGE [$$186]  |PARTITIONED|
+                                                            select (neq($$165, 0)) project: [$$c, $$ca, $$186, $$187]
                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- SORT_GROUP_BY[$$195, $$196]  |PARTITIONED|
-                                                                        {
+                                                                group by ([$$186 := $$195; $$187 := $$196]) decor ([$$c; $$ca]) {
+                                                                          aggregate [$$165] <- [agg-sum($$194)]
                                                                           -- AGGREGATE  |LOCAL|
+                                                                            nested tuple source
                                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                        }
+                                                                       }
+                                                                -- SORT_GROUP_BY[$$195, $$196]  |PARTITIONED|
+                                                                  exchange
                                                                   -- HASH_PARTITION_EXCHANGE [$$195, $$196]  |PARTITIONED|
-                                                                    -- PRE_CLUSTERED_GROUP_BY[$$150, $$151]  |PARTITIONED|
-                                                                            {
+                                                                    group by ([$$195 := $$150; $$196 := $$151]) decor ([$$c; $$ca]) {
+                                                                              aggregate [$$194] <- [agg-count({"ss1": $$ss1, "dd1": $$dd1})]
                                                                               -- AGGREGATE  |LOCAL|
+                                                                                select (not(is-missing($$185)))
                                                                                 -- STREAM_SELECT  |LOCAL|
+                                                                                  nested tuple source
                                                                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                            }
+                                                                           }
+                                                                    -- PRE_CLUSTERED_GROUP_BY[$$150, $$151]  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        order (ASC, $$150) (ASC, $$151)
                                                                         -- STABLE_SORT [$$150(ASC), $$151(ASC)]  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            project ([$$c, $$ca, $$ss1, $$dd1, $$185, $$150, $$151])
                                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                left outer join (eq($$150, $$167))
                                                                                 -- HYBRID_HASH_JOIN [$$150][$$167]  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- HASH_PARTITION_EXCHANGE [$$150]  |PARTITIONED|
+                                                                                    project ([$$c, $$ca, $$150, $$151])
                                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        join (eq($$161, $$151))
                                                                                         -- HYBRID_HASH_JOIN [$$161][$$151]  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- HASH_PARTITION_EXCHANGE [$$161]  |PARTITIONED|
+                                                                                            assign [$$161] <- [$$c.getField(4)]
                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                -- DATASOURCE_SCAN (tpcds.customer)  |PARTITIONED|
+                                                                                                data-scan []<-[$$150, $$c] <- tpcds.customer
+                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    empty-tuple-source
                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- HASH_PARTITION_EXCHANGE [$$151]  |PARTITIONED|
-                                                                                            -- DATASOURCE_SCAN (tpcds.customer_address)  |PARTITIONED|
+                                                                                            data-scan []<-[$$151, $$ca] <- tpcds.customer_address
+                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                empty-tuple-source
                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- HASH_PARTITION_EXCHANGE [$$167]  |PARTITIONED|
+                                                                                    assign [$$185] <- [true]
                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                      project ([$$ss1, $$167, $$dd1])
                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                          join (eq($$172, $$154))
                                                                                           -- HYBRID_HASH_JOIN [$$172][$$154]  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- HASH_PARTITION_EXCHANGE [$$172]  |PARTITIONED|
+                                                                                              assign [$$167, $$172] <- [$$ss1.getField(3), $$ss1.getField(0)]
                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                project ([$$ss1])
                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                    -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                                    data-scan []<-[$$152, $$153, $$ss1] <- tpcds.store_sales
+                                                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                        empty-tuple-source
                                                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              replicate
                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- HASH_PARTITION_EXCHANGE [$$154]  |PARTITIONED|
+                                                                                                  select (and(lt($$dd1.getField(10), 4), eq($$dd1.getField(6), 1900)))
                                                                                                   -- STREAM_SELECT  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                      -- DATASOURCE_SCAN (tpcds.date_dim)  |PARTITIONED|
+                                                                                                      data-scan []<-[$$154, $$dd1] <- tpcds.date_dim
+                                                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                          empty-tuple-source
                                                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                          exchange
                                                           -- HASH_PARTITION_EXCHANGE [$$169]  |PARTITIONED|
+                                                            assign [$$188] <- [true]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              project ([$$ws1, $$169, $$dd1])
                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  join (eq($$174, $$157))
                                                                   -- HYBRID_HASH_JOIN [$$174][$$157]  |PARTITIONED|
+                                                                    exchange
                                                                     -- HASH_PARTITION_EXCHANGE [$$174]  |PARTITIONED|
+                                                                      assign [$$169, $$174] <- [$$ws1.getField(4), $$ws1.getField(0)]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        project ([$$ws1])
                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- DATASOURCE_SCAN (tpcds.web_sales)  |PARTITIONED|
+                                                                            data-scan []<-[$$155, $$156, $$ws1] <- tpcds.web_sales
+                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                empty-tuple-source
                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      assign [$$157, $$dd1] <- [$$154, $$dd1] project: [$$157, $$dd1]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          replicate
                                                                           -- REPLICATE  |PARTITIONED|
+                                                                            exchange
                                                                             -- HASH_PARTITION_EXCHANGE [$$154]  |PARTITIONED|
+                                                                              select (and(lt($$dd1.getField(10), 4), eq($$dd1.getField(6), 1900)))
                                                                               -- STREAM_SELECT  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- DATASOURCE_SCAN (tpcds.date_dim)  |PARTITIONED|
+                                                                                  data-scan []<-[$$154, $$dd1] <- tpcds.date_dim
+                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      empty-tuple-source
                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$171]  |PARTITIONED|
+                                        assign [$$191] <- [true]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$cs1, $$171, $$dd1])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              join (eq($$176, $$160))
                                               -- HYBRID_HASH_JOIN [$$176][$$160]  |PARTITIONED|
+                                                exchange
                                                 -- HASH_PARTITION_EXCHANGE [$$176]  |PARTITIONED|
+                                                  assign [$$171, $$176] <- [$$cs1.getField(7), $$cs1.getField(0)]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    project ([$$cs1])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (tpcds.catalog_sales)  |PARTITIONED|
+                                                        data-scan []<-[$$158, $$159, $$cs1] <- tpcds.catalog_sales
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  assign [$$160, $$dd1] <- [$$154, $$dd1] project: [$$160, $$dd1]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- HASH_PARTITION_EXCHANGE [$$154]  |PARTITIONED|
+                                                          select (and(lt($$dd1.getField(10), 4), eq($$dd1.getField(6), 1900)))
                                                           -- STREAM_SELECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN (tpcds.date_dim)  |PARTITIONED|
+                                                              data-scan []<-[$$154, $$dd1] <- tpcds.date_dim
+                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1596.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1596.plan
index 286620f..e56b411 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1596.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1596.plan
@@ -1,26 +1,52 @@
+distribute result [$$50]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$50] <- [{"cs1": $$cs1, "cr1": $$cr1, "i1": $$i1}] project: [$$50]
     -- ASSIGN  |PARTITIONED|
+      project ([$$cs1, $$cr1, $$i1])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$53(ASC), $$54(ASC) ]  |PARTITIONED|
+          order (ASC, $$53) (ASC, $$54)
           -- STABLE_SORT [$$53(ASC), $$54(ASC)]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$cs1, $$cr1, $$i1, $$53, $$54])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$57, $$53))
                   -- HYBRID_HASH_JOIN [$$53][$$57]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$53]  |PARTITIONED|
+                      project ([$$cs1, $$cr1, $$53, $$54])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          left outer join (and(eq($$54, $$56), eq($$53, $$55)))
                           -- HYBRID_HASH_JOIN [$$54, $$53][$$56, $$55]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$54, $$53]  |PARTITIONED|
-                              -- DATASOURCE_SCAN (tpcds.catalog_sales)  |PARTITIONED|
+                              data-scan []<-[$$53, $$54, $$cs1] <- tpcds.catalog_sales
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$56, $$55]  |PARTITIONED|
-                              -- DATASOURCE_SCAN (tpcds.catalog_returns)  |PARTITIONED|
+                              data-scan []<-[$$55, $$56, $$cr1] <- tpcds.catalog_returns
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
-                      -- DATASOURCE_SCAN (tpcds.item)  |PARTITIONED|
+                      data-scan []<-[$$57, $$i1] <- tpcds.item
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1596_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1596_ps.plan
index 4cc1702..3b949ce 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1596_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1596_ps.plan
@@ -1,57 +1,114 @@
+distribute result [$$50]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$50] <- [{"cs1": $$cs1, "cr1": $$cr1, "i1": $$i1}] project: [$$50]
     -- ASSIGN  |PARTITIONED|
+      project ([$$cs1, $$cr1, $$i1])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$53) (ASC, $$54)
           -- STABLE_SORT [$$53(ASC), $$54(ASC)]  |PARTITIONED|
+            exchange
             -- RANGE_PARTITION_EXCHANGE [$$53(ASC), $$54(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$72
               -- FORWARD  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate
                   -- REPLICATE  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$cs1, $$cr1, $$i1, $$53, $$54])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          join (eq($$57, $$53))
                           -- HYBRID_HASH_JOIN [$$53][$$57]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$53]  |PARTITIONED|
+                              project ([$$cs1, $$cr1, $$53, $$54])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  left outer join (and(eq($$54, $$56), eq($$53, $$55)))
                                   -- HYBRID_HASH_JOIN [$$54, $$53][$$56, $$55]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$54, $$53]  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (tpcds.catalog_sales)  |PARTITIONED|
+                                      data-scan []<-[$$53, $$54, $$cs1] <- tpcds.catalog_sales
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$56, $$55]  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (tpcds.catalog_returns)  |PARTITIONED|
+                                      data-scan []<-[$$55, $$56, $$cr1] <- tpcds.catalog_returns
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
-                              -- DATASOURCE_SCAN (tpcds.item)  |PARTITIONED|
+                              data-scan []<-[$$57, $$i1] <- tpcds.item
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$72] <- [agg-range-map($$69, $$70, $$71)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$69, $$70, $$71] <- [agg-local-sampling($$53, $$54), agg-null-writer($$53), agg-null-writer($$54)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$53, $$54])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate
                             -- REPLICATE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$cs1, $$cr1, $$i1, $$53, $$54])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (eq($$57, $$53))
                                     -- HYBRID_HASH_JOIN [$$53][$$57]  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$53]  |PARTITIONED|
+                                        project ([$$cs1, $$cr1, $$53, $$54])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            left outer join (and(eq($$54, $$56), eq($$53, $$55)))
                                             -- HYBRID_HASH_JOIN [$$54, $$53][$$56, $$55]  |PARTITIONED|
+                                              exchange
                                               -- HASH_PARTITION_EXCHANGE [$$54, $$53]  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpcds.catalog_sales)  |PARTITIONED|
+                                                data-scan []<-[$$53, $$54, $$cs1] <- tpcds.catalog_sales
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              exchange
                                               -- HASH_PARTITION_EXCHANGE [$$56, $$55]  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpcds.catalog_returns)  |PARTITIONED|
+                                                data-scan []<-[$$55, $$56, $$cr1] <- tpcds.catalog_returns
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (tpcds.item)  |PARTITIONED|
+                                        data-scan []<-[$$57, $$i1] <- tpcds.item
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping.plan
index 9308292..6573c67 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping.plan
@@ -1,40 +1,74 @@
+distribute result [$$116]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$116] <- [{"l_shipmode": $$l_shipmode, "high_line_count": $$127, "low_line_count": $$128}] project: [$$116]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$l_shipmode(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$135]  |PARTITIONED|
-                {
+        group by ([$$l_shipmode := $$135]) decor ([]) {
+                  aggregate [$$127, $$128] <- [agg-global-sql-sum($$133), agg-global-sql-sum($$134)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$135]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$135]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$118]  |PARTITIONED|
-                    {
+            group by ([$$135 := $$118]) decor ([]) {
+                      aggregate [$$133, $$134] <- [agg-local-sql-sum(switch-case(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH")), numeric-add(1, numeric-multiply($$123, 0)), numeric-add(0, numeric-multiply($$123, 0)))), agg-local-sql-sum(switch-case(true, eq(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH"))), numeric-add(0, numeric-multiply($$123, 0)), numeric-add(1, numeric-multiply($$123, 0))))]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$118]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$123, $$118])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$124, $$118))
                     -- HYBRID_HASH_JOIN [$$118][$$124]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$123, $$118])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (eq($$122, $$126))
                             -- HYBRID_HASH_JOIN [$$126][$$122]  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$126]  |PARTITIONED|
+                                select (and(lt($$120, $$119), ge($$119, "1994-01-01"), lt($$119, "1995-01-01"), lt($$l.getField("l_shipdate"), $$120))) project: [$$118, $$126]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$120, $$119, $$118, $$126] <- [$$l.getField("l_commitdate"), $$l.getField("l_receiptdate"), $$l.getField("l_shipmode"), $$l.getField("l_orderkey")]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$l])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                        data-scan []<-[$$121, $$l] <- tpch.LineItem
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$122]  |PARTITIONED|
+                                assign [$$123] <- [$$o.getField("o_orderpriority")] project: [$$123, $$122]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                    data-scan []<-[$$122, $$o] <- tpch.Orders
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        unnest $$124 <- scan-collection(array: [ "MAIL", "SHIP" ])
                         -- UNNEST  |UNPARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping_broadcast.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping_broadcast.plan
index 3a0c212..16ac8e5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping_broadcast.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping_broadcast.plan
@@ -1,40 +1,74 @@
+distribute result [$$116]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$116] <- [{"l_shipmode": $$l_shipmode, "high_line_count": $$127, "low_line_count": $$128}] project: [$$116]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$l_shipmode(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$135]  |PARTITIONED|
-                {
+        group by ([$$l_shipmode := $$135]) decor ([]) {
+                  aggregate [$$127, $$128] <- [agg-global-sql-sum($$133), agg-global-sql-sum($$134)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$135]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$135]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$118]  |PARTITIONED|
-                    {
+            group by ([$$135 := $$118]) decor ([]) {
+                      aggregate [$$133, $$134] <- [agg-local-sql-sum(switch-case(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH")), numeric-add(1, numeric-multiply($$123, 0)), numeric-add(0, numeric-multiply($$123, 0)))), agg-local-sql-sum(switch-case(true, eq(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH"))), numeric-add(0, numeric-multiply($$123, 0)), numeric-add(1, numeric-multiply($$123, 0))))]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$118]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$123, $$118])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$124, $$118))
                     -- HYBRID_HASH_JOIN [$$118][$$124]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$123, $$118])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (eq($$125, $$122))
                             -- HYBRID_HASH_JOIN [$$125][$$122]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (and(lt($$120, $$119), ge($$119, "1994-01-01"), lt($$119, "1995-01-01"), lt($$l.getField("l_shipdate"), $$120))) project: [$$118, $$125]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$120, $$119, $$118, $$125] <- [$$l.getField("l_commitdate"), $$l.getField("l_receiptdate"), $$l.getField("l_shipmode"), $$l.getField("l_orderkey")]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$l])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                        data-scan []<-[$$121, $$l] <- tpch.LineItem
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$123] <- [$$o.getField("o_orderpriority")] project: [$$123, $$122]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                    data-scan []<-[$$122, $$o] <- tpch.Orders
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        unnest $$124 <- scan-collection(array: [ "MAIL", "SHIP" ])
                         -- UNNEST  |UNPARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping_broadcast_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping_broadcast_ps.plan
index cacd6c1..1f5315b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping_broadcast_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping_broadcast_ps.plan
@@ -1,90 +1,168 @@
+distribute result [$$116]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$116] <- [{"l_shipmode": $$l_shipmode, "high_line_count": $$127, "low_line_count": $$128}] project: [$$116]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$l_shipmode)
         -- STABLE_SORT [$$l_shipmode(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$l_shipmode(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$138
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$135]  |PARTITIONED|
-                            {
+                    group by ([$$l_shipmode := $$135]) decor ([]) {
+                              aggregate [$$127, $$128] <- [agg-global-sql-sum($$133), agg-global-sql-sum($$134)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$135]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$135]  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$118]  |PARTITIONED|
-                                {
+                        group by ([$$135 := $$118]) decor ([]) {
+                                  aggregate [$$133, $$134] <- [agg-local-sql-sum(switch-case(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH")), numeric-add(1, numeric-multiply($$123, 0)), numeric-add(0, numeric-multiply($$123, 0)))), agg-local-sql-sum(switch-case(true, eq(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH"))), numeric-add(0, numeric-multiply($$123, 0)), numeric-add(1, numeric-multiply($$123, 0))))]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$118]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$123, $$118])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$124, $$118))
                                 -- HYBRID_HASH_JOIN [$$118][$$124]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$123, $$118])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        join (eq($$125, $$122))
                                         -- HYBRID_HASH_JOIN [$$125][$$122]  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            select (and(lt($$120, $$119), ge($$119, "1994-01-01"), lt($$119, "1995-01-01"), lt($$l.getField("l_shipdate"), $$120))) project: [$$118, $$125]
                                             -- STREAM_SELECT  |PARTITIONED|
+                                              assign [$$120, $$119, $$118, $$125] <- [$$l.getField("l_commitdate"), $$l.getField("l_receiptdate"), $$l.getField("l_shipmode"), $$l.getField("l_orderkey")]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$l])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                                    data-scan []<-[$$121, $$l] <- tpch.LineItem
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            assign [$$123] <- [$$o.getField("o_orderpriority")] project: [$$123, $$122]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                                data-scan []<-[$$122, $$o] <- tpch.Orders
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    unnest $$124 <- scan-collection(array: [ "MAIL", "SHIP" ])
                                     -- UNNEST  |UNPARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$138] <- [agg-range-map($$136, $$137)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$136, $$137] <- [agg-local-sampling($$l_shipmode), agg-null-writer($$l_shipmode)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$l_shipmode])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- SORT_GROUP_BY[$$135]  |PARTITIONED|
-                                      {
+                              group by ([$$l_shipmode := $$135]) decor ([]) {
+                                        aggregate [$$127, $$128] <- [agg-global-sql-sum($$133), agg-global-sql-sum($$134)]
                                         -- AGGREGATE  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- SORT_GROUP_BY[$$135]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$135]  |PARTITIONED|
-                                  -- SORT_GROUP_BY[$$118]  |PARTITIONED|
-                                          {
+                                  group by ([$$135 := $$118]) decor ([]) {
+                                            aggregate [$$133, $$134] <- [agg-local-sql-sum(switch-case(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH")), numeric-add(1, numeric-multiply($$123, 0)), numeric-add(0, numeric-multiply($$123, 0)))), agg-local-sql-sum(switch-case(true, eq(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH"))), numeric-add(0, numeric-multiply($$123, 0)), numeric-add(1, numeric-multiply($$123, 0))))]
                                             -- AGGREGATE  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                          }
+                                         }
+                                  -- SORT_GROUP_BY[$$118]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$123, $$118])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          join (eq($$124, $$118))
                                           -- HYBRID_HASH_JOIN [$$118][$$124]  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$123, $$118])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  join (eq($$125, $$122))
                                                   -- HYBRID_HASH_JOIN [$$125][$$122]  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      select (and(lt($$120, $$119), ge($$119, "1994-01-01"), lt($$119, "1995-01-01"), lt($$l.getField("l_shipdate"), $$120))) project: [$$118, $$125]
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        assign [$$120, $$119, $$118, $$125] <- [$$l.getField("l_commitdate"), $$l.getField("l_receiptdate"), $$l.getField("l_shipmode"), $$l.getField("l_orderkey")]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          project ([$$l])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                                              data-scan []<-[$$121, $$l] <- tpch.LineItem
+                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                      assign [$$123] <- [$$o.getField("o_orderpriority")] project: [$$123, $$122]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                                          data-scan []<-[$$122, $$o] <- tpch.Orders
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              unnest $$124 <- scan-collection(array: [ "MAIL", "SHIP" ])
                                               -- UNNEST  |UNPARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping_ps.plan
index 1ca832e..de36b7c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpch/q12_shipping_ps.plan
@@ -1,90 +1,168 @@
+distribute result [$$116]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$116] <- [{"l_shipmode": $$l_shipmode, "high_line_count": $$127, "low_line_count": $$128}] project: [$$116]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$l_shipmode)
         -- STABLE_SORT [$$l_shipmode(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$l_shipmode(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$138
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$135]  |PARTITIONED|
-                            {
+                    group by ([$$l_shipmode := $$135]) decor ([]) {
+                              aggregate [$$127, $$128] <- [agg-global-sql-sum($$133), agg-global-sql-sum($$134)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$135]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$135]  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$118]  |PARTITIONED|
-                                {
+                        group by ([$$135 := $$118]) decor ([]) {
+                                  aggregate [$$133, $$134] <- [agg-local-sql-sum(switch-case(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH")), numeric-add(1, numeric-multiply($$123, 0)), numeric-add(0, numeric-multiply($$123, 0)))), agg-local-sql-sum(switch-case(true, eq(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH"))), numeric-add(0, numeric-multiply($$123, 0)), numeric-add(1, numeric-multiply($$123, 0))))]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$118]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$123, $$118])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$124, $$118))
                                 -- HYBRID_HASH_JOIN [$$118][$$124]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$123, $$118])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        join (eq($$122, $$126))
                                         -- HYBRID_HASH_JOIN [$$126][$$122]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$126]  |PARTITIONED|
+                                            select (and(lt($$120, $$119), ge($$119, "1994-01-01"), lt($$119, "1995-01-01"), lt($$l.getField("l_shipdate"), $$120))) project: [$$118, $$126]
                                             -- STREAM_SELECT  |PARTITIONED|
+                                              assign [$$120, $$119, $$118, $$126] <- [$$l.getField("l_commitdate"), $$l.getField("l_receiptdate"), $$l.getField("l_shipmode"), $$l.getField("l_orderkey")]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$l])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                                    data-scan []<-[$$121, $$l] <- tpch.LineItem
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$122]  |PARTITIONED|
+                                            assign [$$123] <- [$$o.getField("o_orderpriority")] project: [$$123, $$122]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                                data-scan []<-[$$122, $$o] <- tpch.Orders
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    unnest $$124 <- scan-collection(array: [ "MAIL", "SHIP" ])
                                     -- UNNEST  |UNPARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$138] <- [agg-range-map($$136, $$137)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$136, $$137] <- [agg-local-sampling($$l_shipmode), agg-null-writer($$l_shipmode)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$l_shipmode])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- SORT_GROUP_BY[$$135]  |PARTITIONED|
-                                      {
+                              group by ([$$l_shipmode := $$135]) decor ([]) {
+                                        aggregate [$$127, $$128] <- [agg-global-sql-sum($$133), agg-global-sql-sum($$134)]
                                         -- AGGREGATE  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- SORT_GROUP_BY[$$135]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$135]  |PARTITIONED|
-                                  -- SORT_GROUP_BY[$$118]  |PARTITIONED|
-                                          {
+                                  group by ([$$135 := $$118]) decor ([]) {
+                                            aggregate [$$133, $$134] <- [agg-local-sql-sum(switch-case(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH")), numeric-add(1, numeric-multiply($$123, 0)), numeric-add(0, numeric-multiply($$123, 0)))), agg-local-sql-sum(switch-case(true, eq(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH"))), numeric-add(0, numeric-multiply($$123, 0)), numeric-add(1, numeric-multiply($$123, 0))))]
                                             -- AGGREGATE  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                          }
+                                         }
+                                  -- SORT_GROUP_BY[$$118]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$123, $$118])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          join (eq($$124, $$118))
                                           -- HYBRID_HASH_JOIN [$$118][$$124]  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$123, $$118])
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  join (eq($$122, $$126))
                                                   -- HYBRID_HASH_JOIN [$$126][$$122]  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$126]  |PARTITIONED|
+                                                      select (and(lt($$120, $$119), ge($$119, "1994-01-01"), lt($$119, "1995-01-01"), lt($$l.getField("l_shipdate"), $$120))) project: [$$118, $$126]
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        assign [$$120, $$119, $$118, $$126] <- [$$l.getField("l_commitdate"), $$l.getField("l_receiptdate"), $$l.getField("l_shipmode"), $$l.getField("l_orderkey")]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          project ([$$l])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                                              data-scan []<-[$$121, $$l] <- tpch.LineItem
+                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$122]  |PARTITIONED|
+                                                      assign [$$123] <- [$$o.getField("o_orderpriority")] project: [$$123, $$122]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                                          data-scan []<-[$$122, $$o] <- tpch.Orders
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              unnest $$124 <- scan-collection(array: [ "MAIL", "SHIP" ])
                                               -- UNNEST  |UNPARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/union/union_opt_1_1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/union/union_opt_1_1.plan
index fc94531..344802e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/union/union_opt_1_1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/union/union_opt_1_1.plan
@@ -1,41 +1,82 @@
+distribute result [$$63]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$63] <- [{"unique1": $$65, "unique2": $$126, "unique3": $$128}] project: [$$63]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$126(ASC) ]  |PARTITIONED|
+        order (ASC, $$126)
         -- STABLE_SORT [$$126(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            union ($$82, $$92, $$65) ($$129, $$137, $$128) ($$66, $$67, $$126)
             -- UNION_ALL  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (ge($$82, 98)) project: [$$82, $$129, $$66]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$129, $$82] <- [$$t1.getField(10), $$t1.getField(0)] project: [$$66, $$129, $$82]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.onek1.onek1)  |PARTITIONED|
+                      unnest-map [$$66, $$t1] <- index-search("onek1", 0, "Default", "test", "onek1", false, false, 1, $$169, 1, $$169, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$169)
                           -- STABLE_SORT [$$169(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$169])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.onek1.onek1_idx)  |PARTITIONED|
+                                  unnest-map [$$168, $$169] <- index-search("onek1_idx", 0, "Default", "test", "onek1", false, false, 1, $$167, 0, true, true, false)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      assign [$$167] <- [$$170] project: [$$167]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$170] <- [98]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (ge($$92, 98)) project: [$$92, $$137, $$67]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$137, $$92] <- [$$t2.getField(10), $$t2.getField(1)] project: [$$67, $$137, $$92]
                   -- ASSIGN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.onek2.onek2)  |PARTITIONED|
+                      unnest-map [$$67, $$t2] <- index-search("onek2", 0, "Default", "test", "onek2", false, false, 1, $$172, 1, $$172, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$172)
                           -- STABLE_SORT [$$172(ASC)]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$172])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.onek2.onek2_idx)  |PARTITIONED|
+                                  unnest-map [$$171, $$172] <- index-search("onek2_idx", 0, "Default", "test", "onek2", false, false, 1, $$170, 0, true, true, false)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      replicate
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$170] <- [98]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/union/union_opt_1_2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/union/union_opt_1_2.plan
index 11174a8..87c308a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/union/union_opt_1_2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/union/union_opt_1_2.plan
@@ -1,43 +1,86 @@
+distribute result [$$t]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$t])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$120(ASC) ]  |PARTITIONED|
+        order (ASC, $$120)
         -- STABLE_SORT [$$120(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            union ($$54, $$62, $$t) ($$70, $$71, $$120)
             -- UNION_ALL  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (ge($$112, 98)) project: [$$54, $$70]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$54] <- [{"unique1": $$112, "unique2": $$70, "unique3": $$onek1.getField(10)}] project: [$$70, $$112, $$54]
                   -- ASSIGN  |PARTITIONED|
+                    assign [$$112] <- [$$onek1.getField(0)]
                     -- ASSIGN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.onek1.onek1)  |PARTITIONED|
+                        unnest-map [$$70, $$onek1] <- index-search("onek1", 0, "Default", "test", "onek1", false, false, 1, $$145, 1, $$145, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$145)
                             -- STABLE_SORT [$$145(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$145])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.onek1.onek1_idx)  |PARTITIONED|
+                                    unnest-map [$$144, $$145] <- index-search("onek1_idx", 0, "Default", "test", "onek1", false, false, 1, $$143, 0, true, true, false)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$143] <- [$$146] project: [$$143]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            replicate
                                             -- REPLICATE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                assign [$$146] <- [98]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (ge($$116, 98)) project: [$$62, $$71]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$62] <- [{"unique1": $$116, "unique2": $$71, "unique3": $$onek2.getField(10)}] project: [$$71, $$116, $$62]
                   -- ASSIGN  |PARTITIONED|
+                    assign [$$116] <- [$$onek2.getField(1)]
                     -- ASSIGN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.onek2.onek2)  |PARTITIONED|
+                        unnest-map [$$71, $$onek2] <- index-search("onek2", 0, "Default", "test", "onek2", false, false, 1, $$148, 1, $$148, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$148)
                             -- STABLE_SORT [$$148(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$148])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.onek2.onek2_idx)  |PARTITIONED|
+                                    unnest-map [$$147, $$148] <- index-search("onek2_idx", 0, "Default", "test", "onek2", false, false, 1, $$146, 0, true, true, false)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$146] <- [98]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/union/union_opt_1_3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/union/union_opt_1_3.plan
index e8ee1ea..119b3dc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/union/union_opt_1_3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/union/union_opt_1_3.plan
@@ -1,43 +1,86 @@
+distribute result [$$62]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$62] <- [{"alias": $$64, "name": $$126}] project: [$$62]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$64(ASC) ]  |PARTITIONED|
+        order (ASC, $$64)
         -- STABLE_SORT [$$64(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            union ($$81, $$91, $$64) ($$127, $$135, $$126)
             -- UNION_ALL  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (ge($$81, "Von")) project: [$$81, $$127]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$127, $$81] <- [$$t1.getField("name"), $$t1.getField("alias")] project: [$$127, $$81]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$t1])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.fbu1.fbu1)  |PARTITIONED|
+                        unnest-map [$$65, $$t1] <- index-search("fbu1", 0, "Default", "test", "fbu1", false, false, 1, $$167, 1, $$167, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$167)
                             -- STABLE_SORT [$$167(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$167])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.fbu1.fbu1_idx)  |PARTITIONED|
+                                    unnest-map [$$166, $$167] <- index-search("fbu1_idx", 0, "Default", "test", "fbu1", false, false, 1, $$165, 0, true, true, false)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$165] <- [$$168] project: [$$165]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            replicate
                                             -- REPLICATE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                assign [$$168] <- ["Von"]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (ge($$91, "Von")) project: [$$91, $$135]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$135, $$91] <- [$$t2.getField("name"), $$t2.getField("alias")] project: [$$135, $$91]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$t2])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.fbu2.fbu2)  |PARTITIONED|
+                        unnest-map [$$66, $$t2] <- index-search("fbu2", 0, "Default", "test", "fbu2", false, false, 1, $$170, 1, $$170, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$170)
                             -- STABLE_SORT [$$170(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$170])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (test.fbu2.fbu2_idx)  |PARTITIONED|
+                                    unnest-map [$$169, $$170] <- index-search("fbu2_idx", 0, "Default", "test", "fbu2", false, false, 1, $$168, 0, true, true, false)
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$168] <- ["Von"]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/union/union_opt_1_4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/union/union_opt_1_4.plan
index 78c4cc2..1643c2d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/union/union_opt_1_4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/union/union_opt_1_4.plan
@@ -1,45 +1,90 @@
+distribute result [$$t]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$t])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$116(ASC) ]  |PARTITIONED|
+        order (ASC, $$116)
         -- STABLE_SORT [$$116(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            union ($$53, $$60, $$t) ($$110, $$113, $$116)
             -- UNION_ALL  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (ge($$110, "Von")) project: [$$53, $$110]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$53] <- [{"alias": $$110, "name": $$fbu1.getField("name")}] project: [$$110, $$53]
                   -- ASSIGN  |PARTITIONED|
+                    assign [$$110] <- [$$fbu1.getField("alias")]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$fbu1])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.fbu1.fbu1)  |PARTITIONED|
+                          unnest-map [$$68, $$fbu1] <- index-search("fbu1", 0, "Default", "test", "fbu1", false, false, 1, $$141, 1, $$141, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$141)
                               -- STABLE_SORT [$$141(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$141])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.fbu1.fbu1_idx)  |PARTITIONED|
+                                      unnest-map [$$140, $$141] <- index-search("fbu1_idx", 0, "Default", "test", "fbu1", false, false, 1, $$139, 0, true, true, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$139] <- [$$142] project: [$$139]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              replicate
                                               -- REPLICATE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  assign [$$142] <- ["Von"]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select (ge($$113, "Von")) project: [$$60, $$113]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$60] <- [{"alias": $$113, "name": $$fbu2.getField("name")}] project: [$$113, $$60]
                   -- ASSIGN  |PARTITIONED|
+                    assign [$$113] <- [$$fbu2.getField("alias")]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$fbu2])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (test.fbu2.fbu2)  |PARTITIONED|
+                          unnest-map [$$69, $$fbu2] <- index-search("fbu2", 0, "Default", "test", "fbu2", false, false, 1, $$144, 1, $$144, true, true, true)
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$144)
                               -- STABLE_SORT [$$144(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$144])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.fbu2.fbu2_idx)  |PARTITIONED|
+                                      unnest-map [$$143, $$144] <- index-search("fbu2_idx", 0, "Default", "test", "fbu2", false, false, 1, $$142, 0, true, true, false)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$142] <- ["Von"]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/pg_win/pg_win_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/pg_win/pg_win_01.plan
index 49d2e01b..8e2ec09 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/pg_win/pg_win_01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/pg_win/pg_win_01.plan
@@ -1,8 +1,16 @@
+distribute result [$$80]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$80] <- [{"cnt": $$81}] project: [$$80]
     -- ASSIGN  |LOCAL|
+      aggregate [$$81] <- [agg-sql-sum($$82)]
       -- AGGREGATE  |LOCAL|
+        aggregate [$$82] <- [agg-sql-count(1)]
         -- AGGREGATE  |LOCAL|
+          unnest $$four <- range(1, 10)
           -- UNNEST  |UNPARTITIONED|
+            select (false)
             -- STREAM_SELECT  |UNPARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_misc/win_misc_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_misc/win_misc_01.plan
index b4b5e4b..a00d853 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_misc/win_misc_01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_misc/win_misc_01.plan
@@ -1,23 +1,46 @@
+distribute result [$$246]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$246] <- [{"rank_min_delta": $$248, "rank_max_delta": $$249, "percent_rank_min_delta": $$250, "percent_rank_max_delta": $$251}] project: [$$246]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$248, $$249, $$250, $$251] <- [agg-global-sql-min($$256), agg-global-sql-max($$257), agg-global-sql-min($$258), agg-global-sql-max($$259)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$256, $$257, $$258, $$259] <- [agg-local-sql-min($$232), agg-local-sql-max($$232), agg-local-sql-min($$240), agg-local-sql-max($$240)]
           -- AGGREGATE  |PARTITIONED|
+            assign [$$240, $$232] <- [switch-case(true, lt($$260, 0.001), 0, $$260), numeric-subtract($$262, $$212)] project: [$$232, $$240]
             -- ASSIGN  |PARTITIONED|
+              assign [$$260] <- [numeric-subtract(numeric-divide(numeric-subtract($$262, 1), 3), $$222)] project: [$$212, $$262, $$260]
               -- ASSIGN  |PARTITIONED|
+                assign [$$262] <- [numeric-add(numeric-multiply(numeric-subtract(2, $$n), 2), 1)] project: [$$222, $$212, $$262]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$n, $$222, $$212])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    window-aggregate [$$222, $$212] <- [percent-rank-impl($$n), rank-impl($$n)] partition [$$t1.c2, $$p] order (DESC, $$n)
                     -- WINDOW  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$t1.c2) (ASC, $$p) (DESC, $$n)
                         -- STABLE_SORT [$$t1.c2(ASC), $$p(ASC), $$n(DESC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$t1.c2, $$p]  |PARTITIONED|
+                            unnest $$d <- range($$252, 2) project: [$$n, $$t1.c2, $$p]
                             -- UNNEST  |PARTITIONED|
+                              unnest $$n <- range($$252, 2)
                               -- UNNEST  |PARTITIONED|
+                                unnest $$p <- range($$252, 2)
                                 -- UNNEST  |PARTITIONED|
+                                  assign [$$t1.c2, $$252] <- [$$t1.getField("c2"), $$t1.getField("one")] project: [$$t1.c2, $$252]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$t1])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+                                        data-scan []<-[$$247, $$t1] <- test.t1
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_misc/win_misc_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_misc/win_misc_02.plan
index dcb19ce..a7c7cb3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_misc/win_misc_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_misc/win_misc_02.plan
@@ -1,21 +1,39 @@
+distribute result [$$52]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$52] <- [{"c1": $$54, "sum": $$55}] project: [$$52]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$54(ASC) ]  |PARTITIONED|
+        order (ASC, $$54)
         -- STABLE_SORT [$$54(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$54, $$55])
             -- STREAM_PROJECT  |PARTITIONED|
-              -- WINDOW  |PARTITIONED|
-                      {
+              window-aggregate [] <- [] partition [$$40] order (ASC, $$54) frame on (ASC, $$42) start unbounded end [$$42] exclude [$$42] {
+                        aggregate [$$55] <- [agg-sql-sum($$54)]
                         -- AGGREGATE  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                      }
+                     }
+              -- WINDOW  |PARTITIONED|
+                window-aggregate [$$42] <- [row-number-impl()] partition [$$40] order (ASC, $$54)
                 -- WINDOW_STREAM  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$40) (ASC, $$54)
                     -- STABLE_SORT [$$40(ASC), $$54(ASC)]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$40]  |PARTITIONED|
+                        assign [$$40] <- [numeric-mod($$t1.getField("c2"), 2)] project: [$$54, $$40]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+                            data-scan []<-[$$54, $$t1] <- test.t1
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_1.plan
index eea2af0..5936d03 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_1.plan
@@ -1,10 +1,20 @@
+distribute result [$$49]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$49] <- [{"m": $$m, "t": $$t, "row_nubmer": $$42, "percent_rank": round-half-to-even($$47, 2)}] project: [$$49]
     -- ASSIGN  |LOCAL|
+      window-aggregate [$$47, $$42] <- [percent-rank-impl($$t), row-number-impl()] partition [$$m] order (ASC, $$t)
       -- WINDOW  |LOCAL|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+          order (ASC, $$m) (ASC, $$t)
           -- STABLE_SORT [$$m(ASC), $$t(ASC)]  |LOCAL|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+              assign [$$m] <- [numeric-mod($$t, 4)]
               -- ASSIGN  |UNPARTITIONED|
+                unnest $$t <- range(1, 20)
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_10.plan
index 48f9c4b..da26499 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_10.plan
@@ -1,14 +1,25 @@
+distribute result [$$98]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$98] <- [{"m": $$m, "t": $$t, "w1_first": $$99, "w2_first": numeric-subtract($$100, 1), "w3_last": $$101}] project: [$$98]
     -- ASSIGN  |LOCAL|
-      -- WINDOW  |LOCAL|
-              {
+      window-aggregate [] <- [] partition [$$m] order (ASC, $$t) frame on  start unbounded end unbounded {
+                aggregate [$$101, $$100, $$99] <- [agg-last-element($$t), agg-first-element(numeric-add($$t, 1)), agg-first-element($$t)]
                 -- AGGREGATE  |LOCAL|
+                  nested tuple source
                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-              }
+             }
+      -- WINDOW  |LOCAL|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+          order (ASC, $$m) (ASC, $$t)
           -- STABLE_SORT [$$m(ASC), $$t(ASC)]  |LOCAL|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+              assign [$$m] <- [numeric-mod($$t, 4)]
               -- ASSIGN  |UNPARTITIONED|
+                unnest $$t <- range(0, 11)
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_11.plan
index 48f9c4b..f579b08 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_11.plan
@@ -1,14 +1,25 @@
+distribute result [$$98]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$98] <- [{"m": $$m, "t": $$t, "w1_last": $$99, "w2_first": $$100, "w3_first": numeric-subtract($$101, 1)}] project: [$$98]
     -- ASSIGN  |LOCAL|
-      -- WINDOW  |LOCAL|
-              {
+      window-aggregate [] <- [] partition [$$m] order (ASC, $$t) frame on  start unbounded end unbounded {
+                aggregate [$$101, $$100, $$99] <- [agg-first-element(numeric-add($$t, 1)), agg-first-element($$t), agg-last-element($$t)]
                 -- AGGREGATE  |LOCAL|
+                  nested tuple source
                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-              }
+             }
+      -- WINDOW  |LOCAL|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+          order (ASC, $$m) (ASC, $$t)
           -- STABLE_SORT [$$m(ASC), $$t(ASC)]  |LOCAL|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+              assign [$$m] <- [numeric-mod($$t, 4)]
               -- ASSIGN  |UNPARTITIONED|
+                unnest $$t <- range(0, 11)
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_12.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_12.plan
index 9540028..09325d3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_12.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_12.plan
@@ -1,23 +1,43 @@
+distribute result [$$103]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$103] <- [{"x": $$x, "y": $$y, "cnt": $$106, "rnk": $$101}] project: [$$103]
     -- ASSIGN  |LOCAL|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+        order (ASC, $$x) (ASC, $$106)
         -- STABLE_SORT [$$x(ASC), $$106(ASC)]  |LOCAL|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+            project ([$$x, $$y, $$106, $$101])
             -- STREAM_PROJECT  |LOCAL|
+              window-aggregate [$$101] <- [rank-impl($$107)] partition [$$x] order (ASC, $$107)
               -- WINDOW_STREAM  |LOCAL|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                  order (ASC, $$x) (ASC, $$107)
                   -- STABLE_SORT [$$x(ASC), $$107(ASC)]  |LOCAL|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |LOCAL|
-                      -- PRE_CLUSTERED_GROUP_BY[$$109, $$110]  |LOCAL|
-                              {
+                      group by ([$$x := $$109; $$y := $$110]) decor ([]) {
+                                aggregate [$$106, $$107] <- [agg-sql-sum($$111), agg-sql-sum($$112)]
                                 -- AGGREGATE  |LOCAL|
+                                  aggregate [$$111, $$112] <- [agg-sql-count($$r), agg-sql-count($$r)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- PRE_CLUSTERED_GROUP_BY[$$109, $$110]  |LOCAL|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                          order (ASC, $$109) (ASC, $$110)
                           -- STABLE_SORT [$$109(ASC), $$110(ASC)]  |LOCAL|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                              assign [$$110, $$109] <- [numeric-mod($$r, 4), numeric-mod($$r, 2)]
                               -- ASSIGN  |UNPARTITIONED|
+                                unnest $$r <- range(1, 10)
                                 -- UNNEST  |UNPARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_2.plan
index 48f9c4b..2410ddb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_2.plan
@@ -1,14 +1,25 @@
+distribute result [$$58]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$58] <- [{"m": $$m, "t": $$t, "row_nubmer": $$45, "sum": $$59}] project: [$$58]
     -- ASSIGN  |LOCAL|
-      -- WINDOW  |LOCAL|
-              {
+      window-aggregate [$$45] <- [row-number-impl()] partition [$$m] order (ASC, $$t) frame on (ASC, $$t) start unbounded end [$$t] {
+                aggregate [$$59] <- [agg-sql-sum($$t)]
                 -- AGGREGATE  |LOCAL|
+                  nested tuple source
                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-              }
+             }
+      -- WINDOW  |LOCAL|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+          order (ASC, $$m) (ASC, $$t)
           -- STABLE_SORT [$$m(ASC), $$t(ASC)]  |LOCAL|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+              assign [$$m] <- [numeric-mod($$t, 4)]
               -- ASSIGN  |UNPARTITIONED|
+                unnest $$t <- range(1, 20)
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_3.plan
index 48f9c4b..d807436 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_3.plan
@@ -1,14 +1,25 @@
+distribute result [$$66]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$66] <- [{"m": $$m, "t": $$t, "row_nubmer": $$53, "sum": $$67}] project: [$$66]
     -- ASSIGN  |LOCAL|
-      -- WINDOW  |LOCAL|
-              {
+      window-aggregate [$$53] <- [row-number-impl()] partition [$$m] order (ASC, $$t) frame on (ASC, $$t) start unbounded end [$$t] {
+                aggregate [$$67] <- [agg-sql-sum(numeric-add($$t, numeric-mod($$t, 4)))]
                 -- AGGREGATE  |LOCAL|
+                  nested tuple source
                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-              }
+             }
+      -- WINDOW  |LOCAL|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+          order (ASC, $$m) (ASC, $$t)
           -- STABLE_SORT [$$m(ASC), $$t(ASC)]  |LOCAL|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+              assign [$$m] <- [numeric-mod($$t, 4)]
               -- ASSIGN  |UNPARTITIONED|
+                unnest $$t <- range(1, 20)
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_4.plan
index 48f9c4b..05e4725 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_4.plan
@@ -1,14 +1,25 @@
+distribute result [$$96]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$96] <- [{"m": $$m, "t": $$t, "row_nubmer": $$71, "sum": $$97, "avg": round-half-to-even($$98, 2)}] project: [$$96]
     -- ASSIGN  |LOCAL|
-      -- WINDOW  |LOCAL|
-              {
+      window-aggregate [$$71] <- [row-number-impl()] partition [$$m] order (ASC, $$t) frame on (ASC, $$t) start unbounded end [$$t] {
+                aggregate [$$98, $$97] <- [agg-sql-avg(numeric-subtract($$t, numeric-mod($$t, 4))), agg-sql-sum(numeric-add($$t, numeric-mod($$t, 4)))]
                 -- AGGREGATE  |LOCAL|
+                  nested tuple source
                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-              }
+             }
+      -- WINDOW  |LOCAL|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+          order (ASC, $$m) (ASC, $$t)
           -- STABLE_SORT [$$m(ASC), $$t(ASC)]  |LOCAL|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+              assign [$$m] <- [numeric-mod($$t, 4)]
               -- ASSIGN  |UNPARTITIONED|
+                unnest $$t <- range(1, 20)
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_5.plan
index eea2af0..64d7db0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_5.plan
@@ -1,10 +1,20 @@
+distribute result [$$70]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$70] <- [{"m": $$m, "t": $$t, "row_number": $$63, "ntile": $$67}] project: [$$70]
     -- ASSIGN  |LOCAL|
+      window-aggregate [$$67, $$63] <- [ntile-impl(2), row-number-impl()] partition [$$m] order (ASC, $$t)
       -- WINDOW  |LOCAL|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+          order (ASC, $$m) (ASC, $$t)
           -- STABLE_SORT [$$m(ASC), $$t(ASC)]  |LOCAL|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+              assign [$$m] <- [numeric-mod($$t, 4)]
               -- ASSIGN  |UNPARTITIONED|
+                unnest $$t <- range(1, 16)
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_6.plan
index 9c9856b..d92dfc8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_6.plan
@@ -1,11 +1,22 @@
+distribute result [$$71]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$71] <- [{"m": $$m, "t": $$t, "row_number": $$63, "ntile": $$67}] project: [$$71]
     -- ASSIGN  |LOCAL|
+      window-aggregate [$$67] <- [ntile-impl(numeric-add($$63, 1))] partition [$$m] order (ASC, $$t)
       -- WINDOW  |LOCAL|
+        window-aggregate [$$63] <- [row-number-impl()] partition [$$m] order (ASC, $$t)
         -- WINDOW_STREAM  |LOCAL|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+            order (ASC, $$m) (ASC, $$t)
             -- STABLE_SORT [$$m(ASC), $$t(ASC)]  |LOCAL|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                assign [$$m] <- [numeric-mod($$t, 4)]
                 -- ASSIGN  |UNPARTITIONED|
+                  unnest $$t <- range(1, 16)
                   -- UNNEST  |UNPARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_7.plan
index f02cdb4..15b9d0c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_7.plan
@@ -1,16 +1,29 @@
+distribute result [$$69]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$69] <- [{"m": $$m, "t": $$t, "sum": $$70, "avg": round-half-to-even($$71, 2)}] project: [$$69]
     -- ASSIGN  |LOCAL|
+      project ([$$m, $$t, $$70, $$71])
       -- STREAM_PROJECT  |LOCAL|
-        -- WINDOW  |LOCAL|
-                {
+        window-aggregate [] <- [] partition [$$m] order (ASC, $$t) frame on (ASC, $$48) start unbounded end [$$48] {
+                  aggregate [$$71, $$70] <- [agg-sql-avg($$t), agg-sql-sum($$t)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- WINDOW  |LOCAL|
+          window-aggregate [$$48] <- [row-number-impl()] partition [$$m] order (ASC, $$t)
           -- WINDOW_STREAM  |LOCAL|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+              order (ASC, $$m) (ASC, $$t)
               -- STABLE_SORT [$$m(ASC), $$t(ASC)]  |LOCAL|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                  assign [$$m] <- [numeric-mod($$t, 4)]
                   -- ASSIGN  |UNPARTITIONED|
+                    unnest $$t <- range(1, 20)
                     -- UNNEST  |UNPARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_8.plan
index 28dbe05..e6db206 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_8.plan
@@ -1,6 +1,12 @@
+distribute result [$$53]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    aggregate [$$53] <- [agg-sql-sum($$54)]
     -- AGGREGATE  |LOCAL|
+      aggregate [$$54] <- [agg-sql-count(1)]
       -- AGGREGATE  |LOCAL|
+        unnest $$x <- range(1, 10)
         -- UNNEST  |UNPARTITIONED|
-          -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
\ No newline at end of file
+          empty-tuple-source
+          -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_9.plan
index 6136376..9db9829 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_9.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_01/win_opt_01_9.plan
@@ -1,13 +1,23 @@
+distribute result [$$34]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$34] <- [{"x": $$x, "sum": $$35}] project: [$$34]
     -- ASSIGN  |LOCAL|
-      -- WINDOW  |LOCAL|
-              {
+      window-aggregate [] <- [] order (ASC, $$x) frame on  start unbounded end unbounded {
+                aggregate [$$35] <- [agg-sql-sum($$x)]
                 -- AGGREGATE  |LOCAL|
+                  nested tuple source
                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-              }
+             }
+      -- WINDOW  |LOCAL|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+          order (ASC, $$x)
           -- STABLE_SORT [$$x(ASC)]  |LOCAL|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+              unnest $$x <- range(1, 10)
               -- UNNEST  |UNPARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_02/win_opt_02_1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_02/win_opt_02_1.plan
index 367e8cb..ede975f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_02/win_opt_02_1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/window/win_opt_02/win_opt_02_1.plan
@@ -1,21 +1,36 @@
+distribute result [$$174]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$174] <- [{"t": $$r, "x": $$185, "dt": $$186, "dx": numeric-subtract($$185, $$178), "v": int64(numeric-divide(numeric-subtract($$185, $$178), $$186)), "a": int64(numeric-subtract(numeric-divide(numeric-subtract($$185, $$178), $$186), $$179))}] project: [$$174]
     -- ASSIGN  |LOCAL|
+      assign [$$186, $$185] <- [numeric-subtract($$r, $$177), numeric-multiply($$r, $$r)] project: [$$r, $$178, $$179, $$186, $$185]
       -- ASSIGN  |LOCAL|
+        project ([$$r, $$178, $$179, $$177])
         -- STREAM_PROJECT  |LOCAL|
-          -- WINDOW  |LOCAL|
-                  {
+          window-aggregate [] <- [] order (ASC, $$r) frame on (ASC, $$127) start [numeric-subtract($$127, 1)] if [is-numeric-add-compatible($$127)] end [numeric-subtract($$127, 1)] if [is-numeric-add-compatible($$127)] maxObjects 1 {
+                    aggregate [$$179] <- [agg-first-element(numeric-divide(numeric-subtract(numeric-multiply($$r, $$r), $$178), numeric-subtract($$r, $$177)))]
                     -- AGGREGATE  |LOCAL|
+                      nested tuple source
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
-            -- WINDOW  |LOCAL|
-                    {
+                 }
+          -- WINDOW  |LOCAL|
+            window-aggregate [] <- [] order (ASC, $$r) frame on (ASC, $$127) start [numeric-subtract($$127, 1)] if [is-numeric-add-compatible($$127)] end [numeric-subtract($$127, 1)] if [is-numeric-add-compatible($$127)] maxObjects 1 {
+                      aggregate [$$178, $$177] <- [agg-first-element(numeric-multiply($$r, $$r)), agg-first-element($$r)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- WINDOW  |LOCAL|
+              window-aggregate [$$127] <- [row-number-impl()] order (ASC, $$r)
               -- WINDOW_STREAM  |LOCAL|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                  order (ASC, $$r)
                   -- STABLE_SORT [$$r(ASC)]  |LOCAL|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                      unnest $$r <- range(1, 10)
                       -- UNNEST  |UNPARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ASTERIXDB-2402.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ASTERIXDB-2402.plan
index 62e50aa..c7d8549 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ASTERIXDB-2402.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ASTERIXDB-2402.plan
@@ -1,159 +1,300 @@
+distribute result [$$227]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$227])
     -- STREAM_PROJECT  |PARTITIONED|
-      -- SUBPLAN  |PARTITIONED|
-              {
+      subplan {
+                aggregate [$$227] <- [listify($$226)]
                 -- AGGREGATE  |LOCAL|
+                  assign [$$226] <- [{"channelExecutionTime": $$257, "result": $$258, "BrokerEndpoint": $$BrokerEndpoint}]
                   -- ASSIGN  |LOCAL|
-                    -- MICRO_PRE_CLUSTERED_GROUP_BY[$$230]  |LOCAL|
-                            {
+                    group by ([$$BrokerEndpoint := $$230]) decor ([$$257 := $$259; $$258 := $$260]) {
+                              aggregate [] <- []
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- MICRO_PRE_CLUSTERED_GROUP_BY[$$230]  |LOCAL|
+                      order (ASC, $$230)
                       -- MICRO_STABLE_SORT [$$230(ASC)]  |LOCAL|
+                        assign [$$230] <- [$$sub.getField("BrokerEndpoint")]
                         -- ASSIGN  |LOCAL|
+                          unnest $$sub <- scan-collection($$219)
                           -- UNNEST  |LOCAL|
-                            -- SUBPLAN  |LOCAL|
-                                    {
+                            subplan {
+                                      aggregate [$$219] <- [listify($$218)]
                                       -- AGGREGATE  |LOCAL|
+                                        assign [$$218] <- [{"sub": $$sub}]
                                         -- ASSIGN  |LOCAL|
+                                          unnest $$sub <- scan-collection($$256)
                                           -- UNNEST  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- SUBPLAN  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-              }
+             }
+      -- SUBPLAN  |PARTITIONED|
+        project ([$$260, $$259, $$256])
         -- STREAM_PROJECT  |PARTITIONED|
+          commit
           -- COMMIT  |PARTITIONED|
+            project ([$$260, $$259, $$256, $$214])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                insert into channels.EmergenciesNearMeChannelResults from record: $$231 partitioned by [$$214]
                 -- INSERT_DELETE  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$214]  |PARTITIONED|
+                    assign [$$260, $$259, $$256, $$214] <- [$$231.getField("result"), $$231.getField("channelExecutionTime"), $$231.getField("brokerSubIds"), $$231.getField(0)]
                     -- ASSIGN  |PARTITIONED|
+                      assign [$$231] <- [cast(check-unknown(put-autogenerated-key($$212, "resultId")))] project: [$$231]
                       -- ASSIGN  |PARTITIONED|
+                        assign [$$212] <- [{"result": $$result, "channelExecutionTime": current-datetime(), "channelSubId": $$266, "deliveryTime": current-datetime(), "brokerSubIds": $$211}] project: [$$212]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$211, $$266, $$result])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$267]  |PARTITIONED|
-                                      {
+                              group by ([$$269 := $$267]) decor ([$$266; $$result]) {
+                                        aggregate [$$211] <- [listify({"BrokerEndPoint": $$253, "brokerSubId": $$238})]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$268)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$267]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$267)
                                   -- STABLE_SORT [$$267(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$267]  |PARTITIONED|
+                                      project ([$$result, $$266, $$253, $$238, $$268, $$267])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          left outer join (eq($$237, $$266))
                                           -- HYBRID_HASH_JOIN [$$266][$$237]  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              running-aggregate [$$267] <- [create-query-uid()]
                                               -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                unnest $$result <- scan-collection($$191) project: [$$result, $$266]
                                                 -- UNNEST  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- PRE_CLUSTERED_GROUP_BY[$$319]  |PARTITIONED|
-                                                            {
+                                                    group by ([$$266 := $$319]) decor ([]) {
+                                                              aggregate [$$191] <- [listify({"report": $$328, "shelters": $$181})]
                                                               -- AGGREGATE  |LOCAL|
-                                                                -- MICRO_PRE_CLUSTERED_GROUP_BY[$$321, $$322]  |LOCAL|
-                                                                        {
+                                                                group by ([$$262 := $$321; $$263 := $$322]) decor ([$$317; $$323; $$324; $$325; $$319; $$326; $$327; $$328]) {
+                                                                          aggregate [$$181] <- [listify({"location": $$232})]
                                                                           -- AGGREGATE  |LOCAL|
+                                                                            select (not(is-missing($$236)))
                                                                             -- STREAM_SELECT  |LOCAL|
+                                                                              nested tuple source
                                                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                        }
+                                                                       }
+                                                                -- MICRO_PRE_CLUSTERED_GROUP_BY[$$321, $$322]  |LOCAL|
+                                                                  select (and(not(is-missing($$318)), not(is-missing($$320))))
                                                                   -- STREAM_SELECT  |LOCAL|
+                                                                    nested tuple source
                                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                            }
+                                                           }
+                                                    -- PRE_CLUSTERED_GROUP_BY[$$319]  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        order (ASC, $$319) (ASC, $$321) (ASC, $$322)
                                                         -- STABLE_SORT [$$319(ASC), $$321(ASC), $$322(ASC)]  |PARTITIONED|
+                                                          exchange
                                                           -- HASH_PARTITION_EXCHANGE [$$319]  |PARTITIONED|
+                                                            union ($$316, $$291, $$232) ($$u, $$u, $$317) ($$264, $$264, $$318) ($$233, $$233, $$319) ($$265, $$265, $$320) ($$234, $$234, $$321) ($$235, $$235, $$322) ($$242, $$242, $$323) ($$243, $$243, $$324) ($$244, $$244, $$325) ($$252, $$252, $$326) ($$sub, $$sub, $$327) ($$r, $$r, $$328) ($$314, $$289, $$236)
                                                             -- UNION_ALL  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                select (spatial-intersect($$316, $$244)) retain-untrue ($$314 <- missing) project: [$$316, $$u, $$264, $$233, $$265, $$234, $$235, $$242, $$243, $$244, $$252, $$sub, $$r, $$314]
                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                  assign [$$316] <- [$$315.getField(1)] project: [$$233, $$sub, $$242, $$234, $$r, $$243, $$252, $$264, $$235, $$u, $$265, $$244, $$289, $$314, $$316]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- BTREE_SEARCH (channels.Shelters.Shelters)  |PARTITIONED|
+                                                                      left-outer-unnest-map [$$314, $$315] <- index-search("Shelters", 0, "Default", "channels", "Shelters", true, false, 1, $$289, 1, $$289, true, true, true)
+                                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          project ([$$233, $$sub, $$242, $$234, $$r, $$243, $$252, $$264, $$235, $$u, $$265, $$244, $$289])
                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              split ($$290)
                                                                               -- SPLIT  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  project ([$$233, $$sub, $$242, $$234, $$r, $$243, $$252, $$264, $$235, $$u, $$265, $$244, $$285, $$286, $$289, $$290])
                                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                      -- RTREE_SEARCH (channels.Shelters.s_location)  |PARTITIONED|
+                                                                                      left-outer-unnest-map [$$285, $$286, $$287, $$288, $$289, $$290] <- index-search("s_location", 1, "Default", "channels", "Shelters", true, true, 4, $$281, $$282, $$283, $$284)
+                                                                                      -- RTREE_SEARCH  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                          assign [$$281, $$282, $$283, $$284] <- [create-mbr($$244, 2, 0), create-mbr($$244, 2, 1), create-mbr($$244, 2, 2), create-mbr($$244, 2, 3)]
                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              left outer join (and(spatial-intersect($$243, $$244), eq($$235, $$242)))
                                                                                               -- NESTED_LOOP  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                  left outer join (true)
                                                                                                   -- NESTED_LOOP  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                      assign [$$242] <- [$$sub.getField("param0")]
                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                          -- DATASOURCE_SCAN (channels.EmergenciesNearMeChannelChannelSubscriptions)  |PARTITIONED|
+                                                                                                          data-scan []<-[$$233, $$sub] <- channels.EmergenciesNearMeChannelChannelSubscriptions
+                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                              empty-tuple-source
                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                      assign [$$264] <- [true]
                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                        select (gt($$252, numeric-subtract(current-datetime(), day_time_duration: {PT10S })))
                                                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                                                          assign [$$243, $$252] <- [$$r.getField(2), $$r.getField(3)]
                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                              -- DATASOURCE_SCAN (channels.Reports)  |PARTITIONED|
+                                                                                                              data-scan []<-[$$234, $$r] <- channels.Reports
+                                                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                exchange
                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                  empty-tuple-source
                                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                  assign [$$265, $$244] <- [true, $$u.getField(0)]
                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                      -- DATASOURCE_SCAN (channels.UserLocations)  |PARTITIONED|
+                                                                                                      data-scan []<-[$$235, $$u] <- channels.UserLocations
+                                                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                          empty-tuple-source
                                                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                select (spatial-intersect($$291, $$244)) retain-untrue ($$236 <- missing) project: [$$291, $$u, $$264, $$233, $$265, $$234, $$235, $$242, $$243, $$244, $$252, $$sub, $$r, $$289]
                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                  assign [$$291] <- [create-point($$285, $$286)] project: [$$233, $$sub, $$242, $$234, $$r, $$243, $$252, $$264, $$235, $$u, $$265, $$244, $$289, $$291]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    project ([$$233, $$sub, $$242, $$234, $$r, $$243, $$252, $$264, $$235, $$u, $$265, $$244, $$285, $$286, $$289])
                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        split ($$290)
                                                                         -- SPLIT  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            project ([$$233, $$sub, $$242, $$234, $$r, $$243, $$252, $$264, $$235, $$u, $$265, $$244, $$285, $$286, $$289, $$290])
                                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                -- RTREE_SEARCH (channels.Shelters.s_location)  |PARTITIONED|
+                                                                                left-outer-unnest-map [$$285, $$286, $$287, $$288, $$289, $$290] <- index-search("s_location", 1, "Default", "channels", "Shelters", true, true, 4, $$281, $$282, $$283, $$284)
+                                                                                -- RTREE_SEARCH  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                    assign [$$281, $$282, $$283, $$284] <- [create-mbr($$244, 2, 0), create-mbr($$244, 2, 1), create-mbr($$244, 2, 2), create-mbr($$244, 2, 3)]
                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        left outer join (and(spatial-intersect($$243, $$244), eq($$235, $$242)))
                                                                                         -- NESTED_LOOP  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            left outer join (true)
                                                                                             -- NESTED_LOOP  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                assign [$$242] <- [$$sub.getField("param0")]
                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                    -- DATASOURCE_SCAN (channels.EmergenciesNearMeChannelChannelSubscriptions)  |PARTITIONED|
+                                                                                                    data-scan []<-[$$233, $$sub] <- channels.EmergenciesNearMeChannelChannelSubscriptions
+                                                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                        empty-tuple-source
                                                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                assign [$$264] <- [true]
                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                  select (gt($$252, numeric-subtract(current-datetime(), day_time_duration: {PT10S })))
                                                                                                   -- STREAM_SELECT  |PARTITIONED|
+                                                                                                    assign [$$243, $$252] <- [$$r.getField(2), $$r.getField(3)]
                                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                        -- DATASOURCE_SCAN (channels.Reports)  |PARTITIONED|
+                                                                                                        data-scan []<-[$$234, $$r] <- channels.Reports
+                                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                          exchange
                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                            empty-tuple-source
                                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                            assign [$$265, $$244] <- [true, $$u.getField(0)]
                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                -- DATASOURCE_SCAN (channels.UserLocations)  |PARTITIONED|
+                                                                                                data-scan []<-[$$235, $$u] <- channels.UserLocations
+                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    empty-tuple-source
                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$237]  |PARTITIONED|
+                                              assign [$$268] <- [true]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$238, $$237, $$253])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    join (and(eq($$248, $$239), eq($$250, $$240))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 6000000.0]
                                                     -- HYBRID_HASH_JOIN [$$248, $$250][$$239, $$240]  |PARTITIONED|
+                                                      exchange
                                                       -- HASH_PARTITION_EXCHANGE [$$248, $$250]  |PARTITIONED|
+                                                        assign [$$250, $$248] <- [$$bs.getField("BrokerName"), $$bs.getField("DataverseName")] project: [$$238, $$237, $$248, $$250]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (channels.EmergenciesNearMeChannelBrokerSubscriptions)  |PARTITIONED|
+                                                            data-scan []<-[$$237, $$238, $$bs] <- channels.EmergenciesNearMeChannelBrokerSubscriptions [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                      exchange
                                                       -- HASH_PARTITION_EXCHANGE [$$239, $$240]  |PARTITIONED|
+                                                        assign [$$253] <- [$$b.getField("BrokerEndPoint")] project: [$$253, $$239, $$240]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (channels.Broker)  |PARTITIONED|
+                                                            data-scan []<-[$$239, $$240, $$b] <- channels.Broker [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.10.plan
index 665d725..f663a4e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.10.plan
@@ -1,33 +1,63 @@
+distribute result [$$79]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$79] <- [{"g": $$g, "count_distinct_x": $$82, "sum_distinct_x": $$83}] project: [$$79]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$g(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
-                {
+        group by ([$$g := $$g]) decor ([]) {
+                  aggregate [$$82, $$83] <- [agg-sql-count($$72), agg-sql-sum($$72)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$72])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$72)
                       -- MICRO_STABLE_SORT [$$72(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$g)
             -- STABLE_SORT [$$g(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$g]  |PARTITIONED|
+                join (true)
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange [cardinality: 1.0E12, op-cost: 0.0, total-cost: 1.000006E12]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true) [cardinality: 1.0E12, op-cost: 1.0E12, total-cost: 1.000006E12]
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$72] <- [$$x.getField(1)] project: [$$72] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$x]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                              data-scan []<-[$$80, $$x] <- test.d1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        project ([]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                            data-scan []<-[$$81, $$y] <- test.d2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    unnest $$g <- range(1, 3)
                     -- UNNEST  |UNPARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.11.plan
index 55a8c3a..11620b2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.11.plan
@@ -1,40 +1,75 @@
+distribute result [$$79]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$79] <- [{"g": $$g, "sum_distinct_x": $$82, "sum_distinct_y": $$83}] project: [$$79]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$g(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
-                {
+        group by ([$$g := $$g]) decor ([]) {
+                  aggregate [$$82] <- [agg-sql-sum($$72)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$72])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$72)
                       -- MICRO_STABLE_SORT [$$72(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$83] <- [agg-sql-sum($$77)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$77])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$77)
                       -- MICRO_STABLE_SORT [$$77(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$g)
             -- STABLE_SORT [$$g(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$g]  |PARTITIONED|
+                join (true)
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange [cardinality: 1.0E12, op-cost: 0.0, total-cost: 1.000006E12]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true) [cardinality: 1.0E12, op-cost: 1.0E12, total-cost: 1.000006E12]
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$72] <- [$$x.getField(1)] project: [$$72] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$x]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                              data-scan []<-[$$80, $$x] <- test.d1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        assign [$$77] <- [$$y.getField(1)] project: [$$77] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$y]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                              data-scan []<-[$$81, $$y] <- test.d2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    unnest $$g <- range(1, 3)
                     -- UNNEST  |UNPARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.12.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.12.plan
index 523e336..cdf64bc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.12.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.12.plan
@@ -1,37 +1,69 @@
+distribute result [$$88]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$88] <- [{"g": $$g, "sum_x": $$91, "sum_distinct_x": $$92, "sum_distinct_y": $$93}] project: [$$88]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$g(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
-                {
+        group by ([$$g := $$g]) decor ([]) {
+                  aggregate [$$91] <- [agg-sql-sum($$76)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$92, $$93] <- [agg-sql-sum($$76), agg-sql-sum($$76)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$76])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$76)
                       -- MICRO_STABLE_SORT [$$76(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$g)
             -- STABLE_SORT [$$g(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$g]  |PARTITIONED|
+                join (true)
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange [cardinality: 1.0E12, op-cost: 0.0, total-cost: 1.000006E12]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true) [cardinality: 1.0E12, op-cost: 1.0E12, total-cost: 1.000006E12]
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$76] <- [$$x.getField(1)] project: [$$76] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$x]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                              data-scan []<-[$$89, $$x] <- test.d1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        project ([]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                            data-scan []<-[$$90, $$y] <- test.d2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    unnest $$g <- range(1, 3)
                     -- UNNEST  |UNPARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.13.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.13.plan
index aefdb9a..7ecd634 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.13.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.13.plan
@@ -1,53 +1,99 @@
+distribute result [$$100]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$100] <- [{"g": $$g, "sum_distinct_x": $$104, "sum_y": $$105, "sum_distinct_z": $$106}] project: [$$100]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$g(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
-                {
+        group by ([$$g := $$g]) decor ([]) {
+                  aggregate [$$104] <- [agg-sql-sum($$88)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$88])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$88)
                       -- MICRO_STABLE_SORT [$$88(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$105] <- [agg-sql-sum($$93)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$106] <- [agg-sql-sum($$98)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$98])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$98)
                       -- MICRO_STABLE_SORT [$$98(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$g)
             -- STABLE_SORT [$$g(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$g]  |PARTITIONED|
+                join (true)
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange [cardinality: 1.0E12, op-cost: 0.0, total-cost: 1.000006E12]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (true) [cardinality: 1.0E12, op-cost: 1.0E12, total-cost: 1.000006E12]
                         -- NESTED_LOOP  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$88] <- [$$x.getField(1)] project: [$$88] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$x]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                  data-scan []<-[$$101, $$x] <- test.d1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$93] <- [$$y.getField(1)] project: [$$93] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$y]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                  data-scan []<-[$$102, $$y] <- test.d2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        assign [$$98] <- [$$z.getField(1)] project: [$$98] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$z]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.d3)  |PARTITIONED|
+                              data-scan []<-[$$103, $$z] <- test.d3 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    unnest $$g <- range(1, 3)
                     -- UNNEST  |UNPARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.14.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.14.plan
index c522bc1..4e6f920 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.14.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.14.plan
@@ -1,59 +1,109 @@
+distribute result [$$154]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$154] <- [{"g": $$g, "sum_distinct_x": $$158, "sum_y": $$159, "sum_distinct_z": $$160, "avg_distinct_x": $$161, "avg_distinct_y": $$162, "count_x": $$163, "count_distinct_y": $$164, "avg_z": $$165, "count_distinct_z": $$166}] project: [$$154]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$g(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
-                {
+        group by ([$$g := $$g]) decor ([]) {
+                  aggregate [$$158, $$161] <- [agg-sql-sum($$112), agg-sql-avg($$112)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$112])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$112)
                       -- MICRO_STABLE_SORT [$$112(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$159, $$163, $$165] <- [agg-sql-sum($$117), agg-sql-count($$112), agg-sql-avg($$122)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$160, $$166] <- [agg-sql-sum($$122), agg-sql-count($$122)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$122])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$122)
                       -- MICRO_STABLE_SORT [$$122(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
-                {
+               }
+               {
+                  aggregate [$$162, $$164] <- [agg-sql-avg($$117), agg-sql-count($$117)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$117])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$117)
                       -- MICRO_STABLE_SORT [$$117(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$g)
             -- STABLE_SORT [$$g(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$g]  |PARTITIONED|
+                join (true)
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange [cardinality: 1.0E12, op-cost: 0.0, total-cost: 1.000006E12]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (true) [cardinality: 1.0E12, op-cost: 1.0E12, total-cost: 1.000006E12]
                         -- NESTED_LOOP  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$112] <- [$$x.getField(1)] project: [$$112] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$x]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                                  data-scan []<-[$$155, $$x] <- test.d1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$117] <- [$$y.getField(1)] project: [$$117] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$y]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                                  data-scan []<-[$$156, $$y] <- test.d2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        assign [$$122] <- [$$z.getField(1)] project: [$$122] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$z]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.d3)  |PARTITIONED|
+                              data-scan []<-[$$157, $$z] <- test.d3 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    unnest $$g <- range(1, 3)
                     -- UNNEST  |UNPARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.9.plan
index 979d032..3be0ae0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.9.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/aggregate-sql-sugar/distinct_mixed/distinct_mixed.9.plan
@@ -1,33 +1,63 @@
+distribute result [$$70]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$70] <- [{"g": $$g, "count_distinct_x": $$73}] project: [$$70]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$g(ASC) ]  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
-                {
+        group by ([$$g := $$g]) decor ([]) {
+                  aggregate [$$73] <- [agg-sql-count($$68)]
                   -- AGGREGATE  |LOCAL|
+                    distinct ([$$68])
                     -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                      order (ASC, $$68)
                       -- MICRO_STABLE_SORT [$$68(ASC)]  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$g]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$g)
             -- STABLE_SORT [$$g(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$g]  |PARTITIONED|
+                join (true)
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange [cardinality: 1.0E12, op-cost: 0.0, total-cost: 1.000006E12]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (true) [cardinality: 1.0E12, op-cost: 1.0E12, total-cost: 1.000006E12]
                     -- NESTED_LOOP  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$68] <- [$$x.getField(1)] project: [$$68] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$x]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.d1)  |PARTITIONED|
+                              data-scan []<-[$$71, $$x] <- test.d1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        project ([]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.d2)  |PARTITIONED|
+                            data-scan []<-[$$72, $$y] <- test.d2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    unnest $$g <- range(1, 3)
                     -- UNNEST  |UNPARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query1.plan
index a7f9021..ff83e78 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query1.plan
@@ -1,12 +1,24 @@
+distribute result [$$35] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"D": $$D, "DI": $$DI}] project: [$$35] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq($$DI.getField("field2"), 2), eq($$DI.getField("field3"), 3))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$DI <- scan-collection($$39) project: [$$D, $$DI] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          select (and(eq($$D.getField("field1"), 1), eq($$D.getField("field4"), 4)))
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$39] <- [$$D.getField("items")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TestDataverse.Dataset1)  |PARTITIONED|
+                  data-scan []<-[$$36, $$D] <- TestDataverse.Dataset1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query2.plan
index a7f9021..9b44843 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query2.plan
@@ -1,12 +1,24 @@
+distribute result [$$39] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$39] <- [{"D": $$D, "DI": $$DI}] project: [$$39] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq($$DI.getField("field2"), 2), eq($$DI.getField("field3"), 3), eq($$DI.getField("field3_notindexed"), 3))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$DI <- scan-collection($$44) project: [$$D, $$DI] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          select (and(eq($$D.getField("field4"), 4), eq($$D.getField("field1"), 1), eq($$D.getField("field4_notindexed"), 4)))
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$44] <- [$$D.getField("items")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TestDataverse.Dataset1)  |PARTITIONED|
+                  data-scan []<-[$$40, $$D] <- TestDataverse.Dataset1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query3.plan
index b14812e..787edcb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query3.plan
@@ -1,15 +1,30 @@
+distribute result [$$51] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$51] <- [{"D": $$D, "DOI": $$DOI, "DII": $$DII}] project: [$$51] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq($$DII.getField("field2"), 2), eq($$DII.getField("field3"), 3), eq($$DII.getField("field3_notindexed"), 3))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$DII <- scan-collection($$57) project: [$$D, $$DOI, $$DII] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          select (eq($$DOI.getField("field2_notindexed"), 2))
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$57] <- [$$DOI.getField("inner_items")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              unnest $$DOI <- scan-collection($$55) project: [$$D, $$DOI] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- UNNEST  |PARTITIONED|
+                select (and(eq($$D.getField("field1"), 1), eq($$D.getField("field4"), 4)))
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$55] <- [$$D.getField("outer_items")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$D]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (TestDataverse.Dataset1)  |PARTITIONED|
+                        data-scan []<-[$$52, $$D] <- TestDataverse.Dataset1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query4.plan
index ab210b2..dcfd44c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query4.plan
@@ -1,20 +1,37 @@
+distribute result [$$37] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$37] <- [{"D": $$D}] project: [$$37] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select ($$32) project: [$$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D, $$32]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$32] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (and(eq($$43, 2), eq($$42, 3)))
                       -- STREAM_SELECT  |LOCAL|
+                        assign [$$43, $$42] <- [$$DI.getField("field2"), $$DI.getField("field3")]
                         -- ASSIGN  |LOCAL|
+                          unnest $$DI <- scan-collection($$41)
                           -- UNNEST  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+          -- SUBPLAN  |PARTITIONED|
+            select (and(eq($$D.getField("field1"), 1), eq($$D.getField("field4"), 4)))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$41] <- [$$D.getField("items")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$D]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (TestDataverse.Dataset1)  |PARTITIONED|
+                    data-scan []<-[$$38, $$D] <- TestDataverse.Dataset1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query5.plan
index 6a47d67..260dd51 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query5.plan
@@ -1,29 +1,52 @@
+distribute result [$$55] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$55] <- [{"D": $$D}] project: [$$55] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select ($$50) project: [$$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D, $$50]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$50] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select ($$48)
                       -- STREAM_SELECT  |LOCAL|
-                        -- SUBPLAN  |LOCAL|
-                                {
+                        subplan {
+                                  aggregate [$$48] <- [non-empty-stream()]
                                   -- AGGREGATE  |LOCAL|
+                                    select (and(eq($$64, 2), eq($$63, 3), eq($$62, 3)))
                                     -- STREAM_SELECT  |LOCAL|
+                                      assign [$$64, $$63, $$62] <- [$$DII.getField("field2"), $$DII.getField("field3"), $$DII.getField("field3_notindexed")]
                                       -- ASSIGN  |LOCAL|
+                                        unnest $$DII <- scan-collection($$61)
                                         -- UNNEST  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SUBPLAN  |LOCAL|
+                          select (eq($$60, 2))
                           -- STREAM_SELECT  |LOCAL|
+                            assign [$$61, $$60] <- [$$DOI.getField("inner_items"), $$DOI.getField("field2_notindexed")]
                             -- ASSIGN  |LOCAL|
+                              unnest $$DOI <- scan-collection($$59)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+          -- SUBPLAN  |PARTITIONED|
+            select (and(eq($$D.getField("field1"), 1), eq($$D.getField("field4"), 4)))
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$59] <- [$$D.getField("outer_items")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$D]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (TestDataverse.Dataset1)  |PARTITIONED|
+                    data-scan []<-[$$56, $$D] <- TestDataverse.Dataset1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query8.plan
index 9bf272a..c98f46e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query8.plan
@@ -1,36 +1,69 @@
+distribute result [$$57] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$57] <- [{"D2": $$D2, "D1": $$D1}] project: [$$57] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select ($$50) project: [$$D2, $$D1]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D2, $$D1, $$50]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$50] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (and(eq($$69, to-bigint($$70)), eq($$67, to-bigint($$68))))
                       -- STREAM_SELECT  |LOCAL|
+                        assign [$$69, $$67] <- [$$D1I.getField("field2"), $$D1I.getField("field3")]
                         -- ASSIGN  |LOCAL|
+                          unnest $$D1I <- scan-collection($$66)
                           -- UNNEST  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$66] <- [$$D1.getField("items")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D2, $$70, $$68, $$D1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$59, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", true, false, 1, $$77, 1, $$77, true, true, true) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$77, $$D2, $$70, $$68])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$77, $$78])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$77) (ASC, $$78)
                               -- STABLE_SORT [$$77(ASC), $$78(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$D2, $$70, $$68, $$77, $$78])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                      unnest-map [$$73, $$74, $$75, $$76, $$77] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", true, true, 4, $$61, $$71, $$72, $$63, 4, $$61, $$71, $$72, $$63, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          running-aggregate [$$78] <- [create-query-uid()]
                                           -- RUNNING_AGGREGATE  |PARTITIONED|
+                                            assign [$$72, $$71] <- [to-bigint($$68), to-bigint($$70)]
                                             -- ASSIGN  |PARTITIONED|
+                                              assign [$$63, $$61, $$70, $$68] <- [to-bigint($$D2.getField("field4")), to-bigint($$D2.getField("field1")), $$D2.getField("field2"), $$D2.getField("field3")]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$D2])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (TestDataverse.Dataset2)  |PARTITIONED|
+                                                    data-scan []<-[$$58, $$D2] <- TestDataverse.Dataset2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query9.plan
index ab7ffda..e0f846d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query9.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/atomic-and-array-queries/query9.plan
@@ -1,45 +1,84 @@
+distribute result [$$79] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$79] <- [{"D2": $$D2, "D1": $$D1}] project: [$$79] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select ($$72) project: [$$D2, $$D1]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D2, $$D1, $$72]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$72] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select ($$70)
                       -- STREAM_SELECT  |LOCAL|
-                        -- SUBPLAN  |LOCAL|
-                                {
+                        subplan {
+                                  aggregate [$$70] <- [non-empty-stream()]
                                   -- AGGREGATE  |LOCAL|
+                                    select (and(eq($$96, to-bigint($$97)), eq($$94, to-bigint($$95)), eq($$92, to-bigint($$93))))
                                     -- STREAM_SELECT  |LOCAL|
+                                      assign [$$96, $$94, $$92] <- [$$DII.getField("field2"), $$DII.getField("field3"), $$DII.getField("field3_notindexed")]
                                       -- ASSIGN  |LOCAL|
+                                        unnest $$DII <- scan-collection($$91)
                                         -- UNNEST  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SUBPLAN  |LOCAL|
+                          select (eq($$89, to-bigint($$90)))
                           -- STREAM_SELECT  |LOCAL|
+                            assign [$$91, $$89] <- [$$DOI.getField("inner_items"), $$DOI.getField("field2_notindexed")]
                             -- ASSIGN  |LOCAL|
+                              unnest $$DOI <- scan-collection($$88)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$88] <- [$$D1.getField("outer_items")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D2, $$97, $$95, $$93, $$90, $$D1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TestDataverse.Dataset1.Dataset1)  |PARTITIONED|
+                  unnest-map [$$81, $$D1] <- index-search("Dataset1", 0, "Default", "TestDataverse", "Dataset1", true, false, 1, $$108, 1, $$108, true, true, true) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$108, $$D2, $$97, $$95, $$93, $$90])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          distinct ([$$108, $$109])
                           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              order (ASC, $$108) (ASC, $$109)
                               -- STABLE_SORT [$$108(ASC), $$109(ASC)]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  project ([$$D2, $$97, $$95, $$93, $$90, $$108, $$109])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (TestDataverse.Dataset1.d1Idx)  |PARTITIONED|
+                                      unnest-map [$$104, $$105, $$106, $$107, $$108] <- index-search("d1Idx", 0, "Default", "TestDataverse", "Dataset1", true, true, 4, $$83, $$100, $$101, $$85, 4, $$83, $$100, $$101, $$85, true, true, true)
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          running-aggregate [$$109] <- [create-query-uid()]
                                           -- RUNNING_AGGREGATE  |PARTITIONED|
+                                            assign [$$101, $$100] <- [to-bigint($$95), to-bigint($$97)]
                                             -- ASSIGN  |PARTITIONED|
+                                              assign [$$85, $$83, $$97, $$95, $$93, $$90] <- [to-bigint($$D2.getField("field4")), to-bigint($$D2.getField("field1")), $$D2.getField("field2"), $$D2.getField("field3"), $$D2.getField("field3_notindexed"), $$D2.getField("field2_notindexed")]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$D2])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (TestDataverse.Dataset2)  |PARTITIONED|
+                                                    data-scan []<-[$$80, $$D2] <- TestDataverse.Dataset2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/multiple-indexes/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/multiple-indexes/query1.plan
index f5099d7..afb642e62 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/multiple-indexes/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/multiple-indexes/query1.plan
@@ -1,19 +1,35 @@
+distribute result [$$32] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"k": $$k}] project: [$$32] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select ($$30) project: [$$k] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$k, $$30]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$30] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (and(eq($$36, 284), eq($$35, 263)))
                       -- STREAM_SELECT  |LOCAL|
+                        assign [$$36, $$35] <- [$$v.getField("a"), $$v.getField("b")]
                         -- ASSIGN  |LOCAL|
+                          unnest $$v <- scan-collection($$34)
                           -- UNNEST  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$34] <- [$$k.getField("uarr_i")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              project ([$$k]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.KSI)  |PARTITIONED|
+                  data-scan []<-[$$33, $$k] <- test.KSI [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/multiple-indexes/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/multiple-indexes/query2.plan
index f5099d7..b226f93 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/multiple-indexes/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/multiple-indexes/query2.plan
@@ -1,19 +1,35 @@
+distribute result [$$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"k": $$k}] project: [$$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select ($$32) project: [$$k] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$k, $$32]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$32] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (and(eq($$39, 284), eq($$38, 263), eq($$37, 123)))
                       -- STREAM_SELECT  |LOCAL|
+                        assign [$$39, $$38, $$37] <- [$$v.getField("a"), $$v.getField("b"), $$v.getField("c")]
                         -- ASSIGN  |LOCAL|
+                          unnest $$v <- scan-collection($$36)
                           -- UNNEST  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$36] <- [$$k.getField("uarr_i")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              project ([$$k]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.KSI)  |PARTITIONED|
+                  data-scan []<-[$$35, $$k] <- test.KSI [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/multiple-quantifiers/query7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/multiple-quantifiers/query7.plan
index 306ff7f..13c7d3b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/multiple-quantifiers/query7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/multiple-quantifiers/query7.plan
@@ -1,20 +1,37 @@
+distribute result [$$46] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$46] <- [{"D1": $$D1}] project: [$$46] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (and($$42, eq($$43, 0))) project: [$$D1] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$D1, $$42, $$43]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$42, $$43] <- [non-empty-stream(), agg-sql-count(switch-case(and(eq($$50, 1), eq($$51, 2)), true, null, true))]
                     -- AGGREGATE  |LOCAL|
+                      assign [$$51] <- [$$J.getField("item")]
                       -- ASSIGN  |LOCAL|
+                        unnest $$J <- scan-collection($$49)
                         -- UNNEST  |LOCAL|
+                          assign [$$50] <- [$$I.getField(0)]
                           -- ASSIGN  |LOCAL|
+                            unnest $$I <- scan-collection($$48)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$49, $$48] <- [$$D1.getField("other_items"), $$D1.getField(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              project ([$$D1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TestDataverse.Dataset1)  |PARTITIONED|
+                  data-scan []<-[$$47, $$D1] <- TestDataverse.Dataset1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-1/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-1/query1.plan
index 6208814..f7afed9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-1/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-1/query1.plan
@@ -1,18 +1,33 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$20] <- [{"business_id": $$23}] project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select ($$17) project: [$$23] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$23, $$17]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$17] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (eq("2016-04-26 19:49:16", $#1))
                       -- STREAM_SELECT  |LOCAL|
+                        unnest $#1 <- scan-collection($$22)
                         -- UNNEST  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$23, $$22] <- [$$C.getField(1), $$C.getField(2)] project: [$$23, $$22] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                  data-scan []<-[$$21, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-1/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-1/query2.plan
index a931a58..a169f12 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-1/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-1/query2.plan
@@ -1,21 +1,39 @@
+distribute result [$$50] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$50] <- [{"$1": $$52}] project: [$$50] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$52] <- [agg-sql-sum($$54)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$54] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select ($$43) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$43]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$43] <- [non-empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select (and(gt($$D, "2016"), lt($$D, "2017")))
                             -- STREAM_SELECT  |LOCAL|
+                              unnest $$D <- scan-collection($$53)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+                -- SUBPLAN  |PARTITIONED|
+                  assign [$$53] <- [$$C.getField(2)] project: [$$53] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                        data-scan []<-[$$51, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-1/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-1/query4.plan
index 48dfd6c..ebc5e72 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-1/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-1/query4.plan
@@ -1,20 +1,37 @@
+distribute result [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$52] <- [{"$1": $$54}] project: [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$54] <- [agg-sql-sum($$56)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$56] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (and($$43, eq($$44, 0))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$43, $$44]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$43, $$44] <- [non-empty-stream(), agg-sql-count(switch-case(and(gt($$D, "2016"), lt($$D, "2017")), true, null, true))]
                           -- AGGREGATE  |LOCAL|
+                            unnest $$D <- scan-collection($$55)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+                -- SUBPLAN  |PARTITIONED|
+                  assign [$$55] <- [$$C.getField(2)] project: [$$55] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                        data-scan []<-[$$53, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-2/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-2/query1.plan
index 6208814..6525e37 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-2/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-2/query1.plan
@@ -1,18 +1,33 @@
+distribute result [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$21] <- [{"business_id": $$24}] project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select ($$18) project: [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$24, $$18]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$18] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (eq("2016-04-26", $#1))
                       -- STREAM_SELECT  |LOCAL|
+                        unnest $#1 <- scan-collection($$23)
                         -- UNNEST  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$23, $$24] <- [$$C.getField(2).getField(0), $$C.getField(1)] project: [$$24, $$23] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                  data-scan []<-[$$22, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-2/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-2/query2.plan
index a931a58..b0c8711 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-2/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-2/query2.plan
@@ -1,21 +1,39 @@
+distribute result [$$51] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$51] <- [{"$1": $$53}] project: [$$51] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$53] <- [agg-sql-sum($$56)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$56] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select ($$44) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$44]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$44] <- [non-empty-stream()]
                           -- AGGREGATE  |LOCAL|
+                            select (and(gt($$D, "2016"), lt($$D, "2017")))
                             -- STREAM_SELECT  |LOCAL|
+                              unnest $$D <- scan-collection($$54)
                               -- UNNEST  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+                -- SUBPLAN  |PARTITIONED|
+                  assign [$$54] <- [$$C.getField(2).getField(0)] project: [$$54] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                        data-scan []<-[$$52, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-2/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-2/query3.plan
index 48dfd6c..ab2e263 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-2/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-2/query3.plan
@@ -1,20 +1,37 @@
+distribute result [$$53] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$53] <- [{"$1": $$55}] project: [$$53] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$55] <- [agg-sql-sum($$58)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$58] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (and($$44, eq($$45, 0))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$44, $$45]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
-                -- SUBPLAN  |PARTITIONED|
-                        {
+                subplan {
+                          aggregate [$$44, $$45] <- [non-empty-stream(), agg-sql-count(switch-case(and(gt($$D, "2016"), lt($$D, "2017")), true, null, true))]
                           -- AGGREGATE  |LOCAL|
+                            unnest $$D <- scan-collection($$56)
                             -- UNNEST  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+                -- SUBPLAN  |PARTITIONED|
+                  assign [$$56] <- [$$C.getField(2).getField(0)] project: [$$56] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                        data-scan []<-[$$54, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-3/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-3/query1.plan
index 507cf3e..c804302 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-3/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-3/query1.plan
@@ -1,19 +1,35 @@
+distribute result [$$30] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$30] <- [{"business_id": $$34}] project: [$$30] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select ($$27) project: [$$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$34, $$27]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$27] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (eq("2016-04-26", $$33))
                       -- STREAM_SELECT  |LOCAL|
+                        assign [$$33] <- [$$D.getField(0)]
                         -- ASSIGN  |LOCAL|
+                          unnest $$D <- scan-collection($$32)
                           -- UNNEST  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$34, $$32] <- [$$C.getField(1), $$C.getField(2)] project: [$$34, $$32] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                  data-scan []<-[$$31, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-3/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-3/query2.plan
index 507cf3e..576d034 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-3/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-3/query2.plan
@@ -1,19 +1,35 @@
+distribute result [$$33] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"business_id": $$38}] project: [$$33] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select ($$30) project: [$$38] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$38, $$30]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$30] <- [non-empty-stream()]
                     -- AGGREGATE  |LOCAL|
+                      select (and(eq($$37, "2016-04-26"), eq($$36, "19:49:16")))
                       -- STREAM_SELECT  |LOCAL|
+                        assign [$$37, $$36] <- [$$D.getField(0), $$D.getField(1)]
                         -- ASSIGN  |LOCAL|
+                          unnest $$D <- scan-collection($$35)
                           -- UNNEST  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$38, $$35] <- [$$C.getField(1), $$C.getField(2)] project: [$$38, $$35] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                  data-scan []<-[$$34, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-3/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-3/query3.plan
index ff93394..61d3a04 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-3/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-quantified-queries/use-case-3/query3.plan
@@ -1,18 +1,33 @@
+distribute result [$$35] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"business_id": $$40}] project: [$$35] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (and($$30, eq($$31, 0))) project: [$$40] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$40, $$30, $$31]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
-          -- SUBPLAN  |PARTITIONED|
-                  {
+          subplan {
+                    aggregate [$$30, $$31] <- [non-empty-stream(), agg-sql-count(switch-case(and(ge($$38, "2016"), le($$38, "2017")), true, null, true))]
                     -- AGGREGATE  |LOCAL|
+                      assign [$$38] <- [$$D.getField(0)]
                       -- ASSIGN  |LOCAL|
+                        unnest $$D <- scan-collection($$37)
                         -- UNNEST  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 } [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+          -- SUBPLAN  |PARTITIONED|
+            assign [$$40, $$37] <- [$$C.getField(1), $$C.getField(2)] project: [$$40, $$37] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                  data-scan []<-[$$36, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-1/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-1/query1.plan
index 51d0004..fe04b6a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-1/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-1/query1.plan
@@ -1,11 +1,22 @@
+distribute result [$$28] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$28] <- [{"business_id": $$31}] project: [$$28] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26 19:49:16", $$D)) project: [$$31] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$30) project: [$$31, $$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$31, $$30] <- [$$C.getField(1), $$C.getField(2)] project: [$$31, $$30] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                data-scan []<-[$$29, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-1/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-1/query2.plan
index 1ff305e..efb8412 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-1/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-1/query2.plan
@@ -1,14 +1,28 @@
+distribute result [$$49] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$49] <- [{"$1": $$51}] project: [$$49] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$51] <- [agg-sql-sum($$53)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$53] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017"))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$52) project: [$$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- UNNEST  |PARTITIONED|
+                assign [$$52] <- [$$C.getField(2)] project: [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                      data-scan []<-[$$50, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-2/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-2/query1.plan
index 51d0004..dd556a9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-2/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-2/query1.plan
@@ -1,11 +1,22 @@
+distribute result [$$29] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"business_id": $$32}] project: [$$29] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26", $$D)) project: [$$32] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$31) project: [$$32, $$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$31, $$32] <- [$$C.getField(2).getField(0), $$C.getField(1)] project: [$$31, $$32] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                data-scan []<-[$$30, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-2/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-2/query2.plan
index 1ff305e..7be0f1a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-2/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-2/query2.plan
@@ -1,14 +1,28 @@
+distribute result [$$50] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$50] <- [{"$1": $$52}] project: [$$50] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$52] <- [agg-sql-sum($$55)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$55] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017"))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$53) project: [$$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- UNNEST  |PARTITIONED|
+                assign [$$53] <- [$$C.getField(2).getField(0)] project: [$$53] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                      data-scan []<-[$$51, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-3/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-3/query1.plan
index 51d0004..9357e48 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-3/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-3/query1.plan
@@ -1,11 +1,22 @@
+distribute result [$$29] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"business_id": $$33}] project: [$$29] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26", $$D.getField(0))) project: [$$33] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$31) project: [$$33, $$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$33, $$31] <- [$$C.getField(1), $$C.getField(2)] project: [$$33, $$31] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                data-scan []<-[$$30, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-3/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-3/query2.plan
index a2530d6..3cb4957 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-3/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-3/query2.plan
@@ -1,15 +1,30 @@
+distribute result [$$51] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$51] <- [{"$1": $$54}] project: [$$51] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$54] <- [agg-sql-sum($$56)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$56] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$52, "2016"), lt($$52, "2017"))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$52] <- [$$D.getField(0)] project: [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                unnest $$D <- scan-collection($$55) project: [$$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- UNNEST  |PARTITIONED|
+                  assign [$$55] <- [$$C.getField(2)] project: [$$55] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                        data-scan []<-[$$53, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-3/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-3/query3.plan
index 51d0004..7777677 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-3/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-3/query3.plan
@@ -1,11 +1,22 @@
+distribute result [$$32] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"business_id": $$37}] project: [$$32] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq("2016-04-26", $$D.getField(0)), eq($$D.getField(1), "19:49:16"))) project: [$$37] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$34) project: [$$37, $$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$37, $$34] <- [$$C.getField(1), $$C.getField(2)] project: [$$37, $$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                data-scan []<-[$$33, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-4/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-4/query1.plan
index e1cb4ae..5ceae18 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-4/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-4/query1.plan
@@ -1,13 +1,26 @@
+distribute result [$$40] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$40] <- [{"business_id": $$44}] project: [$$40] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26", $$D)) project: [$$44] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$43) project: [$$44, $$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$43] <- [$$CT.getField(0)] project: [$$44, $$43] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            unnest $$CT <- scan-collection($$42) project: [$$44, $$CT] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- UNNEST  |PARTITIONED|
+              assign [$$44, $$42] <- [$$C.getField(1), $$C.getField(2)] project: [$$44, $$42] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                    data-scan []<-[$$41, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-4/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-4/query2.plan
index 0f29817..2d91b95 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-4/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/use-case-4/query2.plan
@@ -1,16 +1,32 @@
+distribute result [$$61] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$61] <- [{"$1": $$63}] project: [$$61] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$63] <- [agg-sql-sum($$66)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$66] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017"))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$65) project: [$$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- UNNEST  |PARTITIONED|
+                assign [$$65] <- [$$CT.getField(0)] project: [$$65] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  unnest $$CT <- scan-collection($$64) project: [$$CT] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- UNNEST  |PARTITIONED|
+                    assign [$$64] <- [$$C.getField(2)] project: [$$64] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                          data-scan []<-[$$62, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-3-level-record-path/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-3-level-record-path/query1.plan
index 51d0004..c3ce341 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-3-level-record-path/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-3-level-record-path/query1.plan
@@ -1,11 +1,22 @@
+distribute result [$$31] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"business_id": $$34}] project: [$$31] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26", $$D)) project: [$$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$33) project: [$$34, $$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$33, $$34] <- [$$C.getField(2).getField(0).getField(0).getField(0), $$C.getField(1)] project: [$$33, $$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                data-scan []<-[$$32, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-3-level-record-path/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-3-level-record-path/query2.plan
index 1ff305e..18af69b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-3-level-record-path/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-3-level-record-path/query2.plan
@@ -1,14 +1,28 @@
+distribute result [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$52] <- [{"$1": $$54}] project: [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$54] <- [agg-sql-sum($$59)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$59] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017"))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$55) project: [$$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- UNNEST  |PARTITIONED|
+                assign [$$55] <- [$$C.getField(2).getField(0).getField(0).getField(0)] project: [$$55] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                      data-scan []<-[$$53, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-composite-pk/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-composite-pk/query1.plan
index 51d0004..0591caa 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-composite-pk/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-composite-pk/query1.plan
@@ -1,11 +1,22 @@
+distribute result [$$28] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$28] <- [{"business_id": $$30}] project: [$$28] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26 19:49:16", $$D)) project: [$$30] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$31) project: [$$30, $$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$31] <- [$$C.getField(2)] project: [$$30, $$31] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$30, $$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                data-scan []<-[$$29, $$30, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-composite-pk/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-composite-pk/query2.plan
index 1ff305e..4ea9367 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-composite-pk/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-composite-pk/query2.plan
@@ -1,14 +1,28 @@
+distribute result [$$49] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$49] <- [{"$1": $$52}] project: [$$49] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$52] <- [agg-sql-sum($$54)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$54] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017"))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$53) project: [$$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- UNNEST  |PARTITIONED|
+                assign [$$53] <- [$$C.getField(2)] project: [$$53] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                      data-scan []<-[$$50, $$51, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-composite-sk/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-composite-sk/query1.plan
index be29177..dadeb3c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-composite-sk/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-composite-sk/query1.plan
@@ -1,12 +1,24 @@
+distribute result [$$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"business_id": $$35}] project: [$$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq("2016-04-26", $$D.getField(0)), eq("19:49:16", $$D.getField(1)))) project: [$$35] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$37) project: [$$35, $$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          select (eq("--1UhMGODdWsrMastO9DZw", $$35))
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$35, $$37] <- [$$C.getField(1), $$C.getField(2)] project: [$$35, $$37] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                  data-scan []<-[$$36, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-composite-sk/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-composite-sk/query2.plan
index a2530d6..3cb4957 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-composite-sk/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-composite-sk/query2.plan
@@ -1,15 +1,30 @@
+distribute result [$$51] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$51] <- [{"$1": $$54}] project: [$$51] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$54] <- [agg-sql-sum($$56)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$56] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$52, "2016"), lt($$52, "2017"))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$52] <- [$$D.getField(0)] project: [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                unnest $$D <- scan-collection($$55) project: [$$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- UNNEST  |PARTITIONED|
+                  assign [$$55] <- [$$C.getField(2)] project: [$$55] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                        data-scan []<-[$$53, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-filter-fields/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-filter-fields/query1.plan
index 504456d..066fdd1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-filter-fields/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-filter-fields/query1.plan
@@ -1,13 +1,26 @@
+distribute result [$$31] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"business_id": $$32}] project: [$$31] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26 19:49:16", $$D)) project: [$$32] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$34) project: [$$32, $$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          select (eq($$32, "--1UhMGODdWsrMastO9DZw"))
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$32, $$34] <- [$$C.getField(1), $$C.getField(2)] project: [$$32, $$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                  data-scan []<-[$$33, $$C] <- TestYelp.YelpCheckin with filter on min:[$$35] max:[$$35] [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                      assign [$$35] <- ["--1UhMGODdWsrMastO9DZw"]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-filter-fields/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-filter-fields/query2.plan
index 1ff305e..efb8412 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-filter-fields/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/closed/with-filter-fields/query2.plan
@@ -1,14 +1,28 @@
+distribute result [$$49] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$49] <- [{"$1": $$51}] project: [$$49] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$51] <- [agg-sql-sum($$53)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$53] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017"))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$52) project: [$$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- UNNEST  |PARTITIONED|
+                assign [$$52] <- [$$C.getField(2)] project: [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                      data-scan []<-[$$50, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query1.plan
index 9e0c394..3185b1b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query1.plan
@@ -1,11 +1,22 @@
+distribute result [$$29] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"D": $$D, "F": $$F}] project: [$$29] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$F.getField("open_field_3a"), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$F <- scan-collection($$31) project: [$$D, $$F] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$31] <- [$$D.getField("open_field_1").getField("open_field_2")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$D]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (TestDataverse.TestDataset)  |PARTITIONED|
+                data-scan []<-[$$30, $$D] <- TestDataverse.TestDataset [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query2.plan
index 9e0c394..e783c4d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query2.plan
@@ -1,11 +1,22 @@
+distribute result [$$30] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$30] <- [{"D": $$D, "F": $$F}] project: [$$30] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$F.getField("open_field_3b").getField("open_field_4"), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$F <- scan-collection($$32) project: [$$D, $$F] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$32] <- [$$D.getField("open_field_1").getField("open_field_2")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$D]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (TestDataverse.TestDataset)  |PARTITIONED|
+                data-scan []<-[$$31, $$D] <- TestDataverse.TestDataset [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query3.plan
index aa33226..9c84f27 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query3.plan
@@ -1,13 +1,26 @@
+distribute result [$$41] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$41] <- [{"D": $$D, "F1": $$F1, "F2": $$F2}] project: [$$41] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$F2, 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$F2 <- scan-collection($$44) project: [$$D, $$F1, $$F2] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$44] <- [$$F1.getField("open_field_3c").getField("open_field_4a")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            unnest $$F1 <- scan-collection($$43) project: [$$D, $$F1] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- UNNEST  |PARTITIONED|
+              assign [$$43] <- [$$D.getField("open_field_1").getField("open_field_2")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$D]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (TestDataverse.TestDataset)  |PARTITIONED|
+                    data-scan []<-[$$42, $$D] <- TestDataverse.TestDataset [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query4.plan
index aa33226..7c73644 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query4.plan
@@ -1,13 +1,26 @@
+distribute result [$$42] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$42] <- [{"D": $$D, "F1": $$F1, "F2": $$F2}] project: [$$42] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$F2.getField("open_field_5"), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$F2 <- scan-collection($$45) project: [$$D, $$F1, $$F2] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$45] <- [$$F1.getField("open_field_3c").getField("open_field_4b")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            unnest $$F1 <- scan-collection($$44) project: [$$D, $$F1] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- UNNEST  |PARTITIONED|
+              assign [$$44] <- [$$D.getField("open_field_1").getField("open_field_2")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$D]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (TestDataverse.TestDataset)  |PARTITIONED|
+                    data-scan []<-[$$43, $$D] <- TestDataverse.TestDataset [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query5.plan
index 9e0c394..a23c604 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query5.plan
@@ -1,11 +1,22 @@
+distribute result [$$29] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"D": $$D, "F": $$F}] project: [$$29] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$F.getField("open_field_3a"), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$F <- scan-collection($$31) project: [$$D, $$F] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$31] <- [$$D.getField(1).getField("open_field_2")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$D]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (TestDataverse.TestDataset)  |PARTITIONED|
+                data-scan []<-[$$30, $$D] <- TestDataverse.TestDataset [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query6.plan
index 9e0c394..491f342 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query6.plan
@@ -1,11 +1,22 @@
+distribute result [$$30] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$30] <- [{"D": $$D, "F": $$F}] project: [$$30] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$F.getField("open_field_3b").getField("open_field_4"), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$F <- scan-collection($$32) project: [$$D, $$F] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$32] <- [$$D.getField(1).getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$D]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (TestDataverse.TestDataset)  |PARTITIONED|
+                data-scan []<-[$$31, $$D] <- TestDataverse.TestDataset [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query7.plan
index aa33226..28346e8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query7.plan
@@ -1,13 +1,26 @@
+distribute result [$$41] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$41] <- [{"D": $$D, "F1": $$F1, "F2": $$F2}] project: [$$41] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$F2, 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$F2 <- scan-collection($$44) project: [$$D, $$F1, $$F2] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$44] <- [$$F1.getField(0).getField("open_field_4a")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            unnest $$F1 <- scan-collection($$43) project: [$$D, $$F1] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- UNNEST  |PARTITIONED|
+              assign [$$43] <- [$$D.getField(1).getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$D]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (TestDataverse.TestDataset)  |PARTITIONED|
+                    data-scan []<-[$$42, $$D] <- TestDataverse.TestDataset [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query8.plan
index aa33226..2fce4f9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/complex-structures/query8.plan
@@ -1,13 +1,26 @@
+distribute result [$$42] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$42] <- [{"D": $$D, "F1": $$F1, "F2": $$F2}] project: [$$42] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (gt($$F2.getField("open_field_5"), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$F2 <- scan-collection($$45) project: [$$D, $$F1, $$F2] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$45] <- [$$F1.getField(0).getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            unnest $$F1 <- scan-collection($$44) project: [$$D, $$F1] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- UNNEST  |PARTITIONED|
+              assign [$$44] <- [$$D.getField(1).getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$D]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (TestDataverse.TestDataset)  |PARTITIONED|
+                    data-scan []<-[$$43, $$D] <- TestDataverse.TestDataset [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/multiple-indexes/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/multiple-indexes/query1.plan
index 0df8d5a..4e3f6dc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/multiple-indexes/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/multiple-indexes/query1.plan
@@ -1,11 +1,22 @@
+distribute result [$$31] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"k": $$k, "v": $$v}] project: [$$31] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq($$v.getField("a"), 284), eq($$v.getField("b"), 263))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$v <- scan-collection($$33) project: [$$k, $$v] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$33] <- [$$k.getField("uarr_i")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$k]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.KSI)  |PARTITIONED|
+                data-scan []<-[$$32, $$k] <- test.KSI [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/multiple-indexes/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/multiple-indexes/query2.plan
index 0df8d5a..1ed6aac 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/multiple-indexes/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/multiple-indexes/query2.plan
@@ -1,11 +1,22 @@
+distribute result [$$33] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"k": $$k, "v": $$v}] project: [$$33] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq($$v.getField("a"), 284), eq($$v.getField("b"), 263), eq($$v.getField("c"), 123))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$v <- scan-collection($$35) project: [$$k, $$v] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$35] <- [$$k.getField("uarr_i")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$k]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.KSI)  |PARTITIONED|
+                data-scan []<-[$$34, $$k] <- test.KSI [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-1/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-1/query1.plan
index 51d0004..da21fcc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-1/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-1/query1.plan
@@ -1,11 +1,22 @@
+distribute result [$$28] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$28] <- [{"business_id": $$31}] project: [$$28] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26 19:49:16", $$D)) project: [$$31] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$30) project: [$$31, $$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$31, $$30] <- [$$C.getField("business_id"), $$C.getField("dates")] project: [$$31, $$30] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                data-scan []<-[$$29, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-1/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-1/query2.plan
index 1ff305e..6c53c7f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-1/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-1/query2.plan
@@ -1,14 +1,28 @@
+distribute result [$$49] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$49] <- [{"$1": $$51}] project: [$$49] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$51] <- [agg-sql-sum($$53)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$53] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017"))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$52) project: [$$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- UNNEST  |PARTITIONED|
+                assign [$$52] <- [$$C.getField("dates")] project: [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                      data-scan []<-[$$50, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-2/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-2/query1.plan
index 51d0004..4794f4e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-2/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-2/query1.plan
@@ -1,11 +1,22 @@
+distribute result [$$29] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"business_id": $$32}] project: [$$29] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26", $$D)) project: [$$32] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$31) project: [$$32, $$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$31, $$32] <- [$$C.getField("checkin_times").getField("dates"), $$C.getField("business_id")] project: [$$31, $$32] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                data-scan []<-[$$30, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-2/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-2/query2.plan
index 1ff305e..9be26a3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-2/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-2/query2.plan
@@ -1,14 +1,28 @@
+distribute result [$$50] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$50] <- [{"$1": $$52}] project: [$$50] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$52] <- [agg-sql-sum($$55)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$55] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017"))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$53) project: [$$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- UNNEST  |PARTITIONED|
+                assign [$$53] <- [$$C.getField("checkin_times").getField("dates")] project: [$$53] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                      data-scan []<-[$$51, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-3/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-3/query1.plan
index 51d0004..7c577b0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-3/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-3/query1.plan
@@ -1,11 +1,22 @@
+distribute result [$$29] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"business_id": $$33}] project: [$$29] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26", $$D.getField("date"))) project: [$$33] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$31) project: [$$33, $$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$33, $$31] <- [$$C.getField("business_id"), $$C.getField("checkin_times")] project: [$$33, $$31] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                data-scan []<-[$$30, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-3/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-3/query2.plan
index a2530d6..81192d2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-3/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-3/query2.plan
@@ -1,15 +1,30 @@
+distribute result [$$51] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$51] <- [{"$1": $$54}] project: [$$51] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$54] <- [agg-sql-sum($$56)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$56] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$52, "2016"), lt($$52, "2017"))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$52] <- [$$D.getField("date")] project: [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                unnest $$D <- scan-collection($$55) project: [$$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- UNNEST  |PARTITIONED|
+                  assign [$$55] <- [$$C.getField("checkin_times")] project: [$$55] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                        data-scan []<-[$$53, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-3/query3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-3/query3.plan
index 51d0004..1187d50 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-3/query3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-3/query3.plan
@@ -1,11 +1,22 @@
+distribute result [$$32] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"business_id": $$37}] project: [$$32] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq("2016-04-26", $$D.getField("date")), eq($$D.getField("time"), "19:49:16"))) project: [$$37] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$34) project: [$$37, $$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$37, $$34] <- [$$C.getField("business_id"), $$C.getField("checkin_times")] project: [$$37, $$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                data-scan []<-[$$33, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-4/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-4/query1.plan
index e1cb4ae..5b6c891 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-4/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-4/query1.plan
@@ -1,13 +1,26 @@
+distribute result [$$40] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$40] <- [{"business_id": $$44}] project: [$$40] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26", $$D)) project: [$$44] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$43) project: [$$44, $$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$43] <- [$$CT.getField("dates")] project: [$$44, $$43] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            unnest $$CT <- scan-collection($$42) project: [$$44, $$CT] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- UNNEST  |PARTITIONED|
+              assign [$$44, $$42] <- [$$C.getField("business_id"), $$C.getField("checkin_times")] project: [$$44, $$42] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                    data-scan []<-[$$41, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-4/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-4/query2.plan
index 0f29817..c427714 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-4/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/use-case-4/query2.plan
@@ -1,16 +1,32 @@
+distribute result [$$61] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$61] <- [{"$1": $$63}] project: [$$61] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$63] <- [agg-sql-sum($$66)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$66] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017"))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$65) project: [$$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- UNNEST  |PARTITIONED|
+                assign [$$65] <- [$$CT.getField("dates")] project: [$$65] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  unnest $$CT <- scan-collection($$64) project: [$$CT] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- UNNEST  |PARTITIONED|
+                    assign [$$64] <- [$$C.getField("checkin_times")] project: [$$64] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                          data-scan []<-[$$62, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/with-3-level-record-path/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/with-3-level-record-path/query1.plan
index 51d0004..10416a5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/with-3-level-record-path/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/with-3-level-record-path/query1.plan
@@ -1,11 +1,22 @@
+distribute result [$$31] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$31] <- [{"business_id": $$34}] project: [$$31] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq("2016-04-26", $$D)) project: [$$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$33) project: [$$34, $$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          assign [$$33, $$34] <- [$$C.getField("checkin_data").getField("checkin_temporal").getField("checkin_times").getField("dates"), $$C.getField("business_id")] project: [$$33, $$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                data-scan []<-[$$32, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/with-3-level-record-path/query2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/with-3-level-record-path/query2.plan
index 1ff305e..7722c45 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/with-3-level-record-path/query2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/with-3-level-record-path/query2.plan
@@ -1,14 +1,28 @@
+distribute result [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$52] <- [{"$1": $$54}] project: [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$54] <- [agg-sql-sum($$59)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$59] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (and(gt($$D, "2016"), lt($$D, "2017"))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              unnest $$D <- scan-collection($$55) project: [$$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- UNNEST  |PARTITIONED|
+                assign [$$55] <- [$$C.getField("checkin_data").getField("checkin_temporal").getField("checkin_times").getField("dates")] project: [$$55] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                      data-scan []<-[$$53, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/with-composite-sk/query1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/with-composite-sk/query1.plan
index be29177..09224ff 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/with-composite-sk/query1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/array-index/select-unnest-queries/open/with-composite-sk/query1.plan
@@ -1,12 +1,24 @@
+distribute result [$$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$34] <- [{"business_id": $$35}] project: [$$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (and(eq("2016-04-26", $$D.getField("date")), eq("19:49:16", $$D.getField("time")))) project: [$$35] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        unnest $$D <- scan-collection($$37) project: [$$35, $$D] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- UNNEST  |PARTITIONED|
+          select (eq("--1UhMGODdWsrMastO9DZw", $$35))
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$35, $$37] <- [$$C.getField("business_id"), $$C.getField("checkin_times")] project: [$$35, $$37] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              project ([$$C]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (TestYelp.YelpCheckin)  |PARTITIONED|
+                  data-scan []<-[$$36, $$C] <- TestYelp.YelpCheckin [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-3.plan
index 4e9bc29..e4f8c82 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-3.plan
@@ -1,23 +1,46 @@
+distribute result [$$39] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
   -- SORT_MERGE_EXCHANGE [$$39(ASC) ]  |PARTITIONED|
+    order (ASC, $$39) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
     -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$36, $$tenk2.getField(7))) project: [$$39] [cardinality: 5.0E11, op-cost: 5.00004E11, total-cost: 5.00009E11]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$39] <- [$$tenk2.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$36, $$tenk2]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk2.tenk2)  |PARTITIONED|
+                unnest-map [$$35, $$tenk2] <- index-search("tenk2", 0, "Default", "test", "tenk2", true, false, 1, $$45, 1, $$45, true, true, true) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$45)
                     -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$36, $$45])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk2.idx_tenk2_1k_2k)  |PARTITIONED|
+                            unnest-map [$$43, $$44, $$45] <- index-search("idx_tenk2_1k_2k", 0, "Default", "test", "tenk2", true, true, 1, $$36, 1, $$36, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$36] <- [$$tenk1.getField(7)] project: [$$36]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$tenk1])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.tenk1.tenk1)  |PARTITIONED|
+                                      unnest-map [$$34, $$tenk1] <- index-search("tenk1", 0, "Default", "test", "tenk1", false, false, 0, 1, $$40, true, false, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$40] <- [1]
                                           -- ASSIGN  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-4.plan
index acfe0c3..c68f8b4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-4.plan
@@ -1,22 +1,44 @@
+distribute result [$$39] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
   -- SORT_MERGE_EXCHANGE [$$39(ASC) ]  |PARTITIONED|
+    order (ASC, $$39) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
     -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        project ([$$39]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$36, $$37)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
             -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
               -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                assign [$$36] <- [$$tenk1.getField(7)] project: [$$36] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.tenk1.tenk1)  |PARTITIONED|
+                      unnest-map [$$34, $$tenk1] <- index-search("tenk1", 0, "Default", "test", "tenk1", false, false, 0, 1, $$40, true, false, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$40] <- [1]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
               -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                assign [$$39, $$37] <- [$$tenk2.getField(0), $$tenk2.getField(7)] project: [$$39, $$37] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk2]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.tenk2)  |PARTITIONED|
+                      data-scan []<-[$$35, $$tenk2] <- test.tenk2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-5.plan
new file mode 100644
index 0000000..c68f8b4
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-5.plan
@@ -0,0 +1,44 @@
+distribute result [$$39] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
+  -- SORT_MERGE_EXCHANGE [$$39(ASC) ]  |PARTITIONED|
+    order (ASC, $$39) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
+    -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
+      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        project ([$$39]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
+        -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$36, $$37)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
+            -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
+              -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                assign [$$36] <- [$$tenk1.getField(7)] project: [$$36] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+                -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      unnest-map [$$34, $$tenk1] <- index-search("tenk1", 0, "Default", "test", "tenk1", false, false, 0, 1, $$40, true, false, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$40] <- [1]
+                          -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
+                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
+              -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                assign [$$39, $$37] <- [$$tenk2.getField(0), $$tenk2.getField(7)] project: [$$39, $$37] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+                -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk2]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      data-scan []<-[$$35, $$tenk2] <- test.tenk2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
+                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-6.plan
index 2b707e9..b4f6c25 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-6.plan
@@ -1,22 +1,44 @@
+distribute result [$$39] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
   -- SORT_MERGE_EXCHANGE [$$39(ASC) ]  |PARTITIONED|
+    order (ASC, $$39) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
     -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        project ([$$39]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$36, $$37)) [cardinality: 5.0E11, op-cost: 5.00004E11, total-cost: 5.00009E11]
             -- HYBRID_HASH_JOIN [$$37][$$36]  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
               -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                assign [$$39, $$37] <- [$$tenk2.getField(0), $$tenk2.getField(7)] project: [$$39, $$37] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk2]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.tenk2)  |PARTITIONED|
+                      data-scan []<-[$$35, $$tenk2] <- test.tenk2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                assign [$$36] <- [$$tenk1.getField(7)] project: [$$36] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.tenk1.tenk1)  |PARTITIONED|
+                      unnest-map [$$34, $$tenk1] <- index-search("tenk1", 0, "Default", "test", "tenk1", false, false, 0, 1, $$40, true, false, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$40] <- [1]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-7.plan
new file mode 100644
index 0000000..be39ae6
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/hints-indexnl-params/hints-indexnl-params-7.plan
@@ -0,0 +1,44 @@
+distribute result [$$39] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
+  -- SORT_MERGE_EXCHANGE [$$39(ASC) ]  |PARTITIONED|
+    order (ASC, $$39) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
+    -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
+      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        project ([$$39]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
+        -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$36, $$37)) [cardinality: 5.0E11, op-cost: 5.00004E11, total-cost: 5.00009E11]
+            -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
+              -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                assign [$$36] <- [$$tenk1.getField(7)] project: [$$36] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+                -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      unnest-map [$$34, $$tenk1] <- index-search("tenk1", 0, "Default", "test", "tenk1", false, false, 0, 1, $$40, true, false, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$40] <- [1]
+                          -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
+                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+              -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                assign [$$39, $$37] <- [$$tenk2.getField(0), $$tenk2.getField(7)] project: [$$39, $$37] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+                -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk2]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      data-scan []<-[$$35, $$tenk2] <- test.tenk2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
+                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/secondary-equi-join_04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/secondary-equi-join_04.plan
index 04756e9..bd6de74 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/secondary-equi-join_04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-join/secondary-equi-join_04.plan
@@ -1,31 +1,62 @@
+distribute result [$$44] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.000018E12]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.000018E12]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"a": $$a, "b": $$b, "c": $$c}] project: [$$44] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.000018E12]
     -- ASSIGN  |PARTITIONED|
+      project ([$$b, $$c, $$a]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.000018E12]
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.000018E12]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$49, $$45)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 1.000018E12]
           -- HYBRID_HASH_JOIN [$$45][$$49]  |PARTITIONED|
+            exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              select (eq($$45, $$c.getField(1))) [cardinality: 5.0E11, op-cost: 5.00004E11, total-cost: 5.00009E11]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$b, $$45, $$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- BTREE_SEARCH (test.testdst3.testdst3)  |PARTITIONED|
+                    unnest-map [$$48, $$c] <- index-search("testdst3", 0, "Default", "test", "testdst3", true, false, 1, $$52, 1, $$52, true, true, true) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- BTREE_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$52)
                         -- STABLE_SORT [$$52(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$b, $$45, $$52])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.testdst3.sec3_Idx)  |PARTITIONED|
+                                unnest-map [$$51, $$52] <- index-search("sec3_Idx", 0, "Default", "test", "testdst3", true, true, 1, $$45, 1, $$45, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$45] <- [$$b.getField(1)]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$b])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.testdst2)  |PARTITIONED|
+                                          data-scan []<-[$$47, $$b] <- test.testdst2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
             -- BROADCAST_EXCHANGE  |PARTITIONED|
+              assign [$$49] <- [$$a.getField(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$a]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+                    data-scan []<-[$$46, $$a] <- test.testdst [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/btree-index-composite-key-04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/btree-index-composite-key-04.plan
index b32ef1c..39beb27 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/btree-index-composite-key-04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/btree-index-composite-key-04.plan
@@ -1,12 +1,24 @@
+distribute result [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"id": $$22, "fname": $$21, "lname": $$25}] project: [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$22(ASC) ]  |PARTITIONED|
+        order (ASC, $$22) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$21, "A")) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25, $$21] <- [$$employee.getField(2), $$employee.getField(1)] project: [$$22, $$25, $$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.employee)  |PARTITIONED|
+                  data-scan []<-[$$22, $$employee] <- test.employee [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-02.plan
index 311e202..9e79341 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-02.plan
@@ -1,12 +1,24 @@
+distribute result [$$58] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$58] <- [{"id": $$61, "x": $$72, "y": int64-default-null($$64)}] project: [$$58] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$61(ASC) ]  |PARTITIONED|
+        order (ASC, $$61) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$61(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (le($$72, 1)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$72, $$64] <- [int64-default-null($$ds2.getField("x")), $$ds2.getField("y")] project: [$$61, $$72, $$64] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds2)  |PARTITIONED|
+                  data-scan []<-[$$61, $$ds2] <- test.ds2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-10.plan
index 9e04d8e..d021e2a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-10.plan
@@ -1,12 +1,24 @@
+distribute result [$$44] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"id": $$50, "f_dt_fmt": $$59}] project: [$$44] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
+        order (ASC, $$50) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$59, datetime: { 2020-12-20T00:00:00.000 })) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$59] <- [datetime-default-null($$ds5.getField("f_dt_fmt"), "MM/DD/YYYY hh:mm:ss.nnna")] project: [$$50, $$59] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds5)  |PARTITIONED|
+                  data-scan []<-[$$50, $$ds5] <- test.ds5 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-11.plan
index 9e04d8e..7c53d8c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-11.plan
@@ -1,12 +1,24 @@
+distribute result [$$44] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"id": $$50, "f_d_fmt": $$59}] project: [$$44] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
+        order (ASC, $$50) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$59, date: { 2020-12-20 })) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$59] <- [date-default-null($$ds5.getField("f_d_fmt"), "MM/DD/YYYY")] project: [$$50, $$59] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds5)  |PARTITIONED|
+                  data-scan []<-[$$50, $$ds5] <- test.ds5 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-12.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-12.plan
index 9e04d8e..7f15fd1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-12.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-12.plan
@@ -1,12 +1,24 @@
+distribute result [$$44] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"id": $$50, "f_t_fmt": $$59}] project: [$$44] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
+        order (ASC, $$50) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$59, time: { 18:13:03.000 })) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$59] <- [time-default-null($$ds5.getField("f_t_fmt"), "hh:mm:ss.nnna")] project: [$$50, $$59] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds5)  |PARTITIONED|
+                  data-scan []<-[$$50, $$ds5] <- test.ds5 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-13.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-13.plan
index c488edd..fc7b5e7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-13.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-13.plan
@@ -1,12 +1,24 @@
+distribute result [$$44] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"id": $$50, "f_dt": $$59}] project: [$$44] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
+        order (ASC, $$50) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$59, datetime: { 2020-12-20T00:00:00.000 })) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$59] <- [datetime-default-null($$ds6.getField("f_dt"))] project: [$$50, $$59] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds6)  |PARTITIONED|
+                  data-scan []<-[$$50, $$ds6] <- test.ds6 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-14.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-14.plan
index c488edd..e4f2cc7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-14.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-14.plan
@@ -1,12 +1,24 @@
+distribute result [$$44] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"id": $$50, "f_d": $$59}] project: [$$44] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
+        order (ASC, $$50) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$59, date: { 2020-12-20 })) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$59] <- [date-default-null($$ds6.getField("f_d"))] project: [$$50, $$59] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds6)  |PARTITIONED|
+                  data-scan []<-[$$50, $$ds6] <- test.ds6 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-15.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-15.plan
index c488edd..48e98d5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-15.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-15.plan
@@ -1,12 +1,24 @@
+distribute result [$$44] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$44] <- [{"id": $$50, "f_t": $$59}] project: [$$44] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
+        order (ASC, $$50) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$59, time: { 18:13:03.000 })) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$59] <- [time-default-null($$ds6.getField("f_t"))] project: [$$50, $$59] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds6)  |PARTITIONED|
+                  data-scan []<-[$$50, $$ds6] <- test.ds6 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-20.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-20.plan
index 161c4d4..7b8f9c3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-20.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-20.plan
@@ -1,12 +1,24 @@
+distribute result [$$57] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$57] <- [{"id": $$60, "s_f2": $$70}] project: [$$57] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$60(ASC) ]  |PARTITIONED|
+        order (ASC, $$60) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$70, "4")) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$70] <- [string-default-null($$ds7.getField(2))] project: [$$60, $$70] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds7)  |PARTITIONED|
+                  data-scan []<-[$$60, $$ds7] <- test.ds7 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-23.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-23.plan
index 161c4d4..bdb4bbe 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-23.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-23.plan
@@ -1,12 +1,24 @@
+distribute result [$$57] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$57] <- [{"id": $$60, "s_f2": $$70}] project: [$$57] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$60(ASC) ]  |PARTITIONED|
+        order (ASC, $$60) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$70, 4)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$70] <- [int64-default-null($$ds7.getField(2))] project: [$$60, $$70] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds7)  |PARTITIONED|
+                  data-scan []<-[$$60, $$ds7] <- test.ds7 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-24.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-24.plan
index 12e67c6..362376d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-24.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-24.plan
@@ -1,12 +1,24 @@
+distribute result [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$18] <- [{"id": $$21, "s_f2": $$20}] project: [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$20, "4")) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$20] <- [$$ds7.getField(2)] project: [$$21, $$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds7)  |PARTITIONED|
+                  data-scan []<-[$$21, $$ds7] <- test.ds7 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-25.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-25.plan
index 161c4d4..271758e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-25.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/cast-default-null/cast-default-null-25.plan
@@ -1,12 +1,24 @@
+distribute result [$$57] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$57] <- [{"id": $$60, "s_f2": $$62}] project: [$$57] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$60(ASC) ]  |PARTITIONED|
+        order (ASC, $$60) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$62, "4")) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$62] <- [$$ds7.getField(2)] project: [$$60, $$62] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.ds7)  |PARTITIONED|
+                  data-scan []<-[$$60, $$ds7] <- test.ds7 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/disjunctive-predicate/disjunctive-predicate-1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/disjunctive-predicate/disjunctive-predicate-1.plan
index 2ebdb2e..e01516f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/disjunctive-predicate/disjunctive-predicate-1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/disjunctive-predicate/disjunctive-predicate-1.plan
@@ -1,10 +1,20 @@
+distribute result [$$x]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$x])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BTREE_SEARCH (test.TestSet.TestSet)  |PARTITIONED|
+        unnest-map [$$21, $$x] <- index-search("TestSet", 0, "Default", "test", "TestSet", true, true, 1, $$22, 1, $$22, true, true, true)
+        -- BTREE_SEARCH  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$22)
             -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                unnest $$22 <- scan-collection(array: [ "one", "two" ])
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/disjunctive-predicate/disjunctive-predicate-2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/disjunctive-predicate/disjunctive-predicate-2.plan
index 642109c..6be8b2b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/disjunctive-predicate/disjunctive-predicate-2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/disjunctive-predicate/disjunctive-predicate-2.plan
@@ -1,15 +1,30 @@
+distribute result [$$x]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (eq($$22, $$x.getField(1))) project: [$$x]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$22, $$x])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.TestSet.TestSet)  |PARTITIONED|
+          unnest-map [$$21, $$x] <- index-search("TestSet", 0, "Default", "test", "TestSet", true, false, 1, $$24, 1, $$24, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$24)
               -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$22, $$24])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (test.TestSet.TestSetIndex)  |PARTITIONED|
+                      unnest-map [$$23, $$24] <- index-search("TestSetIndex", 0, "Default", "test", "TestSet", true, true, 1, $$22, 1, $$22, true, true, true)
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          unnest $$22 <- scan-collection(array: [ "one", "two" ])
                           -- UNNEST  |UNPARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-10.plan
index da99423..31aaea2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-10.plan
@@ -1,11 +1,22 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$18, $$tenk] <- test.tenk [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-11.plan
index 88609bd..51821ad 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-11.plan
@@ -1,17 +1,34 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        project ([$$24])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$23, $$21))
             -- HYBRID_HASH_JOIN [$$21][$$23]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$24, $$21] <- [$$tenk.getField(0), $$tenk.getField(7)] project: [$$24, $$21]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$tenk])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                      data-scan []<-[$$22, $$tenk] <- test.tenk
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                unnest $$23 <- scan-collection(array: [ 0, 1 ])
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-12.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-12.plan
index 82a6ab3..2ad3f5d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-12.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-12.plan
@@ -1,19 +1,38 @@
+distribute result [$$24]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24)
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$23, $$tenk.getField(7))) project: [$$24]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)]
           -- ASSIGN  |PARTITIONED|
+            project ([$$23, $$tenk])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$22, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", true, false, 1, $$28, 1, $$28, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$28)
                     -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$23, $$28])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                            unnest-map [$$26, $$27, $$28] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", true, true, 1, $$29, 1, $$29, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$29] <- [cast-lax($$23)]
                                 -- ASSIGN  |UNPARTITIONED|
+                                  unnest $$23 <- scan-collection(array: [ 0, 1 ])
                                   -- UNNEST  |UNPARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-13.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-13.plan
index da99423..31aaea2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-13.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-13.plan
@@ -1,11 +1,22 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$18, $$tenk] <- test.tenk [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-4.plan
index da99423..31aaea2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-4.plan
@@ -1,11 +1,22 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$18, $$tenk] <- test.tenk [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-6.plan
index fc75e19..7b22453 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-6.plan
@@ -1,11 +1,22 @@
+distribute result [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$21, $$tenk] <- test.tenk [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-7.plan
index fc75e19..7b22453 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-7.plan
@@ -1,11 +1,22 @@
+distribute result [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$21, $$tenk] <- test.tenk [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-8.plan
index fc75e19..7b22453 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-8.plan
@@ -1,11 +1,22 @@
+distribute result [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$21, $$tenk] <- test.tenk [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-9.plan
index da99423..31aaea2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-9.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-skip-index/hints-skip-index-9.plan
@@ -1,11 +1,22 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$18, $$tenk] <- test.tenk [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-10.plan
index da99423..31aaea2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-10.plan
@@ -1,11 +1,22 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$18, $$tenk] <- test.tenk [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-11.plan
index da99423..31aaea2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-11.plan
@@ -1,11 +1,22 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$18, $$tenk] <- test.tenk [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-12.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-12.plan
index fc75e19..a3104d1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-12.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-12.plan
@@ -1,11 +1,22 @@
+distribute result [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(9), 0))) project: [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$21, $$tenk] <- test.tenk [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-13.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-13.plan
index da99423..31aaea2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-13.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-13.plan
@@ -1,11 +1,22 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$18, $$tenk] <- test.tenk [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-14.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-14.plan
index da99423..f25b1e4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-14.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-14.plan
@@ -1,11 +1,22 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(8), 0)) project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$18, $$tenk] <- test.tenk [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-15.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-15.plan
index fc75e19..7b22453 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-15.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-15.plan
@@ -1,11 +1,22 @@
+distribute result [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$21, $$tenk] <- test.tenk [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-16.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-16.plan
index fc75e19..7b22453 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-16.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-16.plan
@@ -1,11 +1,22 @@
+distribute result [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$21, $$tenk] <- test.tenk [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-17.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-17.plan
index ad64bb8..26d08a6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-17.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-17.plan
@@ -1,18 +1,36 @@
+distribute result [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$29, 1, $$29, true, true, true) [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 4000000.0]
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$29)
                     -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$29])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                            unnest-map [$$27, $$28, $$29] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 1, $$25, 1, $$26, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$25, $$26] <- [0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-18.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-18.plan
index da99423..31aaea2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-18.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-18.plan
@@ -1,11 +1,22 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$18, $$tenk] <- test.tenk [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-19.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-19.plan
index da99423..31aaea2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-19.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-19.plan
@@ -1,11 +1,22 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.tenk)  |PARTITIONED|
+                data-scan []<-[$$18, $$tenk] <- test.tenk [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-3.plan
index cfff6e8..767b3bb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-3.plan
@@ -1,18 +1,36 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
   -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+    order (ASC, $$20) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
     -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (eq($$tenk.getField(7), 0)) project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$20] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$18, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$25, 1, $$25, true, true, true) [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 4000000.0]
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$25)
                     -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$25])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                            unnest-map [$$23, $$24, $$25] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 1, $$21, 1, $$22, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$21, $$22] <- [0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-4.plan
index 9a52414..87f98b1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-4.plan
@@ -1,35 +1,70 @@
+distribute result [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$33, 1, $$33, true, true, true) [cardinality: 1000000.0, op-cost: 6000000.0, total-cost: 6000000.0]
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    intersect [$$33] <- [[$$28], [$$32]]
                     -- INTERSECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$28)
                         -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$28])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_1k)  |PARTITIONED|
+                                unnest-map [$$27, $$28] <- index-search("idx_1k", 0, "Default", "test", "tenk", false, false, 1, $$25, 1, $$26, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$25, $$26] <- [$$29, $$30] project: [$$25, $$26]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$29, $$30] <- [0, 0]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$32)
                         -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$32])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_2k)  |PARTITIONED|
+                                unnest-map [$$31, $$32] <- index-search("idx_2k", 0, "Default", "test", "tenk", false, false, 1, $$29, 1, $$30, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$29, $$30] <- [0, 0]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-5.plan
index 5e57a22..8d7f326 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-5.plan
@@ -1,35 +1,70 @@
+distribute result [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(9), 0))) project: [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$35, 1, $$35, true, true, true) [cardinality: 1000000.0, op-cost: 6000000.0, total-cost: 6000000.0]
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    intersect [$$35] <- [[$$29], [$$34]]
                     -- INTERSECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$29)
                         -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$29])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                                unnest-map [$$27, $$28, $$29] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 1, $$25, 1, $$26, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$25, $$26] <- [$$30, $$31] project: [$$25, $$26]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$30, $$31] <- [0, 0]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$34)
                         -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$34])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_5k_10k)  |PARTITIONED|
+                                unnest-map [$$32, $$33, $$34] <- index-search("idx_5k_10k", 0, "Default", "test", "tenk", false, false, 1, $$30, 1, $$31, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$30, $$31] <- [0, 0]
                                         -- ASSIGN  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-7.plan
index 797e5fa..bb6f9da 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-7.plan
@@ -1,18 +1,36 @@
+distribute result [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 4000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$31, 1, $$31, true, true, true) [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 4000000.0]
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$31)
                     -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$31])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                            unnest-map [$$29, $$30, $$31] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 2, $$25, $$26, 2, $$27, $$28, true, true, true)
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$25, $$26, $$27, $$28] <- [0, 0, 0, 0]
                                 -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-8.plan
index e32ac40..0918221 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-8.plan
@@ -1,29 +1,58 @@
+distribute result [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$37, 1, $$37, true, true, true) [cardinality: 1000000.0, op-cost: 6000000.0, total-cost: 6000000.0]
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    intersect [$$37] <- [[$$31], [$$36]]
                     -- INTERSECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$31)
                         -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$31])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                                unnest-map [$$29, $$30, $$31] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 2, $$25, $$26, 2, $$27, $$28, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$25, $$26, $$27, $$28] <- [0, 0, 0, 0]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$36)
                         -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$36])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_2k_5k)  |PARTITIONED|
+                                unnest-map [$$34, $$35, $$36] <- index-search("idx_2k_5k", 0, "Default", "test", "tenk", false, false, 1, $$32, 1, $$33, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$32, $$33] <- [0, 0]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-9.plan
index e32ac40..0918221 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-9.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/hints-use-index/hints-use-index-9.plan
@@ -1,29 +1,58 @@
+distribute result [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
   -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+    order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
     -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        select (and(eq($$tenk.getField(7), 0), eq($$tenk.getField(8), 0))) project: [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
         -- STREAM_SELECT  |PARTITIONED|
+          assign [$$24] <- [$$tenk.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
           -- ASSIGN  |PARTITIONED|
+            project ([$$tenk]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                unnest-map [$$21, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 1, $$37, 1, $$37, true, true, true) [cardinality: 1000000.0, op-cost: 6000000.0, total-cost: 6000000.0]
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    intersect [$$37] <- [[$$31], [$$36]]
                     -- INTERSECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$31)
                         -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$31])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_1k_2k)  |PARTITIONED|
+                                unnest-map [$$29, $$30, $$31] <- index-search("idx_1k_2k", 0, "Default", "test", "tenk", false, false, 2, $$25, $$26, 2, $$27, $$28, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$25, $$26, $$27, $$28] <- [0, 0, 0, 0]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$36)
                         -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$36])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.idx_2k_5k)  |PARTITIONED|
+                                unnest-map [$$34, $$35, $$36] <- index-search("idx_2k_5k", 0, "Default", "test", "tenk", false, false, 1, $$32, 1, $$33, true, true, true)
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$32, $$33] <- [0, 0]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/intersection-misc/intersection-misc-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/intersection-misc/intersection-misc-01.plan
index 33ccc2e..cf06553 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/intersection-misc/intersection-misc-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/intersection-misc/intersection-misc-01.plan
@@ -1,96 +1,186 @@
+distribute result [$$125]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$125] <- [{"t1": $$95, "t2": $$t2, "t3": $$119}] project: [$$125]
     -- ASSIGN  |PARTITIONED|
+      project ([$$95, $$t2, $$119])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$142(ASC), $$132(ASC), $$144(ASC) ]  |PARTITIONED|
+          order (ASC, $$142) (ASC, $$132) (ASC, $$144)
           -- STABLE_SORT [$$142(ASC), $$132(ASC), $$144(ASC)]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$95, $$t2, $$119, $$142, $$132, $$144])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$137, $$144))
                   -- HYBRID_HASH_JOIN [$$137][$$144]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$137]  |PARTITIONED|
+                      project ([$$95, $$t2, $$142, $$132, $$137])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          join (eq($$142, $$136))
                           -- HYBRID_HASH_JOIN [$$142][$$136]  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- HASH_PARTITION_EXCHANGE [$$142]  |PARTITIONED|
+                              assign [$$95] <- [{"c3": $$142}] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ASSIGN  |PARTITIONED|
+                                select ($$89) project: [$$142]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  project ([$$89, $$142]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
-                                              {
+                                      group by ([$$149 := $$130]) decor ([$$142]) {
+                                                aggregate [$$89] <- [non-empty-stream()]
                                                 -- AGGREGATE  |LOCAL|
+                                                  select (not(is-missing($$148)))
                                                   -- STREAM_SELECT  |LOCAL|
+                                                    nested tuple source
                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                              }
+                                             } [cardinality: 0.0, op-cost: 0.0, total-cost: 1000000.0]
+                                      -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          order (ASC, $$130) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- STABLE_SORT [$$130(ASC)]  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- HASH_PARTITION_EXCHANGE [$$130]  |PARTITIONED|
+                                              project ([$$142, $$148, $$130]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  left outer join (eq($$139, $$85)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                   -- HYBRID_HASH_JOIN [$$139][$$85]  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- HASH_PARTITION_EXCHANGE [$$139]  |PARTITIONED|
+                                                      select (eq($$d.getField("c5"), 1)) project: [$$142, $$130, $$139] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        assign [$$142, $$139] <- [$$d.getField("c3"), $$d.getField("c1")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                             -- REPLICATE  |PARTITIONED|
+                                                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.d)  |PARTITIONED|
+                                                                data-scan []<-[$$130, $$d] <- test.d [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                                                          assign [$$148, $$85] <- [true, $$c.getField("c11")] project: [$$148, $$85]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            project ([$$c])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.c)  |PARTITIONED|
+                                                                data-scan []<-[$$131, $$c] <- test.c [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- HASH_PARTITION_EXCHANGE [$$136]  |PARTITIONED|
+                              assign [$$137, $$136] <- [$$t2.getField("c4"), $$t2.getField("c2")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ASSIGN  |PARTITIONED|
+                                assign [$$132, $$t2] <- [$$130, $$d] project: [$$132, $$t2] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.d)  |PARTITIONED|
+                                        data-scan []<-[$$130, $$d] <- test.d [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- HASH_PARTITION_EXCHANGE [$$144]  |PARTITIONED|
+                      assign [$$119] <- [{"c4": $$144}] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        select ($$108) project: [$$144]
                         -- STREAM_SELECT  |PARTITIONED|
+                          project ([$$108, $$144]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$133]  |PARTITIONED|
-                                      {
+                              group by ([$$151 := $$133]) decor ([$$144]) {
+                                        aggregate [$$108] <- [non-empty-stream()]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$150)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     } [cardinality: 0.0, op-cost: 0.0, total-cost: 1000000.0]
+                              -- PRE_CLUSTERED_GROUP_BY[$$133]  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$133) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- STABLE_SORT [$$133(ASC)]  |PARTITIONED|
+                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- HASH_PARTITION_EXCHANGE [$$133]  |PARTITIONED|
+                                      project ([$$144, $$150, $$133]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          left outer join (eq($$140, $$104)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                           -- HYBRID_HASH_JOIN [$$140][$$104]  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- HASH_PARTITION_EXCHANGE [$$140]  |PARTITIONED|
+                                              select (and(eq($$d.getField("c5"), 1), ge($$129, "2019-01-01"), le($$129, "2019-02-01"))) project: [$$144, $$133, $$140] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- STREAM_SELECT  |PARTITIONED|
+                                                assign [$$144, $$129, $$140] <- [$$d.getField("c4"), $$d.getField("c6"), $$d.getField("c1")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  assign [$$133, $$d] <- [$$130, $$d] project: [$$133, $$d] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.d)  |PARTITIONED|
+                                                          data-scan []<-[$$130, $$d] <- test.d [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$150, $$104] <- [$$148, $$85] project: [$$150, $$104]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  replicate
                                                   -- REPLICATE  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                                                      assign [$$148, $$85] <- [true, $$c.getField("c11")] project: [$$148, $$85]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$c])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.c)  |PARTITIONED|
+                                                            data-scan []<-[$$131, $$c] <- test.c [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/intersection-misc/intersection-misc-02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/intersection-misc/intersection-misc-02.plan
index 33ccc2e..cf06553 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/intersection-misc/intersection-misc-02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/intersection-misc/intersection-misc-02.plan
@@ -1,96 +1,186 @@
+distribute result [$$125]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$125] <- [{"t1": $$95, "t2": $$t2, "t3": $$119}] project: [$$125]
     -- ASSIGN  |PARTITIONED|
+      project ([$$95, $$t2, $$119])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$142(ASC), $$132(ASC), $$144(ASC) ]  |PARTITIONED|
+          order (ASC, $$142) (ASC, $$132) (ASC, $$144)
           -- STABLE_SORT [$$142(ASC), $$132(ASC), $$144(ASC)]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$95, $$t2, $$119, $$142, $$132, $$144])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$137, $$144))
                   -- HYBRID_HASH_JOIN [$$137][$$144]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$137]  |PARTITIONED|
+                      project ([$$95, $$t2, $$142, $$132, $$137])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          join (eq($$142, $$136))
                           -- HYBRID_HASH_JOIN [$$142][$$136]  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- HASH_PARTITION_EXCHANGE [$$142]  |PARTITIONED|
+                              assign [$$95] <- [{"c3": $$142}] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ASSIGN  |PARTITIONED|
+                                select ($$89) project: [$$142]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  project ([$$89, $$142]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
-                                              {
+                                      group by ([$$149 := $$130]) decor ([$$142]) {
+                                                aggregate [$$89] <- [non-empty-stream()]
                                                 -- AGGREGATE  |LOCAL|
+                                                  select (not(is-missing($$148)))
                                                   -- STREAM_SELECT  |LOCAL|
+                                                    nested tuple source
                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                              }
+                                             } [cardinality: 0.0, op-cost: 0.0, total-cost: 1000000.0]
+                                      -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          order (ASC, $$130) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- STABLE_SORT [$$130(ASC)]  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- HASH_PARTITION_EXCHANGE [$$130]  |PARTITIONED|
+                                              project ([$$142, $$148, $$130]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  left outer join (eq($$139, $$85)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                   -- HYBRID_HASH_JOIN [$$139][$$85]  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- HASH_PARTITION_EXCHANGE [$$139]  |PARTITIONED|
+                                                      select (eq($$d.getField("c5"), 1)) project: [$$142, $$130, $$139] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        assign [$$142, $$139] <- [$$d.getField("c3"), $$d.getField("c1")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                             -- REPLICATE  |PARTITIONED|
+                                                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.d)  |PARTITIONED|
+                                                                data-scan []<-[$$130, $$d] <- test.d [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                                                          assign [$$148, $$85] <- [true, $$c.getField("c11")] project: [$$148, $$85]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            project ([$$c])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.c)  |PARTITIONED|
+                                                                data-scan []<-[$$131, $$c] <- test.c [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- HASH_PARTITION_EXCHANGE [$$136]  |PARTITIONED|
+                              assign [$$137, $$136] <- [$$t2.getField("c4"), $$t2.getField("c2")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ASSIGN  |PARTITIONED|
+                                assign [$$132, $$t2] <- [$$130, $$d] project: [$$132, $$t2] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.d)  |PARTITIONED|
+                                        data-scan []<-[$$130, $$d] <- test.d [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- HASH_PARTITION_EXCHANGE [$$144]  |PARTITIONED|
+                      assign [$$119] <- [{"c4": $$144}] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        select ($$108) project: [$$144]
                         -- STREAM_SELECT  |PARTITIONED|
+                          project ([$$108, $$144]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$133]  |PARTITIONED|
-                                      {
+                              group by ([$$151 := $$133]) decor ([$$144]) {
+                                        aggregate [$$108] <- [non-empty-stream()]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$150)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     } [cardinality: 0.0, op-cost: 0.0, total-cost: 1000000.0]
+                              -- PRE_CLUSTERED_GROUP_BY[$$133]  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$133) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- STABLE_SORT [$$133(ASC)]  |PARTITIONED|
+                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- HASH_PARTITION_EXCHANGE [$$133]  |PARTITIONED|
+                                      project ([$$144, $$150, $$133]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          left outer join (eq($$140, $$104)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                           -- HYBRID_HASH_JOIN [$$140][$$104]  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- HASH_PARTITION_EXCHANGE [$$140]  |PARTITIONED|
+                                              select (and(eq($$d.getField("c5"), 1), ge($$129, "2019-01-01"), le($$129, "2019-02-01"))) project: [$$144, $$133, $$140] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- STREAM_SELECT  |PARTITIONED|
+                                                assign [$$144, $$129, $$140] <- [$$d.getField("c4"), $$d.getField("c6"), $$d.getField("c1")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  assign [$$133, $$d] <- [$$130, $$d] project: [$$133, $$d] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.d)  |PARTITIONED|
+                                                          data-scan []<-[$$130, $$d] <- test.d [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$150, $$104] <- [$$148, $$85] project: [$$150, $$104]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  replicate
                                                   -- REPLICATE  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                                                      assign [$$148, $$85] <- [true, $$c.getField("c11")] project: [$$148, $$85]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$c])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.c)  |PARTITIONED|
+                                                            data-scan []<-[$$131, $$c] <- test.c [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/intersection-misc/intersection-misc-03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/intersection-misc/intersection-misc-03.plan
index 33ccc2e..cf06553 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/intersection-misc/intersection-misc-03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index-selection/intersection-misc/intersection-misc-03.plan
@@ -1,96 +1,186 @@
+distribute result [$$125]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$125] <- [{"t1": $$95, "t2": $$t2, "t3": $$119}] project: [$$125]
     -- ASSIGN  |PARTITIONED|
+      project ([$$95, $$t2, $$119])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$142(ASC), $$132(ASC), $$144(ASC) ]  |PARTITIONED|
+          order (ASC, $$142) (ASC, $$132) (ASC, $$144)
           -- STABLE_SORT [$$142(ASC), $$132(ASC), $$144(ASC)]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$95, $$t2, $$119, $$142, $$132, $$144])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$137, $$144))
                   -- HYBRID_HASH_JOIN [$$137][$$144]  |PARTITIONED|
+                    exchange
                     -- HASH_PARTITION_EXCHANGE [$$137]  |PARTITIONED|
+                      project ([$$95, $$t2, $$142, $$132, $$137])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          join (eq($$142, $$136))
                           -- HYBRID_HASH_JOIN [$$142][$$136]  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- HASH_PARTITION_EXCHANGE [$$142]  |PARTITIONED|
+                              assign [$$95] <- [{"c3": $$142}] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ASSIGN  |PARTITIONED|
+                                select ($$89) project: [$$142]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  project ([$$89, $$142]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
-                                              {
+                                      group by ([$$149 := $$130]) decor ([$$142]) {
+                                                aggregate [$$89] <- [non-empty-stream()]
                                                 -- AGGREGATE  |LOCAL|
+                                                  select (not(is-missing($$148)))
                                                   -- STREAM_SELECT  |LOCAL|
+                                                    nested tuple source
                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                              }
+                                             } [cardinality: 0.0, op-cost: 0.0, total-cost: 1000000.0]
+                                      -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          order (ASC, $$130) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- STABLE_SORT [$$130(ASC)]  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- HASH_PARTITION_EXCHANGE [$$130]  |PARTITIONED|
+                                              project ([$$142, $$148, $$130]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  left outer join (eq($$139, $$85)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                   -- HYBRID_HASH_JOIN [$$139][$$85]  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- HASH_PARTITION_EXCHANGE [$$139]  |PARTITIONED|
+                                                      select (eq($$d.getField("c5"), 1)) project: [$$142, $$130, $$139] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        assign [$$142, $$139] <- [$$d.getField("c3"), $$d.getField("c1")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                             -- REPLICATE  |PARTITIONED|
+                                                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.d)  |PARTITIONED|
+                                                                data-scan []<-[$$130, $$d] <- test.d [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                                                          assign [$$148, $$85] <- [true, $$c.getField("c11")] project: [$$148, $$85]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            project ([$$c])
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.c)  |PARTITIONED|
+                                                                data-scan []<-[$$131, $$c] <- test.c [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- HASH_PARTITION_EXCHANGE [$$136]  |PARTITIONED|
+                              assign [$$137, $$136] <- [$$t2.getField("c4"), $$t2.getField("c2")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ASSIGN  |PARTITIONED|
+                                assign [$$132, $$t2] <- [$$130, $$d] project: [$$132, $$t2] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- REPLICATE  |PARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.d)  |PARTITIONED|
+                                        data-scan []<-[$$130, $$d] <- test.d [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- HASH_PARTITION_EXCHANGE [$$144]  |PARTITIONED|
+                      assign [$$119] <- [{"c4": $$144}] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        select ($$108) project: [$$144]
                         -- STREAM_SELECT  |PARTITIONED|
+                          project ([$$108, $$144]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$133]  |PARTITIONED|
-                                      {
+                              group by ([$$151 := $$133]) decor ([$$144]) {
+                                        aggregate [$$108] <- [non-empty-stream()]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$150)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     } [cardinality: 0.0, op-cost: 0.0, total-cost: 1000000.0]
+                              -- PRE_CLUSTERED_GROUP_BY[$$133]  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$133) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- STABLE_SORT [$$133(ASC)]  |PARTITIONED|
+                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- HASH_PARTITION_EXCHANGE [$$133]  |PARTITIONED|
+                                      project ([$$144, $$150, $$133]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          left outer join (eq($$140, $$104)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                           -- HYBRID_HASH_JOIN [$$140][$$104]  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- HASH_PARTITION_EXCHANGE [$$140]  |PARTITIONED|
+                                              select (and(eq($$d.getField("c5"), 1), ge($$129, "2019-01-01"), le($$129, "2019-02-01"))) project: [$$144, $$133, $$140] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- STREAM_SELECT  |PARTITIONED|
+                                                assign [$$144, $$129, $$140] <- [$$d.getField("c4"), $$d.getField("c6"), $$d.getField("c1")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  assign [$$133, $$d] <- [$$130, $$d] project: [$$133, $$d] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.d)  |PARTITIONED|
+                                                          data-scan []<-[$$130, $$d] <- test.d [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$150, $$104] <- [$$148, $$85] project: [$$150, $$104]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  replicate
                                                   -- REPLICATE  |PARTITIONED|
+                                                    exchange
                                                     -- HASH_PARTITION_EXCHANGE [$$85]  |PARTITIONED|
+                                                      assign [$$148, $$85] <- [true, $$c.getField("c11")] project: [$$148, $$85]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$c])
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.c)  |PARTITIONED|
+                                                            data-scan []<-[$$131, $$c] <- test.c [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-composite-key-03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-composite-key-03.plan
index e431bd0..2b77f25 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-composite-key-03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-composite-key-03.plan
@@ -1,8 +1,16 @@
+distribute result [$$l]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(eq($$l.getField(1), "Julio"), eq($$l.getField(2), "Isa")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$l])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.employee)  |PARTITIONED|
+          data-scan []<-[$$17, $$l] <- test.employee
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-33.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-33.plan
index 5454dab..cfdfb0d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-33.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-33.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (gt($$emp.getField(1), "Roger"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$14, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-34.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-34.plan
index 5454dab..c04d339 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-34.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-34.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (ge($$emp.getField(1), "Susan"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$14, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-35.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-35.plan
index 5454dab..8ee67da 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-35.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-35.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (lt($$emp.getField(1), "Isa"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$14, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-36.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-36.plan
index 5454dab..1f3784f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-36.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-36.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (le($$emp.getField(1), "Vanpatten"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$14, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-40.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-40.plan
index 5454dab..d083382 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-40.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-40.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(eq($$emp.getField(1), "Young Seok"), eq($$emp.getField(2), "Kim")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$17, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-42.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-42.plan
index 5454dab..abdc887 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-42.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-42.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(gt($$emp.getField(1), "Alex"), lt($$emp.getField(2), "Zach")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$17, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-43.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-43.plan
index 5454dab..0806a13 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-43.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-43.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(gt($$emp.getField(1), "Allan"), lt($$emp.getField(2), "Zubi")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$17, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-44.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-44.plan
index 5454dab..4562e83 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-44.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-44.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(gt($$emp.getField(1), "Allan"), eq($$emp.getField(2), "Xu")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$17, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-45.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-45.plan
index 5454dab..eef6382 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-45.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-45.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(eq($$emp.getField(1), "Julio"), lt($$emp.getField(2), "Xu")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$17, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-46.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-46.plan
index 5454dab..a6aea81 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-46.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-46.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(ge($$emp.getField(1), "Michael"), le($$emp.getField(2), "Xu")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$17, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-47.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-47.plan
index c823a61..f8005c6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-47.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-47.plan
@@ -1,9 +1,18 @@
+distribute result [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(lt($$22, "Tomes"), gt($$22, "Kevin"), gt($$23, "Craig"), lt($$23, "Mary"))) project: [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$23, $$22] <- [$$emp.getField(1), $$emp.getField(2)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+            data-scan []<-[$$24, $$emp] <- test.testdst [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-48.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-48.plan
index c823a61..664c771 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-48.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-48.plan
@@ -1,9 +1,18 @@
+distribute result [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(le($$22, "Tomes"), ge($$22, "Kevin"), ge($$23, "Craig"), le($$23, "Mary"))) project: [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$23, $$22] <- [$$emp.getField(1), $$emp.getField(2)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+            data-scan []<-[$$24, $$emp] <- test.testdst [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-49.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-49.plan
index 5454dab..030cf4c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-49.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-49.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(le($$emp.getField(1), "Craig"), gt($$emp.getField(2), "Kevin")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$17, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-51.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-51.plan
index c823a61..6bda173 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-51.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-51.plan
@@ -1,9 +1,18 @@
+distribute result [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(le($$22, "Tomes"), gt($$22, "Kevin"), gt($$23, "Craig"), le($$23, "Mary"))) project: [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$23, $$22] <- [$$emp.getField(1), $$emp.getField(2)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+            data-scan []<-[$$24, $$emp] <- test.testdst [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-52.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-52.plan
index c823a61..97b8bd5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-52.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-52.plan
@@ -1,9 +1,18 @@
+distribute result [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(lt($$22, "Tomes"), ge($$22, "Kevin"), ge($$23, "Craig"), lt($$23, "Mary"))) project: [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$23, $$22] <- [$$emp.getField(1), $$emp.getField(2)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+            data-scan []<-[$$24, $$emp] <- test.testdst [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-53.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-53.plan
index c823a61..da90edd 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-53.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-53.plan
@@ -1,9 +1,18 @@
+distribute result [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(ge($$22, "Tomes"), le($$22, "Kevin"), ge($$23, "Craig"), le($$23, "Mary"))) project: [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$23, $$22] <- [$$emp.getField(1), $$emp.getField(2)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+            data-scan []<-[$$24, $$emp] <- test.testdst [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-54.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-54.plan
index 5454dab..c012831 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-54.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-54.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (gt($$emp.getField(1), "Max"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$14, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-55.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-55.plan
index 5454dab..382e307 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-55.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-55.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (ge($$emp.getField(1), "Sofia"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$14, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-56.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-56.plan
index 5454dab..8866024 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-56.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-56.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (lt($$emp.getField(1), "Chen"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$14, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-57.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-57.plan
index 5454dab..fb119cc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-57.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-57.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (le($$emp.getField(1), "Julio"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$14, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-58.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-58.plan
index c823a61..2d33976 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-58.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-58.plan
@@ -1,9 +1,18 @@
+distribute result [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(gt($$18, "Neil"), lt($$18, "Roger"))) project: [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$18] <- [$$emp.getField(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+            data-scan []<-[$$19, $$emp] <- test.testdst [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-59.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-59.plan
index c823a61..e13e99a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-59.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-59.plan
@@ -1,9 +1,18 @@
+distribute result [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(ge($$18, "Max"), le($$18, "Roger"))) project: [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$18] <- [$$emp.getField(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+            data-scan []<-[$$19, $$emp] <- test.testdst [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-60.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-60.plan
index 5454dab..a6f2c2b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-60.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-60.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (eq($$emp.getField(1), "Max"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$14, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-61.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-61.plan
index c823a61..2884cc8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-61.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-61.plan
@@ -1,9 +1,18 @@
+distribute result [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(lt($$22, "Tomes"), gt($$22, "Kevin"), gt($$23, "Craig"), le($$23, "Mary"))) project: [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$23, $$22] <- [$$emp.getField(1), $$emp.getField(2)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+            data-scan []<-[$$24, $$emp] <- test.testdst [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-62.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-62.plan
index 5454dab..46bccca 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-62.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-62.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(eq($$emp.getField(1), "Julio"), gt($$emp.getField(2), "Xu")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$17, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-63.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-63.plan
index 5454dab..fcfb398 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-63.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-63.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(lt($$emp.getField(1), "Julio"), eq($$emp.getField(2), "Xu")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$17, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-68.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-68.plan
index 6c20ed9..aa610aa 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-68.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-68.plan
@@ -1,12 +1,24 @@
+distribute result [$$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$25] <- [{"o_custkey": $$28, "o_orderkey": $$29, "o_orderstatus": $$34}] project: [$$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$28(ASC), $$29(ASC) ]  |PARTITIONED|
+        order (ASC, $$28) (ASC, $$29) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$28(ASC), $$29(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(eq($$Orders.getField(5), "1-URGENT"), le($$28, 43), ge($$28, 40))) project: [$$28, $$29, $$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$34, $$28] <- [$$Orders.getField(2), $$Orders.getField(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                  data-scan []<-[$$29, $$Orders] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-68_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-68_ps.plan
index c5b79e8..7492a40 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-68_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-secondary-68_ps.plan
@@ -1,30 +1,60 @@
+distribute result [$$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$25] <- [{"o_custkey": $$28, "o_orderkey": $$29, "o_orderstatus": $$34}] project: [$$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$28) (ASC, $$29) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$28(ASC), $$29(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$28(ASC), $$29(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$38 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (and(eq($$Orders.getField(5), "1-URGENT"), le($$28, 43), ge($$28, 40))) project: [$$28, $$29, $$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$34, $$28] <- [$$Orders.getField(2), $$Orders.getField(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                          data-scan []<-[$$29, $$Orders] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$38] <- [agg-range-map($$35, $$36, $$37)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$35, $$36, $$37] <- [agg-local-sampling($$28, $$29), agg-null-writer($$28), agg-null-writer($$29)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$28, $$29])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- REPLICATE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (and(eq($$Orders.getField(5), "1-URGENT"), le($$28, 43), ge($$28, 40))) project: [$$28, $$29, $$34] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$34, $$28] <- [$$Orders.getField(2), $$Orders.getField(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                    data-scan []<-[$$29, $$Orders] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-01-disable-idxonly.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-01-disable-idxonly.plan
index 6dc1292..eb43e83 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-01-disable-idxonly.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-01-disable-idxonly.plan
@@ -1,12 +1,24 @@
+distribute result [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$18] <- [{"pk": $$21, "sk": $$20}] project: [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$20, 3)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$20] <- [$$o.getField(1)] project: [$$21, $$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.MyData)  |PARTITIONED|
+                  data-scan []<-[$$21, $$o] <- test.MyData [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-01-disable-idxonly_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-01-disable-idxonly_ps.plan
index 7282a9b..7c5408d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-01-disable-idxonly_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-01-disable-idxonly_ps.plan
@@ -1,30 +1,60 @@
+distribute result [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$18] <- [{"pk": $$21, "sk": $$20}] project: [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$26 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (lt($$20, 3)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$20] <- [$$o.getField(1)] project: [$$21, $$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.MyData)  |PARTITIONED|
+                          data-scan []<-[$$21, $$o] <- test.MyData [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$26] <- [agg-range-map($$24, $$25)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$24, $$25] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$21])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- REPLICATE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (lt($$20, 3)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$20] <- [$$o.getField(1)] project: [$$21, $$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.MyData)  |PARTITIONED|
+                                    data-scan []<-[$$21, $$o] <- test.MyData [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-01.plan
index 6dc1292..eb43e83 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-01.plan
@@ -1,12 +1,24 @@
+distribute result [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$18] <- [{"pk": $$21, "sk": $$20}] project: [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt($$20, 3)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$20] <- [$$o.getField(1)] project: [$$21, $$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.MyData)  |PARTITIONED|
+                  data-scan []<-[$$21, $$o] <- test.MyData [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-01_ps.plan
index 7282a9b..7c5408d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-01_ps.plan
@@ -1,30 +1,60 @@
+distribute result [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$18] <- [{"pk": $$21, "sk": $$20}] project: [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$26 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (lt($$20, 3)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$20] <- [$$o.getField(1)] project: [$$21, $$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.MyData)  |PARTITIONED|
+                          data-scan []<-[$$21, $$o] <- test.MyData [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$26] <- [agg-range-map($$24, $$25)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$24, $$25] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$21])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- REPLICATE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (lt($$20, 3)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$20] <- [$$o.getField(1)] project: [$$21, $$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.MyData)  |PARTITIONED|
+                                    data-scan []<-[$$21, $$o] <- test.MyData [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-10.plan
index 8fac4f2..e97e17b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-index/btree-sidx-idxonly-10.plan
@@ -1,13 +1,26 @@
+distribute result [$$73] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    aggregate [$$73] <- [agg-sql-sum($$80)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- AGGREGATE  |UNPARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+        aggregate [$$80] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- AGGREGATE  |PARTITIONED|
+          select (and(ge($$69, 0), lt($$69, 1000000), lt($$74, date: { 2002-11-09 }), ge($$74, date: { 1997-05-19 }))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- STREAM_SELECT  |PARTITIONED|
+            assign [$$69, $$74] <- [$$72.getField(10), $$72.getField(6)] project: [$$69, $$74] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |PARTITIONED|
+              assign [$$72] <- [$$t.getField(12)] project: [$$72] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (twitter.ds_tweet)  |PARTITIONED|
+                    data-scan []<-[$$71, $$t] <- twitter.ds_tweet [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-ternary-inlj/query4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-ternary-inlj/query4.plan
index 2018224..6ae5d25 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-ternary-inlj/query4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/btree-ternary-inlj/query4.plan
@@ -1,30 +1,60 @@
+distribute result [$$70]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$70] <- [{"$1": $$75}] project: [$$70]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$75] <- [agg-sql-sum($$80)]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$80] <- [agg-sql-count(1)]
           -- AGGREGATE  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$74, $$61))
               -- HYBRID_HASH_JOIN [$$61][$$74]  |PARTITIONED|
+                exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$61]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- BTREE_SEARCH (tpcds.customer_address.customer_address)  |PARTITIONED|
+                      unnest-map [$$73, $$ca] <- index-search("customer_address", 0, "Default", "tpcds", "customer_address", true, true, 1, $$78, 1, $$78, true, true, true) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$78) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                           -- STABLE_SORT [$$78(ASC)]  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$78]  |PARTITIONED|
+                              project ([$$78, $$61])
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (tpcds.customer_demographics.customer_demographics)  |PARTITIONED|
+                                  unnest-map [$$72, $$cd2] <- index-search("customer_demographics", 0, "Default", "tpcds", "customer_demographics", true, true, 1, $$76, 1, $$76, true, true, true) [cardinality: 5.0E11, op-cost: 5.00004E11, total-cost: 5.00009E11]
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$76) [cardinality: 5.0E11, op-cost: 5.00004E11, total-cost: 5.00009E11]
                                       -- STABLE_SORT [$$76(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$76]  |PARTITIONED|
+                                          assign [$$78, $$61, $$76] <- [$$c.getField(4), $$c.getField(12), $$c.getField(2)] project: [$$78, $$61, $$76]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$c])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpcds.customer)  |PARTITIONED|
+                                                data-scan []<-[$$71, $$c] <- tpcds.customer [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  unnest $$74 <- scan-collection(array: [ 4, 5 ])
                   -- UNNEST  |UNPARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q10.plan
index ab5c179..b9cf3b6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q10.plan
@@ -1,52 +1,98 @@
+distribute result [$$159] [cardinality: 5.0E12, op-cost: 0.0, total-cost: 2.600009E7]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 5.0E12, op-cost: 0.0, total-cost: 2.600009E7]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 20 [cardinality: 5.0E12, op-cost: 0.0, total-cost: 2.600009E7]
     -- STREAM_LIMIT  |UNPARTITIONED|
+      assign [$$159] <- [{"c_id": $$c_id, "c_last": $$c_last, "revenue": $$175, "c_city": $$c_city, "c_phone": $$c_phone, "n_name": $$n_name}] project: [$$159] [cardinality: 5.0E12, op-cost: 0.0, total-cost: 2.600009E7]
       -- ASSIGN  |PARTITIONED|
+        exchange [cardinality: 5.0E12, op-cost: 0.0, total-cost: 2.600009E7]
         -- SORT_MERGE_EXCHANGE [$$175(DESC) ]  |PARTITIONED|
+          limit 20 [cardinality: 5.0E12, op-cost: 0.0, total-cost: 2.600009E7]
           -- STREAM_LIMIT  |PARTITIONED|
+            exchange [cardinality: 5.0E12, op-cost: 0.0, total-cost: 2.600009E7]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (topK: 20) (DESC, $$175) [cardinality: 5.0E12, op-cost: 0.0, total-cost: 2.600009E7]
               -- STABLE_SORT [topK: 20] [$$175(DESC)]  |PARTITIONED|
+                exchange [cardinality: 5.0E12, op-cost: 0.0, total-cost: 2.600009E7]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- SORT_GROUP_BY[$$184, $$185, $$186, $$187, $$188]  |PARTITIONED|
-                          {
+                  group by ([$$c_id := $$184; $$c_last := $$185; $$c_city := $$186; $$c_phone := $$187; $$n_name := $$188]) decor ([]) {
+                            aggregate [$$175] <- [agg-global-sql-sum($$183)]
                             -- AGGREGATE  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                          }
+                         } [cardinality: 0.0, op-cost: 0.0, total-cost: 2.600009E7]
+                  -- SORT_GROUP_BY[$$184, $$185, $$186, $$187, $$188]  |PARTITIONED|
+                    exchange [cardinality: 5.0E12, op-cost: 0.0, total-cost: 2.600009E7]
                     -- HASH_PARTITION_EXCHANGE [$$184, $$185, $$186, $$187, $$188]  |PARTITIONED|
-                      -- SORT_GROUP_BY[$$166, $$161, $$162, $$163, $$164]  |PARTITIONED|
-                              {
+                      group by ([$$184 := $$166; $$185 := $$161; $$186 := $$162; $$187 := $$163; $$188 := $$164]) decor ([]) {
+                                aggregate [$$183] <- [agg-local-sql-sum($$156)]
                                 -- AGGREGATE  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             } [cardinality: 0.0, op-cost: 0.0, total-cost: 2.600009E7]
+                      -- SORT_GROUP_BY[$$166, $$161, $$162, $$163, $$164]  |PARTITIONED|
+                        exchange [cardinality: 5.0E12, op-cost: 0.0, total-cost: 2.600009E7]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$156, $$166, $$161, $$162, $$163, $$164]) [cardinality: 5.0E12, op-cost: 0.0, total-cost: 2.600009E7]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 5.0E12, op-cost: 0.0, total-cost: 2.600009E7]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              join (eq($$176, $$177)) [cardinality: 5.0E12, op-cost: 1.4E7, total-cost: 2.600009E7]
                               -- HYBRID_HASH_JOIN [$$177][$$176]  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$156] <- [$$ol.getField("ol_amount")] project: [$$156, $$166, $$161, $$162, $$163, $$177] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                                   -- ASSIGN  |PARTITIONED|
+                                    unnest $$ol <- scan-collection($$179) project: [$$166, $$161, $$162, $$163, $$177, $$ol] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                                     -- UNNEST  |PARTITIONED|
+                                      project ([$$166, $$161, $$162, $$163, $$177, $$179]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          join (and(eq($$166, $$170), eq($$171, $$172), eq($$173, $$174))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 6000000.0]
                                           -- HYBRID_HASH_JOIN [$$166, $$171, $$173][$$170, $$172, $$174]  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                             -- HASH_PARTITION_EXCHANGE [$$166, $$171, $$173]  |PARTITIONED|
+                                              assign [$$177, $$163, $$162, $$161, $$173, $$171, $$166] <- [get-item(string-to-codepoint($$c.getField("c_state")), 0), $$c.getField("c_phone"), $$c.getField("c_city"), $$c.getField("c_last"), $$c.getField("c_w_id"), $$c.getField("c_d_id"), $$c.getField("c_id")] project: [$$166, $$161, $$162, $$163, $$177, $$171, $$173] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (test.customer)  |PARTITIONED|
+                                                    data-scan []<-[$$168, $$c] <- test.customer [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                             -- HASH_PARTITION_EXCHANGE [$$170, $$172, $$174]  |PARTITIONED|
+                                              select (and(lt($$165, "2016-01-01 00:00:00.000000"), ge($$165, "2015-10-01 00:00:00.000000"))) project: [$$179, $$170, $$172, $$174] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- STREAM_SELECT  |PARTITIONED|
+                                                assign [$$174, $$172, $$170, $$165, $$179] <- [$$o.getField("o_w_id"), $$o.getField("o_d_id"), $$o.getField("o_c_id"), $$o.getField("o_entry_d"), $$o.getField("o_orderline")] project: [$$174, $$172, $$170, $$165, $$179] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  project ([$$o]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                      data-scan []<-[$$169, $$o] <- test.orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  assign [$$164, $$176] <- [$$n.getField("n_name"), $$n.getField("n_nationkey")] project: [$$164, $$176] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$n]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                        data-scan []<-[$$167, $$n] <- test.nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q11.plan
index 52342a6..5a6b3ef 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q11.plan
@@ -1,107 +1,208 @@
+distribute result [$$176]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$176] <- [{"s_i_id": $$s_i_id, "ordercount": $$188}] project: [$$176]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$188(DESC) ]  |PARTITIONED|
+        order (DESC, $$188)
         -- STABLE_SORT [$$188(DESC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$s_i_id, $$188])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (gt($$187, $$199))
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$214]  |PARTITIONED|
-                            {
+                    group by ([$$s_i_id := $$214]) decor ([]) {
+                              aggregate [$$187, $$188] <- [agg-global-sql-sum($$212), agg-global-sql-sum($$213)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           } [cardinality: 0.0, op-cost: 0.0, total-cost: 5.00015E11]
+                    -- SORT_GROUP_BY[$$214]  |PARTITIONED|
+                      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                       -- HASH_PARTITION_EXCHANGE [$$214]  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$178]  |PARTITIONED|
-                                {
+                        group by ([$$214 := $$178]) decor ([]) {
+                                  aggregate [$$212, $$213] <- [agg-local-sql-sum($$142), agg-local-sql-sum($$142)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               } [cardinality: 0.0, op-cost: 0.0, total-cost: 5.00015E11]
+                        -- SORT_GROUP_BY[$$178]  |PARTITIONED|
+                          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$142, $$178]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$185, $$186)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00015E11]
                                 -- HYBRID_HASH_JOIN [$$186][$$185]  |PARTITIONED|
+                                  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$186]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        join (eq($$197, $$198)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                         -- HYBRID_HASH_JOIN [$$198][$$197]  |PARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$198] <- [$$203] project: [$$198] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                   -- HASH_PARTITION_EXCHANGE [$$203]  |PARTITIONED|
+                                                    select (eq($$191.getField("n_name"), "Germany")) project: [$$203] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                      assign [$$203] <- [$$191.getField("n_nationkey")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$191]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                            data-scan []<-[$$196, $$191] <- test.nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$186, $$197] <- [$$201, $$202] project: [$$186, $$197] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                   -- HASH_PARTITION_EXCHANGE [$$202]  |PARTITIONED|
+                                                    assign [$$201, $$202] <- [$$192.getField("su_suppkey"), $$192.getField("su_nationkey")] project: [$$201, $$202] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$192]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                                          data-scan []<-[$$195, $$192] <- test.supplier [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$185] <- [numeric-mod(numeric-multiply($$s.getField("s_w_id"), $$178), 10000)] project: [$$142, $$178, $$185] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- ASSIGN  |PARTITIONED|
+                                      assign [$$178, $$142] <- [$$s.getField("s_i_id"), $$s.getField("s_order_cnt")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$s]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                  data-scan []<-[$$181, $$s] <- test.stock [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    assign [$$199] <- [get-item($$167, 0)] project: [$$199] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                     -- ASSIGN  |UNPARTITIONED|
+                      aggregate [$$167] <- [listify($$166)] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                       -- AGGREGATE  |UNPARTITIONED|
+                        assign [$$166] <- [numeric-multiply($$211, 5.0E-5)] project: [$$166] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                         -- ASSIGN  |UNPARTITIONED|
+                          aggregate [$$211] <- [agg-global-sql-sum($$215)] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                           -- AGGREGATE  |UNPARTITIONED|
+                            exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                             -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                              aggregate [$$215] <- [agg-local-sql-sum($$163)] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                               -- AGGREGATE  |PARTITIONED|
+                                project ([$$163]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (eq($$200, $$201)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00015E11]
                                     -- HYBRID_HASH_JOIN [$$201][$$200]  |PARTITIONED|
+                                      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        project ([$$201]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            join (eq($$202, $$203)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                             -- HYBRID_HASH_JOIN [$$203][$$202]  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                   -- HASH_PARTITION_EXCHANGE [$$203]  |PARTITIONED|
+                                                    select (eq($$191.getField("n_name"), "Germany")) project: [$$203] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                      assign [$$203] <- [$$191.getField("n_nationkey")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$191]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                            data-scan []<-[$$196, $$191] <- test.nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                   -- HASH_PARTITION_EXCHANGE [$$202]  |PARTITIONED|
+                                                    assign [$$201, $$202] <- [$$192.getField("su_suppkey"), $$192.getField("su_nationkey")] project: [$$201, $$202] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$192]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                                          data-scan []<-[$$195, $$192] <- test.supplier [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        assign [$$200, $$163] <- [numeric-mod(numeric-multiply($$193.getField("s_w_id"), $$193.getField("s_i_id")), 10000), $$193.getField("s_order_cnt")] project: [$$163, $$200] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- ASSIGN  |PARTITIONED|
+                                          assign [$$193] <- [$$s] project: [$$193] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- REPLICATE  |PARTITIONED|
+                                                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  project ([$$s]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                      data-scan []<-[$$181, $$s] <- test.stock [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q16.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q16.plan
index 9a2c5f2..3d9f362 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q16.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q16.plan
@@ -1,59 +1,112 @@
+distribute result [$$128] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$128] <- [{"i_name": $$i_name, "brand": $#1, "i_price": $$i_price, "supplier_cnt": $$139}] project: [$$128] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
       -- SORT_MERGE_EXCHANGE [$$139(DESC) ]  |PARTITIONED|
+        order (DESC, $$139) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
         -- STABLE_SORT [$$139(DESC)]  |PARTITIONED|
+          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- PRE_CLUSTERED_GROUP_BY[$$129, $$130, $$131]  |PARTITIONED|
-                    {
+            group by ([$$i_name := $$129; $#1 := $$130; $$i_price := $$131]) decor ([]) {
+                      aggregate [$$139] <- [agg-sql-count($$150)]
                       -- AGGREGATE  |LOCAL|
+                        distinct ([$$150])
                         -- MICRO_PRE_SORTED_DISTINCT_BY  |LOCAL|
+                          order (ASC, $$150)
                           -- MICRO_STABLE_SORT [$$150(ASC)]  |LOCAL|
+                            assign [$$150] <- [numeric-mod(numeric-multiply($$143, $$144), 10000)]
                             -- ASSIGN  |LOCAL|
+                              nested tuple source
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   } [cardinality: 0.0, op-cost: 0.0, total-cost: 2.000015E12]
+            -- PRE_CLUSTERED_GROUP_BY[$$129, $$130, $$131]  |PARTITIONED|
+              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$129) (ASC, $$130) (ASC, $$131) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
                 -- STABLE_SORT [$$129(ASC), $$130(ASC), $$131(ASC)]  |PARTITIONED|
+                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
                   -- HASH_PARTITION_EXCHANGE [$$129, $$130, $$131]  |PARTITIONED|
+                    assign [$$130] <- [substring1($$132, 1, 3)] project: [$$143, $$144, $$129, $$130, $$131] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
                     -- ASSIGN  |PARTITIONED|
+                      select ($$111) project: [$$129, $$131, $$132, $$144, $$143]
                       -- STREAM_SELECT  |PARTITIONED|
+                        project ([$$111, $$129, $$131, $$132, $$144, $$143]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- PRE_CLUSTERED_GROUP_BY[$$133, $$134]  |PARTITIONED|
-                                    {
+                            group by ([$$146 := $$133; $$147 := $$134]) decor ([$$129; $$131; $$132; $$144 := $$138; $$143 := $$141]) {
+                                      aggregate [$$111] <- [empty-stream()]
                                       -- AGGREGATE  |LOCAL|
+                                        select (not(is-missing($$145)))
                                         -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   } [cardinality: 0.0, op-cost: 0.0, total-cost: 2.000015E12]
+                            -- PRE_CLUSTERED_GROUP_BY[$$133, $$134]  |PARTITIONED|
+                              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$133) (ASC, $$134) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
                                 -- STABLE_SORT [$$133(ASC), $$134(ASC)]  |PARTITIONED|
+                                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
                                   -- HASH_PARTITION_EXCHANGE [$$133, $$134]  |PARTITIONED|
+                                    project ([$$129, $$131, $$132, $$145, $$133, $$134, $$138, $$141]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        join (eq($$137, $$138)) [cardinality: 9.223372036854776E16, op-cost: 1.000004E12, total-cost: 2.000015E12]
                                         -- HYBRID_HASH_JOIN [$$138][$$137]  |PARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$145, $$133, $$138, $$141]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                left outer join (not(if-missing-or-null(neq(numeric-mod(numeric-multiply($$141, $$138), 10000), $$105), false))) [cardinality: 1.0E12, op-cost: 1.0E12, total-cost: 1.000006E12]
                                                 -- NESTED_LOOP  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$138, $$141] <- [$$s.getField("s_i_id"), $$s.getField("s_w_id")] project: [$$133, $$138, $$141] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                        data-scan []<-[$$133, $$s] <- test.stock [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                  exchange
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$145] <- [true]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      select (like($$su.getField("su_comment"), "%Customer%Complaints%")) project: [$$105] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        assign [$$105] <- [$$su.getField("su_suppkey")]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          project ([$$su])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                                              data-scan []<-[$$135, $$su] <- test.supplier [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            select (not(like($$132, "zz%"))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- STREAM_SELECT  |PARTITIONED|
+                                              assign [$$131, $$129, $$132, $$137] <- [$$i.getField("i_price"), $$i.getField("i_name"), $$i.getField("i_data"), $$i.getField("i_id")] project: [$$134, $$131, $$129, $$132, $$137] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.item)  |PARTITIONED|
+                                                  data-scan []<-[$$134, $$i] <- test.item [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q18.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q18.plan
index 27ee1f4..3846846 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q18.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q18.plan
@@ -1,44 +1,82 @@
+distribute result [$$169] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 100 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
     -- STREAM_LIMIT  |UNPARTITIONED|
+      assign [$$169] <- [{"c_last": $$c_last, "o_id": $$c_id, "o_entry_d": $$o_entry_d, "o_ol_cnt": $$o_ol_cnt, "$1": $$192}] project: [$$169] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
       -- ASSIGN  |PARTITIONED|
+        project ([$$c_last, $$c_id, $$o_entry_d, $$o_ol_cnt, $$192]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
           -- SORT_MERGE_EXCHANGE [$$193(DESC), $$o_entry_d(ASC) ]  |PARTITIONED|
+            limit 100 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
             -- STREAM_LIMIT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (topK: 100) (DESC, $$193) (ASC, $$o_entry_d) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                 -- STABLE_SORT [topK: 100] [$$193(DESC), $$o_entry_d(ASC)]  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (gt($$191, 200)) project: [$$c_last, $$c_id, $$o_entry_d, $$o_ol_cnt, $$192, $$193]
                     -- STREAM_SELECT  |PARTITIONED|
+                      project ([$$191, $$192, $$193, $$c_id, $$c_last, $$o_entry_d, $$o_ol_cnt]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- SORT_GROUP_BY[$$201, $$202, $$203, $$204, $$205, $$206, $$207]  |PARTITIONED|
-                                  {
+                          group by ([$$o_id := $$201; $$o_w_id := $$202; $$o_d_id := $$203; $$c_id := $$204; $$c_last := $$205; $$o_entry_d := $$206; $$o_ol_cnt := $$207]) decor ([]) {
+                                    aggregate [$$191, $$192, $$193] <- [agg-global-sql-sum($$198), agg-global-sql-sum($$199), agg-global-sql-sum($$200)]
                                     -- AGGREGATE  |LOCAL|
+                                      nested tuple source
                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
+                                 } [cardinality: 0.0, op-cost: 0.0, total-cost: 6000000.0]
+                          -- SORT_GROUP_BY[$$201, $$202, $$203, $$204, $$205, $$206, $$207]  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                             -- HASH_PARTITION_EXCHANGE [$$201, $$202, $$203, $$204, $$205, $$206, $$207]  |PARTITIONED|
-                              -- SORT_GROUP_BY[$$175, $$183, $$184, $$185, $$179, $$180, $$181]  |PARTITIONED|
-                                      {
+                              group by ([$$201 := $$175; $$202 := $$183; $$203 := $$184; $$204 := $$185; $$205 := $$179; $$206 := $$180; $$207 := $$181]) decor ([]) {
+                                        aggregate [$$198, $$199, $$200] <- [agg-local-sql-sum($$160), agg-local-sql-sum($$160), agg-local-sql-sum($$160)]
                                         -- AGGREGATE  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     } [cardinality: 0.0, op-cost: 0.0, total-cost: 6000000.0]
+                              -- SORT_GROUP_BY[$$175, $$183, $$184, $$185, $$179, $$180, $$181]  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$160] <- [$$ol.getField("ol_amount")] project: [$$160, $$175, $$183, $$184, $$185, $$179, $$180, $$181] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                                   -- ASSIGN  |PARTITIONED|
+                                    unnest $$ol <- scan-collection($$194) project: [$$175, $$183, $$184, $$180, $$181, $$185, $$179, $$ol] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                                     -- UNNEST  |PARTITIONED|
+                                      project ([$$175, $$183, $$184, $$180, $$181, $$194, $$185, $$179]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          join (and(eq($$185, $$188), eq($$189, $$183), eq($$190, $$184))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 6000000.0]
                                           -- HYBRID_HASH_JOIN [$$188, $$183, $$184][$$185, $$189, $$190]  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                             -- HASH_PARTITION_EXCHANGE [$$188, $$183, $$184]  |PARTITIONED|
+                                              assign [$$181, $$180, $$175, $$188, $$183, $$184, $$194] <- [$$o.getField("o_ol_cnt"), $$o.getField("o_entry_d"), $$o.getField("o_id"), $$o.getField("o_c_id"), $$o.getField("o_w_id"), $$o.getField("o_d_id"), $$o.getField("o_orderline")] project: [$$175, $$183, $$184, $$180, $$181, $$194, $$188] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$o]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                    data-scan []<-[$$186, $$o] <- test.orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                             -- HASH_PARTITION_EXCHANGE [$$185, $$189, $$190]  |PARTITIONED|
+                                              assign [$$179, $$190, $$189, $$185] <- [$$c.getField("c_last"), $$c.getField("c_d_id"), $$c.getField("c_w_id"), $$c.getField("c_id")] project: [$$185, $$179, $$189, $$190] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (test.customer)  |PARTITIONED|
+                                                    data-scan []<-[$$187, $$c] <- test.customer [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q2.plan
index e36e0c8..5385d45 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q2.plan
@@ -1,147 +1,288 @@
+distribute result [$$240]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 100
     -- STREAM_LIMIT  |UNPARTITIONED|
+      assign [$$240] <- [{"su_suppkey": $$249, "su_name": $$281, "n_name": $$280, "i_id": $$247, "i_name": $$285, "su_address": $$286, "su_phone": $$287, "su_comment": $$288}] project: [$$240]
       -- ASSIGN  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$280(ASC), $$281(ASC), $$247(ASC) ]  |PARTITIONED|
+          limit 100
           -- STREAM_LIMIT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (topK: 100) (ASC, $$280) (ASC, $$281) (ASC, $$247)
               -- STABLE_SORT [topK: 100] [$$280(ASC), $$281(ASC), $$247(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$249, $$281, $$280, $$247, $$285, $$286, $$287, $$288])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (eq($$260, $$261))
                       -- HYBRID_HASH_JOIN [$$260][$$261]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$260]  |PARTITIONED|
+                          project ([$$249, $$281, $$280, $$247, $$285, $$286, $$287, $$288, $$260])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              join (eq($$267, $$268))
                               -- HYBRID_HASH_JOIN [$$267][$$268]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$267]  |PARTITIONED|
+                                  project ([$$249, $$281, $$247, $$285, $$286, $$287, $$288, $$267])
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      join (eq($$273, $$249))
                                       -- HYBRID_HASH_JOIN [$$273][$$249]  |PARTITIONED|
+                                        exchange
                                         -- HASH_PARTITION_EXCHANGE [$$273]  |PARTITIONED|
+                                          assign [$$273] <- [numeric-mod(numeric-multiply($$279, $$248), 10000)] project: [$$247, $$285, $$273]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$247, $$285, $$279, $$248])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                join (and(eq($$247, $$248), eq($$271, $$262)))
                                                 -- HYBRID_HASH_JOIN [$$247, $$262][$$248, $$271]  |PARTITIONED|
+                                                  exchange
                                                   -- HASH_PARTITION_EXCHANGE [$$247, $$262]  |PARTITIONED|
+                                                    project ([$$247, $$285, $$262])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        join (eq($$247, $$s_i_id))
                                                         -- HYBRID_HASH_JOIN [$$s_i_id][$$247]  |PARTITIONED|
+                                                          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- SORT_GROUP_BY[$$291]  |PARTITIONED|
-                                                                    {
+                                                            group by ([$$s_i_id := $$291]) decor ([]) {
+                                                                      aggregate [$$262] <- [agg-global-sql-min($$290)]
                                                                       -- AGGREGATE  |LOCAL|
+                                                                        nested tuple source
                                                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                    }
+                                                                   } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+                                                            -- SORT_GROUP_BY[$$291]  |PARTITIONED|
+                                                              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                               -- HASH_PARTITION_EXCHANGE [$$291]  |PARTITIONED|
-                                                                -- SORT_GROUP_BY[$$245]  |PARTITIONED|
-                                                                        {
+                                                                group by ([$$291 := $$245]) decor ([]) {
+                                                                          aggregate [$$290] <- [agg-local-sql-min($$194)]
                                                                           -- AGGREGATE  |LOCAL|
+                                                                            nested tuple source
                                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                        }
+                                                                       } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+                                                                -- SORT_GROUP_BY[$$245]  |PARTITIONED|
+                                                                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    project ([$$194, $$245]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        join (eq($$263, $$264)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                                                                         -- HYBRID_HASH_JOIN [$$263][$$264]  |PARTITIONED|
+                                                                          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            project ([$$194, $$245, $$263]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                                              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                join (eq($$265, $$276)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00015E11]
                                                                                 -- HYBRID_HASH_JOIN [$$265][$$276]  |PARTITIONED|
+                                                                                  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    project ([$$194, $$245, $$265]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                                      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        join (eq($$269, $$277)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                                                         -- HYBRID_HASH_JOIN [$$269][$$277]  |PARTITIONED|
+                                                                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                                           -- HASH_PARTITION_EXCHANGE [$$269]  |PARTITIONED|
+                                                                                            assign [$$269] <- [numeric-mod(numeric-multiply($$s1.getField("s_w_id"), $$245), 10000)] project: [$$194, $$245, $$269] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                              assign [$$245, $$194] <- [$$s1.getField("s_i_id"), $$s1.getField("s_quantity")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                  replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                      project ([$$s1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                          -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                                                                          data-scan []<-[$$250, $$s1] <- test.stock [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                              empty-tuple-source
                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                                           -- HASH_PARTITION_EXCHANGE [$$277]  |PARTITIONED|
+                                                                                            assign [$$277, $$265] <- [$$su1.getField("su_suppkey"), $$su1.getField("su_nationkey")] project: [$$265, $$277] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                 -- REPLICATE  |PARTITIONED|
+                                                                                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    project ([$$su1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                        -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                                                                                        data-scan []<-[$$251, $$su1] <- test.supplier [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                          exchange
                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                            empty-tuple-source
                                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                  exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                    assign [$$276, $$263] <- [$$n1.getField("n_nationkey"), $$n1.getField("n_regionkey")] project: [$$263, $$276] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            project ([$$n1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                                                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                                                                data-scan []<-[$$252, $$n1] <- test.nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    empty-tuple-source
                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                          exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                            replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                             -- REPLICATE  |PARTITIONED|
+                                                                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                select (and(ge($$259, "Europ"), lt($$259, "Euroq"))) project: [$$264] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                                  assign [$$264, $$259] <- [$$r1.getField("r_regionkey"), $$r1.getField("r_name")] project: [$$264, $$259] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                    project ([$$r1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                        -- DATASOURCE_SCAN (test.region)  |PARTITIONED|
+                                                                                        data-scan []<-[$$253, $$r1] <- test.region [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            empty-tuple-source
                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                          exchange
                                                           -- HASH_PARTITION_EXCHANGE [$$247]  |PARTITIONED|
+                                                            select (like($$i.getField("i_data"), "%b")) project: [$$247, $$285]
                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                              assign [$$285, $$247] <- [$$i.getField("i_name"), $$i.getField("i_id")]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                project ([$$i])
                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- DATASOURCE_SCAN (test.item)  |PARTITIONED|
+                                                                    data-scan []<-[$$254, $$i] <- test.item
+                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- HASH_PARTITION_EXCHANGE [$$248, $$271]  |PARTITIONED|
+                                                    assign [$$279, $$271, $$248] <- [$$s.getField("s_w_id"), $$s.getField("s_quantity"), $$s.getField("s_i_id")] project: [$$279, $$248, $$271] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      assign [$$s] <- [$$s1] project: [$$s] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                           -- REPLICATE  |PARTITIONED|
+                                                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              project ([$$s1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                                  data-scan []<-[$$250, $$s1] <- test.stock [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- HASH_PARTITION_EXCHANGE [$$249]  |PARTITIONED|
+                                          assign [$$288, $$287, $$286, $$281, $$267, $$249] <- [$$su.getField("su_comment"), $$su.getField("su_phone"), $$su.getField("su_address"), $$su.getField("su_name"), $$su.getField("su_nationkey"), $$su.getField("su_suppkey")] project: [$$249, $$281, $$286, $$287, $$288, $$267] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$su] <- [$$su1] project: [$$su] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    project ([$$su1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                                        data-scan []<-[$$251, $$su1] <- test.supplier [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- HASH_PARTITION_EXCHANGE [$$268]  |PARTITIONED|
+                                  assign [$$280, $$260, $$268] <- [$$n.getField("n_name"), $$n.getField("n_regionkey"), $$n.getField("n_nationkey")] project: [$$280, $$260, $$268] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ASSIGN  |PARTITIONED|
+                                    assign [$$n] <- [$$n1] project: [$$n] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$n1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                data-scan []<-[$$252, $$n1] <- test.nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- HASH_PARTITION_EXCHANGE [$$261]  |PARTITIONED|
+                          assign [$$261] <- [$$264] project: [$$261] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ASSIGN  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- REPLICATE  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  select (and(ge($$259, "Europ"), lt($$259, "Euroq"))) project: [$$264] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- STREAM_SELECT  |PARTITIONED|
+                                    assign [$$264, $$259] <- [$$r1.getField("r_regionkey"), $$r1.getField("r_name")] project: [$$264, $$259] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$r1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.region)  |PARTITIONED|
+                                          data-scan []<-[$$253, $$r1] <- test.region [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q21.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q21.plan
index c9b6770..09cb112 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q21.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q21.plan
@@ -1,102 +1,192 @@
+distribute result [$$339] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.250023E12]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.250023E12]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 100 [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.250023E12]
     -- STREAM_LIMIT  |UNPARTITIONED|
+      project ([$$339]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.250023E12]
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.250023E12]
         -- SORT_MERGE_EXCHANGE [$$su_name(ASC) ]  |PARTITIONED|
+          assign [$$339] <- [{"su_name": $$su_name, "numwait": $$364}] project: [$$su_name, $$339] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.250023E12]
           -- ASSIGN  |PARTITIONED|
+            limit 100 [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.250023E12]
             -- STREAM_LIMIT  |PARTITIONED|
+              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.250023E12]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- SORT_GROUP_BY[$$399]  |PARTITIONED|
-                        {
+                group by ([$$su_name := $$399]) decor ([]) {
+                          aggregate [$$364] <- [agg-sql-sum($$398)]
                           -- AGGREGATE  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       } [cardinality: 0.0, op-cost: 0.0, total-cost: 1.250023E12]
+                -- SORT_GROUP_BY[$$399]  |PARTITIONED|
+                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.250023E12]
                   -- HASH_PARTITION_EXCHANGE [$$399]  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$su_name]  |PARTITIONED|
-                            {
+                    group by ([$$399 := $$su_name]) decor ([]) {
+                              aggregate [$$398] <- [agg-sql-count(1)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           } [cardinality: 0.0, op-cost: 0.0, total-cost: 1.250023E12]
+                    -- SORT_GROUP_BY[$$su_name]  |PARTITIONED|
+                      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.250023E12]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        select (eq($$363, 0)) project: [$$su_name]
                         -- STREAM_SELECT  |PARTITIONED|
+                          project ([$$363, $$su_name]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.250023E12]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.250023E12]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- SORT_GROUP_BY[$$390, $$391, $$392, $$393, $$394, $$395, $$396, $$397]  |PARTITIONED|
-                                      {
+                              group by ([$$o_w_id := $$390; $$o_d_id := $$391; $$o_id := $$392; $$n_nationkey := $$393; $$su_suppkey := $$394; $$s_w_id := $$395; $$s_i_id := $$396; $$su_name := $$397]) decor ([]) {
+                                        aggregate [$$363] <- [agg-sql-sum($$389)]
                                         -- AGGREGATE  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     } [cardinality: 0.0, op-cost: 0.0, total-cost: 1.250023E12]
+                              -- SORT_GROUP_BY[$$390, $$391, $$392, $$393, $$394, $$395, $$396, $$397]  |PARTITIONED|
+                                exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.250023E12]
                                 -- HASH_PARTITION_EXCHANGE [$$390, $$391, $$392, $$393, $$394, $$395, $$396, $$397]  |PARTITIONED|
-                                  -- SORT_GROUP_BY[$$352, $$378, $$377, $$354, $$355, $$351, $$350, $$379]  |PARTITIONED|
-                                          {
+                                  group by ([$$390 := $$352; $$391 := $$378; $$392 := $$377; $$393 := $$354; $$394 := $$355; $$395 := $$351; $$396 := $$350; $$397 := $$379]) decor ([]) {
+                                            aggregate [$$389] <- [agg-sql-count($$326)]
                                             -- AGGREGATE  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                          }
+                                         } [cardinality: 0.0, op-cost: 0.0, total-cost: 1.250023E12]
+                                  -- SORT_GROUP_BY[$$352, $$378, $$377, $$354, $$355, $$351, $$350, $$379]  |PARTITIONED|
+                                    exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.250023E12]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$326, $$352, $$378, $$377, $$354, $$355, $$351, $$350, $$379]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.250023E12]
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 1.250023E12]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          join (eq($$365, $$354)) [cardinality: 9.223372036854776E16, op-cost: 2.50004E11, total-cost: 1.250023E12]
                                           -- HYBRID_HASH_JOIN [$$365][$$354]  |PARTITIONED|
+                                            exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 1.000014E12]
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$326, $$352, $$378, $$377, $$355, $$351, $$350, $$379, $$365]) [cardinality: 2.5E11, op-cost: 0.0, total-cost: 1.000014E12]
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 1.000014E12]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  join (eq($$366, $$355)) [cardinality: 2.5E11, op-cost: 1500000.0, total-cost: 1.000014E12]
                                                   -- HYBRID_HASH_JOIN [$$366][$$355]  |PARTITIONED|
+                                                    exchange [cardinality: 500000.0, op-cost: 500000.0, total-cost: 1.0000105E12]
                                                     -- HASH_PARTITION_EXCHANGE [$$366]  |PARTITIONED|
+                                                      project ([$$326, $$352, $$378, $$377, $$351, $$350, $$366]) [cardinality: 500000.0, op-cost: 0.0, total-cost: 1.00001E12]
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange [cardinality: 500000.0, op-cost: 500000.0, total-cost: 1.0000105E12]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          join (and(eq($$352, $$351), eq($$362, $$350))) [cardinality: 500000.0, op-cost: 1500000.0, total-cost: 1.00001E12]
                                                           -- HYBRID_HASH_JOIN [$$352, $$362][$$351, $$350]  |PARTITIONED|
+                                                            exchange [cardinality: 1000000.0, op-cost: 500000.0, total-cost: 1500000.0]
                                                             -- HASH_PARTITION_EXCHANGE [$$352, $$362]  |PARTITIONED|
+                                                              project ([$$326, $$352, $$378, $$377, $$362]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                exchange [cardinality: 1000000.0, op-cost: 500000.0, total-cost: 1500000.0]
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  left outer join (and(eq($$383, $$378), gt($$384, $$353), eq($$381, $$377), eq($$382, $$352))) [cardinality: 500000.0, op-cost: 1.0E12, total-cost: 1.000006E12]
                                                                   -- NESTED_LOOP  |PARTITIONED|
+                                                                    exchange [cardinality: 1000000.0, op-cost: 500000.0, total-cost: 1500000.0]
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      select (gt($$353, string(numeric-add(date($$349), duration: {P150D })))) project: [$$352, $$378, $$377, $$362, $$353] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                        assign [$$362, $$353] <- [$$ol1.getField("ol_i_id"), $$ol1.getField("ol_delivery_d")] project: [$$378, $$377, $$352, $$349, $$362, $$353] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          unnest $$ol1 <- scan-collection($$376) project: [$$378, $$377, $$352, $$349, $$ol1] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                           -- UNNEST  |PARTITIONED|
+                                                                            select (and(le($$349, "2017-12-31 00:00:00"), ge($$349, "2017-12-01 00:00:00")))
                                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                                              assign [$$378, $$377, $$352, $$349, $$376] <- [$$o1.getField("o_d_id"), $$o1.getField("o_id"), $$o1.getField("o_w_id"), $$o1.getField("o_entry_d"), $$o1.getField("o_orderline")] project: [$$378, $$377, $$352, $$349, $$376] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                assign [$$o1] <- [$$o2] project: [$$o1] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                  exchange [cardinality: 1000000.0, op-cost: 500000.0, total-cost: 1500000.0]
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                      exchange [cardinality: 1000000.0, op-cost: 500000.0, total-cost: 1500000.0]
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        project ([$$o2]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                          exchange [cardinality: 1000000.0, op-cost: 500000.0, total-cost: 1500000.0]
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                            -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                                                            data-scan []<-[$$361, $$o2] <- test.orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                empty-tuple-source
                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                    exchange
                                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                      assign [$$326] <- [{"o_id": $$381, "o_w_id": $$382, "o_d_id": $$383, "ol_delivery_d": $$384}.getField("o_id")]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        assign [$$384] <- [$$ol2.getField("ol_delivery_d")] project: [$$383, $$382, $$381, $$384]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          unnest $$ol2 <- scan-collection($$380) project: [$$383, $$382, $$381, $$ol2] [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
                                                                           -- UNNEST  |PARTITIONED|
+                                                                            select (and(le($$356, "2017-12-31 00:00:00"), ge($$356, "2017-12-01 00:00:00"))) project: [$$383, $$382, $$381, $$380]
                                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                                              assign [$$383, $$382, $$381, $$356, $$380] <- [$$o2.getField("o_d_id"), $$o2.getField("o_w_id"), $$o2.getField("o_id"), $$o2.getField("o_entry_d"), $$o2.getField("o_orderline")] project: [$$383, $$382, $$381, $$356, $$380]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                    exchange [cardinality: 1000000.0, op-cost: 500000.0, total-cost: 1500000.0]
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      project ([$$o2]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                        exchange [cardinality: 1000000.0, op-cost: 500000.0, total-cost: 1500000.0]
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                          -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                                                          data-scan []<-[$$361, $$o2] <- test.orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              empty-tuple-source
                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                             -- HASH_PARTITION_EXCHANGE [$$351, $$350]  |PARTITIONED|
+                                                              assign [$$366] <- [numeric-mod(numeric-multiply($$351, $$350), 10000)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                assign [$$351, $$350] <- [$$s.getField("s_w_id"), $$s.getField("s_i_id")] project: [$$351, $$350] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  project ([$$s]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                                      data-scan []<-[$$359, $$s] <- test.stock [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          empty-tuple-source
                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                     -- HASH_PARTITION_EXCHANGE [$$355]  |PARTITIONED|
+                                                      assign [$$379, $$355, $$365] <- [$$su.getField("su_name"), $$su.getField("su_suppkey"), $$su.getField("su_nationkey")] project: [$$355, $$379, $$365] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$su]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                                            data-scan []<-[$$358, $$su] <- test.supplier [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              select (eq($$n.getField("n_name"), "Peru")) project: [$$354] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- STREAM_SELECT  |PARTITIONED|
+                                                assign [$$354] <- [$$n.getField("n_nationkey")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  project ([$$n]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                      data-scan []<-[$$357, $$n] <- test.nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q5.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q5.plan
index 8e1e3d7..31aa8ab 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q5.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q5.plan
@@ -1,86 +1,166 @@
+distribute result [$$243] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$243] <- [{"n_name": $$n_name, "revenue": $#2}] project: [$$243] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
       -- SORT_MERGE_EXCHANGE [$#2(DESC) ]  |PARTITIONED|
+        order (DESC, $#2) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
         -- STABLE_SORT [$#2(DESC)]  |PARTITIONED|
+          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            assign [$#2] <- [round($$270, 2)] project: [$$n_name, $#2] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
             -- ASSIGN  |PARTITIONED|
+              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- SORT_GROUP_BY[$$292]  |PARTITIONED|
-                        {
+                group by ([$$n_name := $$292]) decor ([]) {
+                          aggregate [$$270] <- [agg-global-sql-sum($$291)]
                           -- AGGREGATE  |LOCAL|
+                            nested tuple source
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+                -- SORT_GROUP_BY[$$292]  |PARTITIONED|
+                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                   -- HASH_PARTITION_EXCHANGE [$$292]  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$275]  |PARTITIONED|
-                            {
+                    group by ([$$292 := $$275]) decor ([]) {
+                              aggregate [$$291] <- [agg-local-sql-sum($$280)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+                    -- SORT_GROUP_BY[$$275]  |PARTITIONED|
+                      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$280, $$275]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (and(eq($$266, $$274), eq($$290, $$269))) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                             -- HYBRID_HASH_JOIN [$$274, $$290][$$266, $$269]  |PARTITIONED|
+                              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00025E11]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$290] <- [numeric-mod(numeric-multiply($$245, $$246), 10000)] project: [$$280, $$275, $$274, $$290] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00025E11]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$280, $$275, $$274, $$245, $$246]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00025E11]
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00025E11]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      join (eq($$256, $$257)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00025E11]
                                       -- HYBRID_HASH_JOIN [$$256][$$257]  |PARTITIONED|
+                                        exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.6E7]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          project ([$$280, $$275, $$274, $$245, $$246, $$256]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.6E7]
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.6E7]
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              join (eq($$258, $$274)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 1.6E7]
                                               -- HYBRID_HASH_JOIN [$$258][$$274]  |PARTITIONED|
+                                                exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1.2E7]
                                                 -- HASH_PARTITION_EXCHANGE [$$258]  |PARTITIONED|
+                                                  project ([$$280, $$245, $$246, $$258]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1.1E7]
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1.2E7]
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      join (and(eq($$276, $$260), eq($$277, $$254), eq($$278, $$263))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 1.1E7]
                                                       -- HYBRID_HASH_JOIN [$$260, $$254, $$263][$$276, $$277, $$278]  |PARTITIONED|
+                                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 7000000.0]
                                                         -- HASH_PARTITION_EXCHANGE [$$260, $$254, $$263]  |PARTITIONED|
+                                                          project ([$$280, $$245, $$246, $$260, $$254, $$263]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 7000000.0]
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              join (and(eq($$254, $$245), eq($$281, $$246))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 6000000.0]
                                                               -- HYBRID_HASH_JOIN [$$245, $$246][$$254, $$281]  |PARTITIONED|
+                                                                exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                 -- HASH_PARTITION_EXCHANGE [$$245, $$246]  |PARTITIONED|
+                                                                  assign [$$246, $$245] <- [$$s.getField("s_i_id"), $$s.getField("s_w_id")] project: [$$245, $$246] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    project ([$$s]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                      exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                                        data-scan []<-[$$247, $$s] <- test.stock [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                 -- HASH_PARTITION_EXCHANGE [$$254, $$281]  |PARTITIONED|
+                                                                  assign [$$281, $$280] <- [$$ol.getField("ol_i_id"), $$ol.getField("ol_amount")] project: [$$280, $$260, $$254, $$263, $$281] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                   -- ASSIGN  |PARTITIONED|
+                                                                    unnest $$ol <- scan-collection($$271) project: [$$263, $$260, $$254, $$ol] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                     -- UNNEST  |PARTITIONED|
+                                                                      select (and(ge($$253, "2016-01-01 00:00:00.000000"), lt($$253, "2017-01-01 00:00:00.000000"))) project: [$$263, $$260, $$254, $$271]
                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                        assign [$$263, $$260, $$254, $$253, $$271] <- [$$o.getField("o_d_id"), $$o.getField("o_c_id"), $$o.getField("o_w_id"), $$o.getField("o_entry_d"), $$o.getField("o_orderline")] project: [$$263, $$260, $$254, $$253, $$271] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                         -- ASSIGN  |PARTITIONED|
+                                                                          project ([$$o]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                              -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                                              data-scan []<-[$$248, $$o] <- test.orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  empty-tuple-source
                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                         -- HASH_PARTITION_EXCHANGE [$$276, $$277, $$278]  |PARTITIONED|
+                                                          assign [$$258, $$278, $$277, $$276] <- [get-item(string-to-codepoint($$c.getField("c_state")), 0), $$c.getField("c_d_id"), $$c.getField("c_w_id"), $$c.getField("c_id")] project: [$$258, $$276, $$277, $$278] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.customer)  |PARTITIONED|
+                                                                data-scan []<-[$$249, $$c] <- test.customer [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                 -- HASH_PARTITION_EXCHANGE [$$274]  |PARTITIONED|
+                                                  assign [$$275, $$274, $$256] <- [$$n.getField("n_name"), $$n.getField("n_nationkey"), $$n.getField("n_regionkey")] project: [$$275, $$274, $$256] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    project ([$$n]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                        data-scan []<-[$$250, $$n] <- test.nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          select (eq($$r.getField("r_name"), "Asia")) project: [$$257] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- STREAM_SELECT  |PARTITIONED|
+                                            assign [$$257] <- [$$r.getField("r_regionkey")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- ASSIGN  |PARTITIONED|
+                                              project ([$$r]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.region)  |PARTITIONED|
+                                                  data-scan []<-[$$251, $$r] <- test.region [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$269, $$266] <- [$$su.getField("su_suppkey"), $$su.getField("su_nationkey")] project: [$$266, $$269] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$su]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                      data-scan []<-[$$252, $$su] <- test.supplier [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q7.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q7.plan
index 9296e8d..e468850 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q7.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q7.plan
@@ -1,90 +1,174 @@
+distribute result [$$271] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$271] <- [{"supp_nation": $$su_nationkey, "cust_nation": $#1, "l_year": $#2, "revenue": round($$301, 2)}] project: [$$271] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
       -- SORT_MERGE_EXCHANGE [$$su_nationkey(ASC), $#1(ASC), $#2(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$328, $$329, $$330]  |PARTITIONED|
-                {
+        group by ([$$su_nationkey := $$328; $#1 := $$329; $#2 := $$330]) decor ([]) {
+                  aggregate [$$301] <- [agg-global-sql-sum($$327)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+        -- SORT_GROUP_BY[$$328, $$329, $$330]  |PARTITIONED|
+          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
           -- HASH_PARTITION_EXCHANGE [$$328, $$329, $$330]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$277, $$273, $$274]  |PARTITIONED|
-                    {
+            group by ([$$328 := $$277; $$329 := $$273; $$330 := $$274]) decor ([]) {
+                      aggregate [$$327] <- [agg-local-sql-sum($$313)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+            -- SORT_GROUP_BY[$$277, $$273, $$274]  |PARTITIONED|
+              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$274, $$273] <- [get-year(date($$309)), substring1($$285, 1, 1)] project: [$$313, $$277, $$273, $$274] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                 -- ASSIGN  |PARTITIONED|
+                  select (or(and(eq($$286, "Germany"), eq($$287, "Cambodia")), and(eq($$286, "Cambodia"), eq($$287, "Germany")))) project: [$$313, $$277, $$309, $$285]
                   -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$313, $$277, $$309, $$285, $$287, $$286]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$277, $$303)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                         -- HYBRID_HASH_JOIN [$$277][$$303]  |PARTITIONED|
+                          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00025E11]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$313, $$277, $$309, $$285, $$287]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00025E11]
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00025E11]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$326, $$300)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00025E11]
                                 -- HYBRID_HASH_JOIN [$$326][$$300]  |PARTITIONED|
+                                  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.6E7]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$326] <- [numeric-mod(numeric-multiply($$275, $$276), 10000)] project: [$$313, $$309, $$285, $$287, $$326] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.6E7]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$313, $$309, $$285, $$275, $$276, $$287]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.6E7]
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.6E7]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          join (eq($$288, $$304)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 1.6E7]
                                           -- HYBRID_HASH_JOIN [$$288][$$304]  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1.2E7]
                                             -- HASH_PARTITION_EXCHANGE [$$288]  |PARTITIONED|
+                                              project ([$$313, $$309, $$285, $$275, $$276, $$288]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1.1E7]
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1.2E7]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  join (and(eq($$305, $$291), eq($$306, $$293), eq($$307, $$295))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 1.1E7]
                                                   -- HYBRID_HASH_JOIN [$$291, $$293, $$295][$$305, $$306, $$307]  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 7000000.0]
                                                     -- HASH_PARTITION_EXCHANGE [$$291, $$293, $$295]  |PARTITIONED|
+                                                      project ([$$313, $$309, $$275, $$276, $$291, $$293, $$295]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 7000000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          join (and(eq($$310, $$275), eq($$311, $$276))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 6000000.0]
                                                           -- HYBRID_HASH_JOIN [$$275, $$276][$$310, $$311]  |PARTITIONED|
+                                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                             -- HASH_PARTITION_EXCHANGE [$$275, $$276]  |PARTITIONED|
+                                                              assign [$$276, $$275] <- [$$s.getField("s_i_id"), $$s.getField("s_w_id")] project: [$$275, $$276] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                project ([$$s]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                                    data-scan []<-[$$278, $$s] <- test.stock [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                             -- HASH_PARTITION_EXCHANGE [$$310, $$311]  |PARTITIONED|
+                                                              select (and(ge($$284, "2017-01-01 00:00:00.000000"), le($$284, "2018-12-31 00:00:00.000000"))) project: [$$313, $$309, $$291, $$293, $$295, $$310, $$311] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                               -- STREAM_SELECT  |PARTITIONED|
+                                                                assign [$$313, $$311, $$310, $$284] <- [$$ol.getField("ol_amount"), $$ol.getField("ol_i_id"), $$ol.getField("ol_supply_w_id"), $$ol.getField("ol_delivery_d")] project: [$$309, $$295, $$293, $$291, $$313, $$311, $$310, $$284] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                 -- ASSIGN  |PARTITIONED|
+                                                                  unnest $$ol <- scan-collection($$302) project: [$$309, $$295, $$293, $$291, $$ol] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                   -- UNNEST  |PARTITIONED|
+                                                                    assign [$$309, $$295, $$293, $$291, $$302] <- [$$o.getField("o_entry_d"), $$o.getField("o_d_id"), $$o.getField("o_w_id"), $$o.getField("o_c_id"), $$o.getField("o_orderline")] project: [$$309, $$295, $$293, $$291, $$302] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      project ([$$o]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                          -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                                          data-scan []<-[$$279, $$o] <- test.orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              empty-tuple-source
                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                     -- HASH_PARTITION_EXCHANGE [$$305, $$306, $$307]  |PARTITIONED|
+                                                      assign [$$288] <- [get-item(string-to-codepoint($$285), 0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        assign [$$307, $$306, $$305, $$285] <- [$$c.getField("c_d_id"), $$c.getField("c_w_id"), $$c.getField("c_id"), $$c.getField("c_state")] project: [$$307, $$306, $$305, $$285] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN (test.customer)  |PARTITIONED|
+                                                              data-scan []<-[$$280, $$c] <- test.customer [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                             -- HASH_PARTITION_EXCHANGE [$$304]  |PARTITIONED|
+                                              replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- REPLICATE  |PARTITIONED|
+                                                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  assign [$$304, $$287] <- [$$n2.getField("n_nationkey"), $$n2.getField("n_name")] project: [$$287, $$304] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    project ([$$n2]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                        data-scan []<-[$$282, $$n2] <- test.nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$300, $$277] <- [$$su.getField("su_suppkey"), $$su.getField("su_nationkey")] project: [$$277, $$300] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$su]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                          data-scan []<-[$$283, $$su] <- test.supplier [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$286, $$303] <- [$$287, $$304] project: [$$286, $$303] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ASSIGN  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$304, $$287] <- [$$n2.getField("n_nationkey"), $$n2.getField("n_name")] project: [$$287, $$304] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$n2]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                          data-scan []<-[$$282, $$n2] <- test.nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q8.plan
index d3a0c1a..c663bd1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q8.plan
@@ -1,114 +1,222 @@
+distribute result [$$293] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$293] <- [{"l_year": $#1, "mkt_share": round(numeric-divide($$322, $$323), 2)}] project: [$$293] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
       -- SORT_MERGE_EXCHANGE [$#1(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$351]  |PARTITIONED|
-                {
+        group by ([$#1 := $$351]) decor ([]) {
+                  aggregate [$$322, $$323] <- [agg-global-sql-sum($$349), agg-global-sql-sum($$350)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+        -- SORT_GROUP_BY[$$351]  |PARTITIONED|
+          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
           -- HASH_PARTITION_EXCHANGE [$$351]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$294]  |PARTITIONED|
-                    {
+            group by ([$$351 := $$294]) decor ([]) {
+                      aggregate [$$349, $$350] <- [agg-local-sql-sum(switch-case(true, eq($$342, "Germany"), $$335, 0)), agg-local-sql-sum($$335)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+            -- SORT_GROUP_BY[$$294]  |PARTITIONED|
+              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$294] <- [get-year(date($$305))] project: [$$342, $$335, $$294] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$335, $$305, $$342]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (eq($$325, $$326)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                       -- HYBRID_HASH_JOIN [$$325][$$326]  |PARTITIONED|
+                        exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$335, $$305, $$325]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              join (eq($$348, $$341)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                               -- HYBRID_HASH_JOIN [$$348][$$341]  |PARTITIONED|
+                                exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$348] <- [numeric-mod(numeric-multiply($$295, $$296), 10000)] project: [$$335, $$305, $$348] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$335, $$305, $$295, $$296]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        join (eq($$308, $$309)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                                         -- HYBRID_HASH_JOIN [$$308][$$309]  |PARTITIONED|
+                                          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00025E11]
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            project ([$$335, $$305, $$295, $$296, $$308]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00025E11]
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00025E11]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                join (eq($$331, $$311)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00025E11]
                                                 -- HYBRID_HASH_JOIN [$$311][$$331]  |PARTITIONED|
+                                                  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.6E7]
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    project ([$$335, $$305, $$295, $$296, $$311]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.6E7]
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.6E7]
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        join (eq($$324, $$306)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 1.6E7]
                                                         -- HYBRID_HASH_JOIN [$$306][$$324]  |PARTITIONED|
+                                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1.2E7]
                                                           -- HASH_PARTITION_EXCHANGE [$$306]  |PARTITIONED|
+                                                            project ([$$335, $$305, $$295, $$296, $$311, $$306]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1.1E7]
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1.2E7]
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                join (and(eq($$333, $$313), eq($$334, $$315), eq($$332, $$317))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 1.1E7]
                                                                 -- HYBRID_HASH_JOIN [$$313, $$315, $$317][$$333, $$334, $$332]  |PARTITIONED|
+                                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 7000000.0]
                                                                   -- HASH_PARTITION_EXCHANGE [$$313, $$315, $$317]  |PARTITIONED|
+                                                                    project ([$$335, $$305, $$295, $$296, $$306, $$313, $$315, $$317]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                      exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 7000000.0]
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        join (and(eq($$306, $$296), eq($$336, $$295))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 6000000.0]
                                                                         -- HYBRID_HASH_JOIN [$$296, $$295][$$306, $$336]  |PARTITIONED|
+                                                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                           -- HASH_PARTITION_EXCHANGE [$$296, $$295]  |PARTITIONED|
+                                                                            assign [$$296, $$295] <- [$$s.getField("s_i_id"), $$s.getField("s_w_id")] project: [$$295, $$296] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                             -- ASSIGN  |PARTITIONED|
+                                                                              project ([$$s]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                                                  data-scan []<-[$$297, $$s] <- test.stock [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      empty-tuple-source
                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                           -- HASH_PARTITION_EXCHANGE [$$306, $$336]  |PARTITIONED|
+                                                                            select (lt($$306, 1000)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                                              assign [$$336, $$335, $$306] <- [$$ol.getField("ol_supply_w_id"), $$ol.getField("ol_amount"), $$ol.getField("ol_i_id")] project: [$$317, $$315, $$313, $$305, $$336, $$335, $$306] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                unnest $$ol <- scan-collection($$327) project: [$$317, $$315, $$313, $$305, $$ol] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                 -- UNNEST  |PARTITIONED|
+                                                                                  select (and(le($$305, "2018-12-31 00:00:00.000000"), ge($$305, "2017-01-01 00:00:00.000000")))
                                                                                   -- STREAM_SELECT  |PARTITIONED|
+                                                                                    assign [$$317, $$315, $$313, $$305, $$327] <- [$$o.getField("o_c_id"), $$o.getField("o_d_id"), $$o.getField("o_w_id"), $$o.getField("o_entry_d"), $$o.getField("o_orderline")] project: [$$317, $$315, $$313, $$305, $$327] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                      project ([$$o]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                          -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                                                          data-scan []<-[$$298, $$o] <- test.orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              empty-tuple-source
                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                   -- HASH_PARTITION_EXCHANGE [$$333, $$334, $$332]  |PARTITIONED|
+                                                                    assign [$$311, $$334, $$333, $$332] <- [get-item(string-to-codepoint($$c.getField("c_state")), 0), $$c.getField("c_d_id"), $$c.getField("c_w_id"), $$c.getField("c_id")] project: [$$311, $$333, $$334, $$332] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                     -- ASSIGN  |PARTITIONED|
+                                                                      project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                          -- DATASOURCE_SCAN (test.customer)  |PARTITIONED|
+                                                                          data-scan []<-[$$300, $$c] <- test.customer [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              empty-tuple-source
                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                           -- HASH_PARTITION_EXCHANGE [$$324]  |PARTITIONED|
+                                                            select (like($$i.getField("i_data"), "%b")) project: [$$324] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                              assign [$$324] <- [$$i.getField("i_id")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                project ([$$i]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- DATASOURCE_SCAN (test.item)  |PARTITIONED|
+                                                                    data-scan []<-[$$299, $$i] <- test.item [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                      exchange
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        empty-tuple-source
                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                    assign [$$331, $$308] <- [$$n1.getField("n_nationkey"), $$n1.getField("n_regionkey")] project: [$$308, $$331] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- REPLICATE  |PARTITIONED|
+                                                          exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            project ([$$n1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                              exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                                data-scan []<-[$$301, $$n1] <- test.nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  exchange
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    empty-tuple-source
                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            select (eq($$r.getField("r_name"), "Europe")) project: [$$309] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- STREAM_SELECT  |PARTITIONED|
+                                              assign [$$309] <- [$$r.getField("r_regionkey")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$r]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (test.region)  |PARTITIONED|
+                                                    data-scan []<-[$$302, $$r] <- test.region [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  assign [$$341, $$325] <- [$$su.getField("su_suppkey"), $$su.getField("su_nationkey")] project: [$$325, $$341] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$su]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                        data-scan []<-[$$303, $$su] <- test.supplier [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          assign [$$342, $$326] <- [$$n2.getField("n_name"), $$n2.getField("n_nationkey")] project: [$$342, $$326] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ASSIGN  |PARTITIONED|
+                            assign [$$n2] <- [$$n1] project: [$$n2] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ASSIGN  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$n1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                        data-scan []<-[$$301, $$n1] <- test.nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q9.plan
index d59c9cf..d078a41 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q9.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/ch2/ch2_q9.plan
@@ -1,71 +1,136 @@
+distribute result [$$196] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$196] <- [{"n_name": $$n_name, "l_year": $#1, "SUM_profit": round($$212, 2)}] project: [$$196] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
       -- SORT_MERGE_EXCHANGE [$$n_name(ASC), $#1(DESC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$231, $$232]  |PARTITIONED|
-                {
+        group by ([$$n_name := $$231; $#1 := $$232]) decor ([]) {
+                  aggregate [$$212] <- [agg-global-sql-sum($$230)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+        -- SORT_GROUP_BY[$$231, $$232]  |PARTITIONED|
+          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
           -- HASH_PARTITION_EXCHANGE [$$231, $$232]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$225, $$198]  |PARTITIONED|
-                    {
+            group by ([$$231 := $$225; $$232 := $$198]) decor ([]) {
+                      aggregate [$$230] <- [agg-local-sql-sum($$218)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+            -- SORT_GROUP_BY[$$225, $$198]  |PARTITIONED|
+              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$198] <- [get-year(date($$219))] project: [$$218, $$225, $$198] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$218, $$219, $$225]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (eq($$213, $$214)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                       -- HYBRID_HASH_JOIN [$$213][$$214]  |PARTITIONED|
+                        exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.0002E11]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$218, $$219, $$213]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.0002E11]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.0002E11]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              join (eq($$229, $$224)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.0002E11]
                               -- HYBRID_HASH_JOIN [$$229][$$224]  |PARTITIONED|
+                                exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  assign [$$229] <- [numeric-mod(numeric-multiply($$199, $$200), 10000)] project: [$$218, $$219, $$229] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$218, $$219, $$199, $$200]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        join (eq($$206, $$207)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 1.1E7]
                                         -- HYBRID_HASH_JOIN [$$206][$$207]  |PARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 7000000.0]
                                           -- HASH_PARTITION_EXCHANGE [$$206]  |PARTITIONED|
+                                            project ([$$218, $$219, $$199, $$200, $$206]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 7000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                join (and(eq($$206, $$200), eq($$217, $$199))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 6000000.0]
                                                 -- HYBRID_HASH_JOIN [$$200, $$199][$$206, $$217]  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                   -- HASH_PARTITION_EXCHANGE [$$200, $$199]  |PARTITIONED|
+                                                    assign [$$200, $$199] <- [$$s.getField("s_i_id"), $$s.getField("s_w_id")] project: [$$199, $$200] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$s]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                          data-scan []<-[$$201, $$s] <- test.stock [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                   -- HASH_PARTITION_EXCHANGE [$$206, $$217]  |PARTITIONED|
+                                                    assign [$$218, $$217, $$206] <- [$$ol.getField("ol_amount"), $$ol.getField("ol_supply_w_id"), $$ol.getField("ol_i_id")] project: [$$218, $$219, $$206, $$217] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      unnest $$ol <- scan-collection($$215) project: [$$219, $$ol] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- UNNEST  |PARTITIONED|
+                                                        assign [$$219, $$215] <- [$$o.getField("o_entry_d"), $$o.getField("o_orderline")] project: [$$219, $$215] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          project ([$$o]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                              data-scan []<-[$$202, $$o] <- test.orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                           -- HASH_PARTITION_EXCHANGE [$$207]  |PARTITIONED|
+                                            select (like($$i.getField("i_data"), "%bb")) project: [$$207] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- STREAM_SELECT  |PARTITIONED|
+                                              assign [$$207] <- [$$i.getField("i_id")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$i]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (test.item)  |PARTITIONED|
+                                                    data-scan []<-[$$203, $$i] <- test.item [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  assign [$$224, $$213] <- [$$su.getField("su_suppkey"), $$su.getField("su_nationkey")] project: [$$213, $$224] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$su]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                        data-scan []<-[$$204, $$su] <- test.supplier [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          assign [$$225, $$214] <- [$$n.getField("n_name"), $$n.getField("n_nationkey")] project: [$$225, $$214] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$n]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                data-scan []<-[$$205, $$n] <- test.nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/column-pushdown/meta.001.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/column-pushdown/meta.001.plan
index 1530eeb..a925c5a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/column-pushdown/meta.001.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/column-pushdown/meta.001.plan
@@ -1,107 +1,208 @@
+distribute result [$$176]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$176] <- [{"s_i_id": $$s_i_id, "ordercount": $$194}] project: [$$176]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$194(DESC) ]  |PARTITIONED|
+        order (DESC, $$194)
         -- STABLE_SORT [$$194(DESC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$s_i_id, $$194])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (gt($$193, $$208))
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$223]  |PARTITIONED|
-                            {
+                    group by ([$$s_i_id := $$223]) decor ([]) {
+                              aggregate [$$193, $$194] <- [agg-global-sql-sum($$221), agg-global-sql-sum($$222)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           } [cardinality: 0.0, op-cost: 0.0, total-cost: 5.00015E11]
+                    -- SORT_GROUP_BY[$$223]  |PARTITIONED|
+                      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                       -- HASH_PARTITION_EXCHANGE [$$223]  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$178]  |PARTITIONED|
-                                {
+                        group by ([$$223 := $$178]) decor ([]) {
+                                  aggregate [$$221, $$222] <- [agg-local-sql-sum($$142), agg-local-sql-sum($$142)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               } [cardinality: 0.0, op-cost: 0.0, total-cost: 5.00015E11]
+                        -- SORT_GROUP_BY[$$178]  |PARTITIONED|
+                          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$142, $$178]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$191, $$192)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00015E11]
                                 -- HYBRID_HASH_JOIN [$$192][$$191]  |PARTITIONED|
+                                  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$192]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        join (eq($$206, $$207)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                         -- HYBRID_HASH_JOIN [$$207][$$206]  |PARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$207] <- [$$212] project: [$$207] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                   -- HASH_PARTITION_EXCHANGE [$$212]  |PARTITIONED|
+                                                    select (eq($$197.getField("n_name"), "Germany")) project: [$$212] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                      assign [$$212] <- [$$197.getField("n_nationkey")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$197]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                            data-scan []<-[$$204, $$197, $$205] <- test.nation project ({n_nationkey:any,n_name:any}) project-meta ({}) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$192, $$206] <- [$$210, $$211] project: [$$192, $$206] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                   -- HASH_PARTITION_EXCHANGE [$$211]  |PARTITIONED|
+                                                    assign [$$210, $$211] <- [$$198.getField("su_suppkey"), $$198.getField("su_nationkey")] project: [$$210, $$211] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$198]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                                          data-scan []<-[$$202, $$198, $$203] <- test.supplier project ({su_suppkey:any,su_nationkey:any}) project-meta ({}) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    assign [$$191] <- [numeric-mod(numeric-multiply($$s.getField("s_w_id"), $$178), 10000)] project: [$$142, $$178, $$191] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- ASSIGN  |PARTITIONED|
+                                      assign [$$178, $$142] <- [$$s.getField("s_i_id"), $$s.getField("s_order_cnt")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$s]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                  data-scan []<-[$$183, $$s, $$184] <- test.stock project ({s_w_id:any,s_i_id:any,s_order_cnt:any}) project-meta ({}) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    assign [$$208] <- [get-item($$167, 0)] project: [$$208] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                     -- ASSIGN  |UNPARTITIONED|
+                      aggregate [$$167] <- [listify($$166)] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                       -- AGGREGATE  |UNPARTITIONED|
+                        assign [$$166] <- [numeric-multiply($$220, 5.0E-5)] project: [$$166] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                         -- ASSIGN  |UNPARTITIONED|
+                          aggregate [$$220] <- [agg-global-sql-sum($$224)] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                           -- AGGREGATE  |UNPARTITIONED|
+                            exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                             -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                              aggregate [$$224] <- [agg-local-sql-sum($$163)] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                               -- AGGREGATE  |PARTITIONED|
+                                project ([$$163]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (eq($$209, $$210)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00015E11]
                                     -- HYBRID_HASH_JOIN [$$210][$$209]  |PARTITIONED|
+                                      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        project ([$$210]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            join (eq($$211, $$212)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                             -- HYBRID_HASH_JOIN [$$212][$$211]  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                   -- HASH_PARTITION_EXCHANGE [$$212]  |PARTITIONED|
+                                                    select (eq($$197.getField("n_name"), "Germany")) project: [$$212] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                      assign [$$212] <- [$$197.getField("n_nationkey")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$197]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                                                            data-scan []<-[$$204, $$197, $$205] <- test.nation project ({n_nationkey:any,n_name:any}) project-meta ({}) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                   -- HASH_PARTITION_EXCHANGE [$$211]  |PARTITIONED|
+                                                    assign [$$210, $$211] <- [$$198.getField("su_suppkey"), $$198.getField("su_nationkey")] project: [$$210, $$211] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$198]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                                          data-scan []<-[$$202, $$198, $$203] <- test.supplier project ({su_suppkey:any,su_nationkey:any}) project-meta ({}) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        assign [$$209, $$163] <- [numeric-mod(numeric-multiply($$199.getField("s_w_id"), $$199.getField("s_i_id")), 10000), $$199.getField("s_order_cnt")] project: [$$163, $$209] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- ASSIGN  |PARTITIONED|
+                                          assign [$$199] <- [$$s] project: [$$199] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- REPLICATE  |PARTITIONED|
+                                                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  project ([$$s]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.stock)  |PARTITIONED|
+                                                      data-scan []<-[$$183, $$s, $$184] <- test.stock project ({s_w_id:any,s_i_id:any,s_order_cnt:any}) project-meta ({}) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/extract-common-operators/extract-common-operators.01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/extract-common-operators/extract-common-operators.01.plan
index e0c2670..6984dda 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/extract-common-operators/extract-common-operators.01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/extract-common-operators/extract-common-operators.01.plan
@@ -1,92 +1,184 @@
+distribute result [$$397]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$397] <- [{"DataverseName": $$405, "SynonymName": $$406}] project: [$$397]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$405(ASC), $$406(ASC) ]  |PARTITIONED|
+        order (ASC, $$405) (ASC, $$406)
         -- STABLE_SORT [$$405(ASC), $$406(ASC)]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$405, $$406])
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                left outer join (eq($$414, $$410))
                 -- HYBRID_HASH_JOIN [$$414][$$410]  |PARTITIONED|
+                  exchange
                   -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$405(ASC), $$406(ASC)] HASH:[$$414]  |PARTITIONED|
+                    order (ASC, $$405) (ASC, $$406)
                     -- STABLE_SORT [$$405(ASC), $$406(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$405, $$406, $$414])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            left outer join (eq($$408, $$414))
                             -- HYBRID_HASH_JOIN [$$414][$$408]  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$414]  |PARTITIONED|
+                                assign [$$414] <- [$$s.getField(3)] project: [$$405, $$406, $$414]
                                 -- ASSIGN  |PARTITIONED|
+                                  assign [$$405, $$406, $$s] <- [$$409, $$410, $$s] project: [$$405, $$406, $$s]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      replicate
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (Metadata.Synonym)  |PARTITIONED|
+                                          data-scan []<-[$$409, $$410, $$s] <- Metadata.Synonym
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- HASH_PARTITION_EXCHANGE [$$408]  |PARTITIONED|
+                                project ([$$408])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (and(eq($$408, $$ds_name), eq($$407, $$dv_name)))
                                     -- HYBRID_HASH_JOIN [$$408, $$407][$$ds_name, $$dv_name]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$408, $$407]  |PARTITIONED|
+                                            project ([$$408, $$407])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (Metadata.Dataset)  |PARTITIONED|
+                                                data-scan []<-[$$407, $$408, $$d] <- Metadata.Dataset
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$ds_name, $$dv_name]  |PARTITIONED|
+                                        join (true)
                                         -- NESTED_LOOP  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            unnest $$dv_name <- scan-collection(array: [ "test2", "test1" ])
                                             -- UNNEST  |UNPARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            replicate
                                             -- REPLICATE  |UNPARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                unnest $$ds_name <- scan-collection(array: [ "ds2", "ds1" ])
                                                 -- UNNEST  |UNPARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                  exchange
                   -- HASH_PARTITION_EXCHANGE [$$410]  |PARTITIONED|
+                    project ([$$410])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        left outer join (eq($$412, $$428))
                         -- HYBRID_HASH_JOIN [$$428][$$412]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$428]  |PARTITIONED|
+                            project ([$$410, $$428])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$410, $$syn_name))
                                 -- HYBRID_HASH_JOIN [$$410][$$syn_name]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$410]  |PARTITIONED|
+                                    assign [$$428] <- [$$s.getField(3)] project: [$$410, $$428]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$410, $$s])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (Metadata.Synonym)  |PARTITIONED|
+                                              data-scan []<-[$$409, $$410, $$s] <- Metadata.Synonym
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$syn_name]  |PARTITIONED|
+                                    unnest $$syn_name <- scan-collection(array: [ "syn2", "syn1" ])
                                     -- UNNEST  |UNPARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$412]  |PARTITIONED|
+                            project ([$$412])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (and(eq($$412, $$ds_name), eq($$411, $$dv_name)))
                                 -- HYBRID_HASH_JOIN [$$412, $$411][$$ds_name, $$dv_name]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$412, $$411] <- [$$408, $$407] project: [$$412, $$411]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        replicate
                                         -- REPLICATE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$408, $$407]  |PARTITIONED|
+                                            project ([$$408, $$407])
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (Metadata.Dataset)  |PARTITIONED|
+                                                data-scan []<-[$$407, $$408, $$d] <- Metadata.Dataset
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$ds_name, $$dv_name]  |PARTITIONED|
+                                    join (true)
                                     -- NESTED_LOOP  |UNPARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        assign [$$ds_name] <- [$$ds_name] project: [$$ds_name]
                                         -- ASSIGN  |UNPARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            replicate
                                             -- REPLICATE  |UNPARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                unnest $$ds_name <- scan-collection(array: [ "ds2", "ds1" ])
                                                 -- UNNEST  |UNPARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        unnest $$dv_name <- scan-collection(array: [ "test2", "test1" ])
                                         -- UNNEST  |UNPARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/filter/inverted-btree-search-return-optional-field.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/filter/inverted-btree-search-return-optional-field.plan
index a76d642..22cd3c6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/filter/inverted-btree-search-return-optional-field.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/filter/inverted-btree-search-return-optional-field.plan
@@ -1,27 +1,54 @@
+distribute result [$$38]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 2147483647 offset 0
     -- STREAM_LIMIT  |UNPARTITIONED|
+      assign [$$38] <- [{"place.bounding_box": $$45, "user.id": $$46, "id": $$41, "coordinate": $$48, "create_at": $$40}] project: [$$38]
       -- ASSIGN  |PARTITIONED|
+        exchange
         -- SORT_MERGE_EXCHANGE [$$40(DESC) ]  |PARTITIONED|
+          limit 2147483647
           -- STREAM_LIMIT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (topK: 2147483647) (DESC, $$40)
               -- STABLE_SORT [topK: 2147483647] [$$40(DESC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$45, $$46, $$41, $$48, $$40])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      join (eq($$42, $$27))
                       -- HYBRID_HASH_JOIN [$$27][$$42]  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          select (and(ftcontains($$t.getField(2), array: [ "francisco" ], "mode", "all"), ge($$40, datetime: { 2018-02-22T10:53:07.888 }), lt($$40, datetime: { 2018-02-22T18:50:39.301 }))) project: [$$45, $$46, $$41, $$48, $$40, $$27]
                           -- STREAM_SELECT  |PARTITIONED|
+                            assign [$$27, $$45, $$46, $$48, $$40] <- [$$t.getField(14).getField(0), $$t.getField(13).getField(6), $$t.getField(12).getField(0), $$t.getField(6), $$t.getField(0)]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (twitter.ds_tweet.ds_tweet)  |PARTITIONED|
+                                unnest-map [$$41, $$t] <- index-search("ds_tweet", 0, "Default", "twitter", "ds_tweet", false, false, 1, $$53, 1, $$53, true, true, true) with filter on min:[$$54] max:[$$55]
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    order (ASC, $$53)
                                     -- STABLE_SORT [$$53(ASC)]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- SINGLE_PARTITION_INVERTED_INDEX_SEARCH (twitter.ds_tweet.text_idx)  |PARTITIONED|
+                                        unnest-map [$$53, $$54, $$55] <- index-search("text_idx", 2, "Default", "twitter", "ds_tweet", false, false, 0, null, 21, true, 1, $$52)
+                                        -- SINGLE_PARTITION_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$52] <- [array: [ "francisco" ]]
                                             -- ASSIGN  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          unnest $$42 <- scan-collection(array: [ 51, 37, 24, 11 ])
                           -- UNNEST  |UNPARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/filter_on_meta_with_idx_2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/filter_on_meta_with_idx_2.plan
index cccf7a1..328ede2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/filter_on_meta_with_idx_2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/filter_on_meta_with_idx_2.plan
@@ -1,22 +1,44 @@
+distribute result [$$33] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$33] <- [{"t": $$t}] project: [$$33] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
     -- ASSIGN  |PARTITIONED|
+      project ([$$t]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$37, $$38)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
           -- HYBRID_HASH_JOIN [$$37][$$38]  |PARTITIONED|
+            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
             -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+              select (gt($$35.getField(2), 100)) project: [$$t, $$37] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$37] <- [$$t.getField(2)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t, $$35]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.KVStore)  |PARTITIONED|
+                      data-scan []<-[$$34, $$t, $$35] <- test.KVStore with filter on min:[$$40] max:[] [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          assign [$$40] <- [100]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
             -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+              assign [$$38] <- [$$o.getField(2)] project: [$$38] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$o]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.OfficerLocations)  |PARTITIONED|
+                    data-scan []<-[$$36, $$o] <- test.OfficerLocations [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/group-by/listify-3.1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/group-by/listify-3.1.plan
index d28f82a..dddf48d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/group-by/listify-3.1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/group-by/listify-3.1.plan
@@ -1,36 +1,72 @@
+distribute result [$$142]
 -- DISTRIBUTE_RESULT  |LOCAL|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    assign [$$142] <- [{"std": round-half-to-even(sqrt($$143), 2)}] project: [$$142]
     -- ASSIGN  |LOCAL|
+      aggregate [$$143] <- [agg-global-sql-avg($$164)]
       -- AGGREGATE  |LOCAL|
+        aggregate [$$164] <- [agg-local-sql-avg($$140)]
         -- AGGREGATE  |LOCAL|
+          assign [$$140] <- [power(numeric-subtract(numeric-add(numeric-subtract($$150, $$t), $$151), 1), 2)] project: [$$140]
           -- ASSIGN  |LOCAL|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+              join (true)
               -- NESTED_LOOP  |LOCAL|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                  join (true)
                   -- NESTED_LOOP  |LOCAL|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                      unnest $$t <- range(1, 10)
                       -- UNNEST  |UNPARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                      assign [$$150] <- [get-item($$111, 0).getField(0)] project: [$$150]
                       -- ASSIGN  |LOCAL|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                          replicate
                           -- REPLICATE  |LOCAL|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                              aggregate [$$111] <- [listify($$110)]
                               -- AGGREGATE  |LOCAL|
+                                assign [$$110] <- [{"mean": $$156, "min": $$157}] project: [$$110]
                                 -- ASSIGN  |LOCAL|
+                                  aggregate [$$156, $$157] <- [agg-global-sql-avg($$162), agg-global-sql-min($$163)]
                                   -- AGGREGATE  |LOCAL|
+                                    aggregate [$$162, $$163] <- [agg-local-sql-avg($$149), agg-local-sql-min($$149)]
                                     -- AGGREGATE  |LOCAL|
+                                      unnest $$149 <- range(1, 10)
                                       -- UNNEST  |UNPARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                  assign [$$151] <- [get-item($$127, 0).getField(1)] project: [$$151]
                   -- ASSIGN  |LOCAL|
+                    assign [$$127] <- [$$111] project: [$$127]
                     -- ASSIGN  |LOCAL|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                        replicate
                         -- REPLICATE  |LOCAL|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                            aggregate [$$111] <- [listify($$110)]
                             -- AGGREGATE  |LOCAL|
+                              assign [$$110] <- [{"mean": $$156, "min": $$157}] project: [$$110]
                               -- ASSIGN  |LOCAL|
+                                aggregate [$$156, $$157] <- [agg-global-sql-avg($$162), agg-global-sql-min($$163)]
                                 -- AGGREGATE  |LOCAL|
+                                  aggregate [$$162, $$163] <- [agg-local-sql-avg($$149), agg-local-sql-min($$149)]
                                   -- AGGREGATE  |LOCAL|
+                                    unnest $$149 <- range(1, 10)
                                     -- UNNEST  |UNPARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/hash-join-with-redundant-variable/hash-join-with-redundant-variable.1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/hash-join-with-redundant-variable/hash-join-with-redundant-variable.1.plan
index 9e8ccb3..95c927f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/hash-join-with-redundant-variable/hash-join-with-redundant-variable.1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/hash-join-with-redundant-variable/hash-join-with-redundant-variable.1.plan
@@ -1,67 +1,134 @@
+distribute result [$$131] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    aggregate [$$131] <- [agg-sql-sum($$141)] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
     -- AGGREGATE  |UNPARTITIONED|
+      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+        aggregate [$$141] <- [agg-sql-count(1)] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
         -- AGGREGATE  |PARTITIONED|
+          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$136, $$137)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
             -- HYBRID_HASH_JOIN [$$136][$$137]  |PARTITIONED|
+              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$136]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$123, $$124)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                     -- HYBRID_HASH_JOIN [$$123][$$124]  |PARTITIONED|
+                      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$123]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (and(eq($$134, $$135), eq($$122, $$123))) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                             -- HYBRID_HASH_JOIN [$$134, $$122][$$135, $$123]  |PARTITIONED|
+                              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$122, $$134]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (eq($$138, $$139)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00015E11]
                                     -- HYBRID_HASH_JOIN [$$139][$$138]  |PARTITIONED|
+                                      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        project ([$$122, $$139]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            join (eq($$132, $$133)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                             -- HYBRID_HASH_JOIN [$$132][$$133]  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                               -- HASH_PARTITION_EXCHANGE [$$132]  |PARTITIONED|
+                                                assign [$$122, $$132] <- [$$c.getField("c_nationkey"), $$c.getField("c_custkey")] project: [$$122, $$132] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (test.customer)  |PARTITIONED|
+                                                      data-scan []<-[$$127, $$c] <- test.customer [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                               -- HASH_PARTITION_EXCHANGE [$$133]  |PARTITIONED|
+                                                select (and(ge($$121, "1993-01-01"), lt($$121, "1993-04-01"))) project: [$$139, $$133] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                  assign [$$139, $$133, $$121] <- [$$o.getField("o_orderkey"), $$o.getField("o_custkey"), $$o.getField("o_orderdate")] project: [$$139, $$133, $$121] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    project ([$$o]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                                        data-scan []<-[$$128, $$o] <- test.orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        assign [$$134, $$138] <- [$$l.getField("l_suppkey"), $$l.getField("l_orderkey")] project: [$$134, $$138] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$l]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.lineitem)  |PARTITIONED|
+                                              data-scan []<-[$$129, $$l] <- test.lineitem [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$135, $$123] <- [$$s.getField("s_suppkey"), $$s.getField("s_nationkey")] project: [$$135, $$123] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ASSIGN  |PARTITIONED|
+                                  project ([$$s]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (test.supplier)  |PARTITIONED|
+                                      data-scan []<-[$$130, $$s] <- test.supplier [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        assign [$$124, $$136] <- [$$n.getField("n_nationkey"), $$n.getField("n_regionkey")] project: [$$124, $$136] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$n]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                              data-scan []<-[$$126, $$n] <- test.nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                select (eq($$r.getField("r_name"), "EUROPE")) project: [$$137] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$137] <- [$$r.getField("r_regionkey")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ASSIGN  |PARTITIONED|
+                    project ([$$r]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.region)  |PARTITIONED|
+                        data-scan []<-[$$125, $$r] <- test.region [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/hash-join-with-redundant-variable/hash-join-with-redundant-variable.2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/hash-join-with-redundant-variable/hash-join-with-redundant-variable.2.plan
index 33b0e85..5583ec2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/hash-join-with-redundant-variable/hash-join-with-redundant-variable.2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/hash-join-with-redundant-variable/hash-join-with-redundant-variable.2.plan
@@ -1,32 +1,64 @@
+distribute result [$$73] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    aggregate [$$73] <- [agg-sql-sum($$74)] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
     -- AGGREGATE  |UNPARTITIONED|
+      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+        aggregate [$$74] <- [agg-sql-count(1)] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
         -- AGGREGATE  |PARTITIONED|
+          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$69, $$67)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00015E11]
             -- HYBRID_HASH_JOIN [$$69][$$67]  |PARTITIONED|
+              exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$69]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$68, $$69)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                     -- HYBRID_HASH_JOIN [$$69][$$68]  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                       -- HASH_PARTITION_EXCHANGE [$$69]  |PARTITIONED|
+                        assign [$$69] <- [$$r.getField("x")] project: [$$69] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$r]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.region)  |PARTITIONED|
+                              data-scan []<-[$$70, $$r] <- test.region [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                       -- HASH_PARTITION_EXCHANGE [$$68]  |PARTITIONED|
+                        assign [$$68] <- [$$o.getField("x")] project: [$$68] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ASSIGN  |PARTITIONED|
+                          project ([$$o]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                              data-scan []<-[$$71, $$o] <- test.orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                assign [$$67] <- [$$n.getField("x")] project: [$$67] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$n]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                      data-scan []<-[$$72, $$n] <- test.nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/hash-join-with-redundant-variable/hash-join-with-redundant-variable.3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/hash-join-with-redundant-variable/hash-join-with-redundant-variable.3.plan
index e3bc303..622dfac 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/hash-join-with-redundant-variable/hash-join-with-redundant-variable.3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/hash-join-with-redundant-variable/hash-join-with-redundant-variable.3.plan
@@ -1,34 +1,68 @@
+distribute result [$$76] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    aggregate [$$76] <- [agg-sql-sum($$77)] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
     -- AGGREGATE  |UNPARTITIONED|
+      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+        aggregate [$$77] <- [agg-sql-count(1)] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
         -- AGGREGATE  |PARTITIONED|
+          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            join (eq($$70, $$72)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 1.1E7]
             -- HYBRID_HASH_JOIN [$$70][$$72]  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 7000000.0]
               -- HASH_PARTITION_EXCHANGE [$$70]  |PARTITIONED|
+                project ([$$70]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 7000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (and(eq($$71, $$70), eq($$78, $$79))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 6000000.0]
                     -- HYBRID_HASH_JOIN [$$71, $$79][$$70, $$78]  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$79] <- [$$71] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ASSIGN  |PARTITIONED|
+                          assign [$$71] <- [$$r.getField("x")] project: [$$71] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$r]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.region)  |PARTITIONED|
+                                data-scan []<-[$$73, $$r] <- test.region [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$78] <- [$$70] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ASSIGN  |PARTITIONED|
+                          assign [$$70] <- [$$o.getField("x")] project: [$$70] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$o]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.orders)  |PARTITIONED|
+                                data-scan []<-[$$75, $$o] <- test.orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
               -- HASH_PARTITION_EXCHANGE [$$72]  |PARTITIONED|
+                assign [$$72] <- [$$n.getField("x")] project: [$$72] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$n]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.nation)  |PARTITIONED|
+                      data-scan []<-[$$74, $$n] <- test.nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.1.plan
index 52a0cb5..f0974dc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.1.plan
@@ -1,10 +1,20 @@
+distribute result [$$28] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$28] <- [{"U": $$U, "augmentedUser": $$34}] project: [$$28] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$34.getField("name"), "Glenn")) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$34] <- [object-add($$U, "favoriteColor", "Green")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- ASSIGN  |PARTITIONED|
+          project ([$$U]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Users)  |PARTITIONED|
+              data-scan []<-[$$29, $$U] <- test.Users [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.2.plan
index 52a0cb5..715f323 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.2.plan
@@ -1,10 +1,20 @@
+distribute result [$$40] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$40] <- [{"U": $$U, "augmentedUser1": $$48, "augmentedUser2": object-add($$48, "favoriteCity", "Irvine")}] project: [$$40] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq(object-add($$48, "favoriteCity", "Irvine").getField("name"), "Glenn")) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$48] <- [object-add($$U, "favoriteColor", "Green")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- ASSIGN  |PARTITIONED|
+          project ([$$U]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Users)  |PARTITIONED|
+              data-scan []<-[$$41, $$U] <- test.Users [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.3.plan
index 52a0cb5..dc08904 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.3.plan
@@ -1,10 +1,20 @@
+distribute result [$$29] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"U": $$U, "augmentedUser": $$36}] project: [$$29] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$36.getField("name").getField("first"), "Glenn")) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$36] <- [object-add($$U, "favoriteColor", "Green")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- ASSIGN  |PARTITIONED|
+          project ([$$U]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Users)  |PARTITIONED|
+              data-scan []<-[$$30, $$U] <- test.Users [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.4.plan
index 52a0cb5..b1ff0be 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.4.plan
@@ -1,10 +1,20 @@
+distribute result [$$28] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$28] <- [{"U": $$U, "augmentedUser": $$34}] project: [$$28] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$34.getField("name"), "Glenn")) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$34] <- [object-remove($$U, "favoriteColor")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- ASSIGN  |PARTITIONED|
+          project ([$$U]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Users)  |PARTITIONED|
+              data-scan []<-[$$29, $$U] <- test.Users [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.8.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.8.plan
index 52a0cb5..a8df82f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.8.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.8.plan
@@ -1,10 +1,20 @@
+distribute result [$$30] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$30] <- [{"U": $$U, "augmentedUser": $$36}] project: [$$30] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$36.getField("name"), "Glenn")) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$36] <- [object-concat({ "favoriteColor": "Green" }, $$U, { "birthdate": "10/09/1996" })] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- ASSIGN  |PARTITIONED|
+          project ([$$U]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.Users)  |PARTITIONED|
+              data-scan []<-[$$31, $$U] <- test.Users [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.9.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.9.plan
index a0197f5..39e1e9a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.9.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/index-through-object/index-through-object.9.plan
@@ -1,31 +1,62 @@
+distribute result [$$85] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$85] <- [{"U1": $$U1, "U2": $$U2, "E1": { "name": "Glenn" }, "augmentedUser1": $$105, "augmentedUser2": $$107, "augmentedUser3": { "name": "Glenn", "favoriteColor": "Blue" }}] project: [$$85] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
     -- ASSIGN  |PARTITIONED|
+      project ([$$U1, $$105, $$U2, $$107]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$88, $$89)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
           -- HYBRID_HASH_JOIN [$$88][$$89]  |PARTITIONED|
+            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
             -- HASH_PARTITION_EXCHANGE [$$88]  |PARTITIONED|
+              assign [$$88] <- [$$105.getField("bestFriend")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                select (eq($$105.getField("name"), "John")) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_SELECT  |PARTITIONED|
+                  assign [$$105] <- [object-add($$U1, "favoriteColor", "Green")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ASSIGN  |PARTITIONED|
+                    assign [$$U1] <- [$$U2] project: [$$U1] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ASSIGN  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- REPLICATE  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$U2]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.Users)  |PARTITIONED|
+                                data-scan []<-[$$87, $$U2] <- test.Users [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
             -- HASH_PARTITION_EXCHANGE [$$89]  |PARTITIONED|
+              select (eq($$107.getField("name"), "Sally")) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_SELECT  |PARTITIONED|
+                assign [$$89] <- [$$107.getField(0)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  assign [$$107] <- [object-add($$U2, "favoriteFood", "Pizza")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ASSIGN  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- REPLICATE  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          project ([$$U2]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.Users)  |PARTITIONED|
+                              data-scan []<-[$$87, $$U2] <- test.Users [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/insert-and-scan-dataset.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/insert-and-scan-dataset.plan
index 0fba5fc..92acff0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/insert-and-scan-dataset.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/insert-and-scan-dataset.plan
@@ -1,14 +1,28 @@
+commit
 -- COMMIT  |PARTITIONED|
+  project ([$$17])
   -- STREAM_PROJECT  |PARTITIONED|
+    exchange
     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+      insert into test.myData from record: $$18 partitioned by [$$17]
       -- INSERT_DELETE  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          materialize
           -- MATERIALIZE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$17]  |PARTITIONED|
+              assign [$$17] <- [$$18.getField(0)]
               -- ASSIGN  |PARTITIONED|
+                assign [$$18] <- [cast({"id": numeric-add($$19, 1)})] project: [$$18]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$19])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.myData)  |PARTITIONED|
+                      data-scan []<-[$$19, $$x] <- test.myData
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-contains.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-contains.plan
index da22292..ddbc578 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-contains.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-contains.plan
@@ -1,11 +1,22 @@
+distribute result [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$16(ASC) ]  |PARTITIONED|
+        order (ASC, $$16) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$16(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (contains($$o.getField(2), "Multimedia")) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                data-scan []<-[$$16, $$o] <- test.DBLP [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                -- DATASOURCE_SCAN  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    empty-tuple-source
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-contains_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-contains_ps.plan
index 93ca5bd..d6a002c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-contains_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-contains_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$15)
         -- STABLE_SORT [$$15(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$15(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$20
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField(2), "Multimedia"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                        data-scan []<-[$$15, $$o] <- test.DBLP
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$20] <- [agg-range-map($$18, $$19)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$18, $$19] <- [agg-local-sampling($$15), agg-null-writer($$15)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$15])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField(2), "Multimedia"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                  data-scan []<-[$$15, $$o] <- test.DBLP
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-edit-distance-check.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-edit-distance-check.plan
index 334be33..3dd7b4d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-edit-distance-check.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-edit-distance-check.plan
@@ -1,13 +1,26 @@
+distribute result [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(edit-distance-check($$o.getField(3), "Amihay Motro", 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$16, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$19, 1, $$19, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$19)
               -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                  unnest-map [$$19] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 2, 1, 12, false, 1, $$18)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$18] <- ["Amihay Motro"]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-edit-distance.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-edit-distance.plan
index 334be33..3dd7b4d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-edit-distance.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-edit-distance.plan
@@ -1,13 +1,26 @@
+distribute result [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(edit-distance-check($$o.getField(3), "Amihay Motro", 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$16, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$19, 1, $$19, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$19)
               -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                  unnest-map [$$19] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 2, 1, 12, false, 1, $$18)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$18] <- ["Amihay Motro"]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-fuzzyeq-edit-distance.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-fuzzyeq-edit-distance.plan
index 0589004..3c0111a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-fuzzyeq-edit-distance.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-fuzzyeq-edit-distance.plan
@@ -1,13 +1,26 @@
+distribute result [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(edit-distance-check($$o.getField(3), "Amihay Motro", 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$15, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$18, 1, $$18, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$18)
               -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                  unnest-map [$$18] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 2, 1, 12, false, 1, $$17)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$17] <- ["Amihay Motro"]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-fuzzyeq-jaccard.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-fuzzyeq-jaccard.plan
index b415aa0..5aad331 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-fuzzyeq-jaccard.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-fuzzyeq-jaccard.plan
@@ -1,13 +1,26 @@
+distribute result [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check(gram-tokens($$o.getField(2), 3, false), array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ], 0.8), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$17, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$20)
               -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                  unnest-map [$$20] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 1, 0.8, 21, false, 1, $$19)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$19] <- [array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-jaccard-check.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-jaccard-check.plan
index 76c3b3b..cb69a9a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-jaccard-check.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-jaccard-check.plan
@@ -1,13 +1,26 @@
+distribute result [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check(gram-tokens($$o.getField(2), 3, false), array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ], 0.5), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$18, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$21, 1, $$21, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$21)
               -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                  unnest-map [$$21] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 1, 0.5, 21, false, 1, $$20)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$20] <- [array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-jaccard.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-jaccard.plan
index 76c3b3b..cb69a9a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-jaccard.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ngram-jaccard.plan
@@ -1,13 +1,26 @@
+distribute result [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check(gram-tokens($$o.getField(2), 3, false), array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ], 0.5), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$18, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$21, 1, $$21, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$21)
               -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                  unnest-map [$$21] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 1, 0.5, 21, false, 1, $$20)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$20] <- [array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-edit-distance-check.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-edit-distance-check.plan
index 971ae76..9a480b3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-edit-distance-check.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-edit-distance-check.plan
@@ -1,16 +1,32 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$18(ASC) ]  |PARTITIONED|
+        order (ASC, $$18) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                unnest-map [$$18, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$22, 1, $$22, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$22)
                     -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                        unnest-map [$$22] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$21)
+                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$21] <- [array: [ "computers", "wine", "walking" ]]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-edit-distance-check_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-edit-distance-check_ps.plan
index a88b1e8..19db353 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-edit-distance-check_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-edit-distance-check_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$18) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$18(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$25 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$18, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$22, 1, $$22, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$22)
                             -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$22] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$21)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$21] <- [array: [ "computers", "wine", "walking" ]]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$25] <- [agg-range-map($$23, $$24)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$23, $$24] <- [agg-local-sampling($$18), agg-null-writer($$18)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$18])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- REPLICATE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                                  unnest-map [$$18, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$22, 1, $$22, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$22)
                                       -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                          unnest-map [$$22] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$21)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$21] <- [array: [ "computers", "wine", "walking" ]]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-edit-distance.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-edit-distance.plan
index 971ae76..9a480b3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-edit-distance.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-edit-distance.plan
@@ -1,16 +1,32 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$18(ASC) ]  |PARTITIONED|
+        order (ASC, $$18) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                unnest-map [$$18, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$22, 1, $$22, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$22)
                     -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                        unnest-map [$$22] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$21)
+                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$21] <- [array: [ "computers", "wine", "walking" ]]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-edit-distance_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-edit-distance_ps.plan
index a88b1e8..19db353 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-edit-distance_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-edit-distance_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$18) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$18(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$18(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$25 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$18, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$22, 1, $$22, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$22)
                             -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$22] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$21)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$21] <- [array: [ "computers", "wine", "walking" ]]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$25] <- [agg-range-map($$23, $$24)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$23, $$24] <- [agg-local-sampling($$18), agg-null-writer($$18)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$18])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- REPLICATE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                                  unnest-map [$$18, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$22, 1, $$22, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$22)
                                       -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                          unnest-map [$$22] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$21)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$21] <- [array: [ "computers", "wine", "walking" ]]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-fuzzyeq-edit-distance.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-fuzzyeq-edit-distance.plan
index ad32edd..4fe4266 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-fuzzyeq-edit-distance.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-fuzzyeq-edit-distance.plan
@@ -1,16 +1,32 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$17(ASC) ]  |PARTITIONED|
+        order (ASC, $$17) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                unnest-map [$$17, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$21, 1, $$21, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$21)
                     -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                        unnest-map [$$21] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$20)
+                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$20] <- [array: [ "computers", "wine", "walking" ]]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-fuzzyeq-edit-distance_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-fuzzyeq-edit-distance_ps.plan
index 7a151d5..f6783c3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-fuzzyeq-edit-distance_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-fuzzyeq-edit-distance_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$17) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$17(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$24 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$17, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$21, 1, $$21, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$21)
                             -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$21] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$20)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$20] <- [array: [ "computers", "wine", "walking" ]]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$24] <- [agg-range-map($$22, $$23)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$22, $$23] <- [agg-local-sampling($$17), agg-null-writer($$17)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$17])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- REPLICATE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                                  unnest-map [$$17, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$21, 1, $$21, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$21)
                                       -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                          unnest-map [$$21] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$20)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$20] <- [array: [ "computers", "wine", "walking" ]]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-fuzzyeq-jaccard.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-fuzzyeq-jaccard.plan
index a9465ae..3397661 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-fuzzyeq-jaccard.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-fuzzyeq-jaccard.plan
@@ -1,13 +1,26 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check($$c.getField(4), array: [ "databases", "computers", "wine" ], 0.8), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$16, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$19, 1, $$19, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$19)
               -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                  unnest-map [$$19] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 1, 0.8, 21, false, 1, $$18)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$18] <- [array: [ "databases", "computers", "wine" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-jaccard-check.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-jaccard-check.plan
index 56b3d06..e748999 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-jaccard-check.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-jaccard-check.plan
@@ -1,13 +1,26 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check($$c.getField(4), array: [ "databases", "computers", "wine" ], 0.7), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$17, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$20)
               -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                  unnest-map [$$20] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 1, 0.7, 21, false, 1, $$19)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$19] <- [array: [ "databases", "computers", "wine" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-jaccard.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-jaccard.plan
index 56b3d06..e748999 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-jaccard.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/olist-jaccard.plan
@@ -1,13 +1,26 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check($$c.getField(4), array: [ "databases", "computers", "wine" ], 0.7), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$17, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$20)
               -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                  unnest-map [$$20] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 1, 0.7, 21, false, 1, $$19)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$19] <- [array: [ "databases", "computers", "wine" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ulist-fuzzyeq-jaccard.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ulist-fuzzyeq-jaccard.plan
index a9465ae..c8866f8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ulist-fuzzyeq-jaccard.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ulist-fuzzyeq-jaccard.plan
@@ -1,13 +1,26 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check($$c.getField(4), multiset: {{ "computers", "wine", "databases" }}, 0.8), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$16, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$19, 1, $$19, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$19)
               -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                  unnest-map [$$19] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 1, 0.8, 22, false, 1, $$18)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$18] <- [multiset: {{ "computers", "wine", "databases" }}]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ulist-jaccard-check.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ulist-jaccard-check.plan
index 56b3d06..8b51efc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ulist-jaccard-check.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ulist-jaccard-check.plan
@@ -1,13 +1,26 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check($$c.getField(4), multiset: {{ "computers", "wine", "databases" }}, 0.7), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$17, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$20)
               -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                  unnest-map [$$20] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 1, 0.7, 22, false, 1, $$19)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$19] <- [multiset: {{ "computers", "wine", "databases" }}]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ulist-jaccard.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ulist-jaccard.plan
index 56b3d06..ca0b820 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ulist-jaccard.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/ulist-jaccard.plan
@@ -1,13 +1,26 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check($$c.getField(4), multiset: {{ "computers", "databases", "wine" }}, 0.7), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$17, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$20)
               -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                  unnest-map [$$20] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 1, 0.7, 22, false, 1, $$19)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$19] <- [multiset: {{ "computers", "databases", "wine" }}]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/word-fuzzyeq-jaccard.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/word-fuzzyeq-jaccard.plan
index f4a3522..9420b6e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/word-fuzzyeq-jaccard.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/word-fuzzyeq-jaccard.plan
@@ -1,13 +1,26 @@
+distribute result [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check(word-tokens($$o.getField(2)), array: [ "transactions", "for", "cooperative", "environments" ], 0.5), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$17, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$20, 1, $$20, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$20)
               -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.keyword_index)  |PARTITIONED|
+                  unnest-map [$$20] <- index-search("keyword_index", 4, "Default", "test", "DBLP", false, false, 1, 0.5, 21, false, 1, $$19)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$19] <- [array: [ "transactions", "for", "cooperative", "environments" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/word-jaccard-check.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/word-jaccard-check.plan
index 043f7d4..2a0a78b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/word-jaccard-check.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/word-jaccard-check.plan
@@ -1,13 +1,26 @@
+distribute result [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check(word-tokens($$o.getField(2)), array: [ "transactions", "for", "cooperative", "environments" ], 0.5), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$18, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$21, 1, $$21, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$21)
               -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.keyword_index)  |PARTITIONED|
+                  unnest-map [$$21] <- index-search("keyword_index", 4, "Default", "test", "DBLP", false, false, 1, 0.5, 21, false, 1, $$20)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$20] <- [array: [ "transactions", "for", "cooperative", "environments" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/word-jaccard.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/word-jaccard.plan
index 043f7d4..2a0a78b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/word-jaccard.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-basic/word-jaccard.plan
@@ -1,13 +1,26 @@
+distribute result [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check(word-tokens($$o.getField(2)), array: [ "transactions", "for", "cooperative", "environments" ], 0.5), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$18, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$21, 1, $$21, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$21)
               -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.keyword_index)  |PARTITIONED|
+                  unnest-map [$$21] <- index-search("keyword_index", 4, "Default", "test", "DBLP", false, false, 1, 0.5, 21, false, 1, $$20)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$20] <- [array: [ "transactions", "for", "cooperative", "environments" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-edit-distance-check-let-panic-nopanic_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-edit-distance-check-let-panic-nopanic_01.plan
index b0c4d3b..1d1d468 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-edit-distance-check-let-panic-nopanic_01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-edit-distance-check-let-panic-nopanic_01.plan
@@ -1,14 +1,28 @@
+distribute result [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(get-item(edit-distance-check($$42, "Amihay Motro", 5), 0), get-item(edit-distance-check($$42, "Amihay Motro", 3), 0))) project: [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$42] <- [$$o.getField(3)]
       -- ASSIGN  |PARTITIONED|
+        project ([$$o])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+            unnest-map [$$43, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$45, 1, $$45, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$45)
                 -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                    unnest-map [$$45] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 2, 3, 12, false, 1, $$44)
+                    -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$44] <- ["Amihay Motro"]
                         -- ASSIGN  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-edit-distance-check-let-panic-nopanic_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-edit-distance-check-let-panic-nopanic_02.plan
index b0c4d3b..12c390f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-edit-distance-check-let-panic-nopanic_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-edit-distance-check-let-panic-nopanic_02.plan
@@ -1,14 +1,28 @@
+distribute result [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(get-item(edit-distance-check($$42, "Amihay Motro", 3), 0), get-item(edit-distance-check($$42, "Amihay Motro", 5), 0))) project: [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$42] <- [$$o.getField(3)]
       -- ASSIGN  |PARTITIONED|
+        project ([$$o])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+            unnest-map [$$43, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$45, 1, $$45, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$45)
                 -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                    unnest-map [$$45] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 2, 3, 12, false, 1, $$44)
+                    -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$44] <- ["Amihay Motro"]
                         -- ASSIGN  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-edit-distance-check-let.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-edit-distance-check-let.plan
index f1cac23..e0c0f65 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-edit-distance-check-let.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-edit-distance-check-let.plan
@@ -1,13 +1,26 @@
+distribute result [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(edit-distance-check($$o.getField(3), "Amihay Motro", 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$27, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$30, 1, $$30, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$30)
               -- STABLE_SORT [$$30(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                  unnest-map [$$30] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 2, 1, 12, false, 1, $$29)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$29] <- ["Amihay Motro"]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-edit-distance-check-substring.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-edit-distance-check-substring.plan
index 3321d55..9340293 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-edit-distance-check-substring.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-edit-distance-check-substring.plan
@@ -1,14 +1,28 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$20] <- [{"id": $$22, "title": $$21}] project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (get-item(edit-distance-check(substring($$21, 0, 8), "datbase", 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$21] <- [$$paper.getField(2)] project: [$$22, $$21]
         -- ASSIGN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+            unnest-map [$$22, $$paper] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$25, 1, $$25, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$25)
                 -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                    unnest-map [$$25] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 2, 1, 12, false, 1, $$24)
+                    -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        assign [$$24] <- ["datbase"]
                         -- ASSIGN  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-jaccard-check-let.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-jaccard-check-let.plan
index 06ac713..0626d29 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-jaccard-check-let.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-jaccard-check-let.plan
@@ -1,13 +1,26 @@
+distribute result [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check(gram-tokens($$o.getField(2), 3, false), array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ], 0.5), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$29, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$32, 1, $$32, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$32)
               -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                  unnest-map [$$32] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 1, 0.5, 21, false, 1, $$31)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$31] <- [array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-jaccard-check-multi-let.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-jaccard-check-multi-let.plan
index fb9a209..14694fc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-jaccard-check-multi-let.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ngram-jaccard-check-multi-let.plan
@@ -1,15 +1,30 @@
+distribute result [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$52] <- [{"Paper": $$59, "Query": array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ]}] project: [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (get-item(similarity-jaccard-check($$59, array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ], 0.5), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$59] <- [gram-tokens($$paper.getField(2), 3, false)] project: [$$59]
         -- ASSIGN  |PARTITIONED|
+          project ([$$paper])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+              unnest-map [$$53, $$paper] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$58, 1, $$58, true, true, true)
+              -- BTREE_SEARCH  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$58)
                   -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.ngram_index)  |PARTITIONED|
+                      unnest-map [$$58] <- index-search("ngram_index", 5, "Default", "test", "DBLP", false, false, 1, 0.5, 21, false, 1, $$57)
+                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$57] <- [array: [ "tra", "ran", "ans", "nsa", "sac", "act", "cti", "tio", "ion", "ons", "ns ", "s f", " fo", "for", "or ", "r c", " co", "coo", "oop", "ope", "per", "era", "rat", "ati", "tiv", "ive", "ve ", "e e", " en", "env", "nvi", "vir", "iro", "ron", "onm", "nme", "men", "ent", "nts" ]]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/olist-edit-distance-check-let.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/olist-edit-distance-check-let.plan
index 5b54be6..ee10f14 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/olist-edit-distance-check-let.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/olist-edit-distance-check-let.plan
@@ -1,16 +1,32 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$29(ASC) ]  |PARTITIONED|
+        order (ASC, $$29) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                unnest-map [$$29, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$33, 1, $$33, true, true, true)
+                -- BTREE_SEARCH  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    order (ASC, $$33)
                     -- STABLE_SORT [$$33(ASC)]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                        unnest-map [$$33] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$32)
+                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$32] <- [array: [ "computers", "wine", "walking" ]]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/olist-edit-distance-check-let_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/olist-edit-distance-check-let_ps.plan
index e8039ef..5c3f992 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/olist-edit-distance-check-let_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/olist-edit-distance-check-let_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$29) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$29(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$36 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$29, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$33, 1, $$33, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$33)
                             -- STABLE_SORT [$$33(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$33] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$32)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$32] <- [array: [ "computers", "wine", "walking" ]]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$36] <- [agg-range-map($$34, $$35)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$34, $$35] <- [agg-local-sampling($$29), agg-null-writer($$29)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$29])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- REPLICATE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                                  unnest-map [$$29, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$33, 1, $$33, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$33)
                                       -- STABLE_SORT [$$33(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                          unnest-map [$$33] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$32)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$32] <- [array: [ "computers", "wine", "walking" ]]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/olist-jaccard-check-let.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/olist-jaccard-check-let.plan
index c597083..aff88ea 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/olist-jaccard-check-let.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/olist-jaccard-check-let.plan
@@ -1,13 +1,26 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check($$c.getField(4), array: [ "databases", "computers", "wine" ], 0.7), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$28, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$31, 1, $$31, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$31)
               -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                  unnest-map [$$31] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 1, 0.7, 21, false, 1, $$30)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$30] <- [array: [ "databases", "computers", "wine" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ulist-jaccard-check-let.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ulist-jaccard-check-let.plan
index c597083..aff88ea 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ulist-jaccard-check-let.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/ulist-jaccard-check-let.plan
@@ -1,13 +1,26 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check($$c.getField(4), array: [ "databases", "computers", "wine" ], 0.7), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$c])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+          unnest-map [$$28, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$31, 1, $$31, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$31)
               -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                  unnest-map [$$31] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 1, 0.7, 21, false, 1, $$30)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$30] <- [array: [ "databases", "computers", "wine" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/word-jaccard-check-let.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/word-jaccard-check-let.plan
index c30299a..1b494fc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/word-jaccard-check-let.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/word-jaccard-check-let.plan
@@ -1,13 +1,26 @@
+distribute result [$$o] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (get-item(similarity-jaccard-check(word-tokens($$o.getField(2)), array: [ "transactions", "for", "cooperative", "environments" ], 0.5), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$o])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+          unnest-map [$$29, $$o] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$32, 1, $$32, true, true, true)
+          -- BTREE_SEARCH  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$32)
               -- STABLE_SORT [$$32(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.keyword_index)  |PARTITIONED|
+                  unnest-map [$$32] <- index-search("keyword_index", 4, "Default", "test", "DBLP", false, false, 1, 0.5, 21, false, 1, $$31)
+                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      assign [$$31] <- [array: [ "transactions", "for", "cooperative", "environments" ]]
                       -- ASSIGN  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/word-jaccard-check-multi-let.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/word-jaccard-check-multi-let.plan
index 9feb07e..a0a04d4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/word-jaccard-check-multi-let.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/inverted-index-complex/word-jaccard-check-multi-let.plan
@@ -1,15 +1,30 @@
+distribute result [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$52] <- [{"Paper": $$59, "Query": array: [ "transactions", "for", "cooperative", "environments" ]}] project: [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (get-item(similarity-jaccard-check($$59, array: [ "transactions", "for", "cooperative", "environments" ], 0.8), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        assign [$$59] <- [word-tokens($$paper.getField(2))] project: [$$59]
         -- ASSIGN  |PARTITIONED|
+          project ([$$paper])
           -- STREAM_PROJECT  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+              unnest-map [$$53, $$paper] <- index-search("DBLP", 0, "Default", "test", "DBLP", false, false, 1, $$58, 1, $$58, true, true, true)
+              -- BTREE_SEARCH  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$58)
                   -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.DBLP.keyword_index)  |PARTITIONED|
+                      unnest-map [$$58] <- index-search("keyword_index", 4, "Default", "test", "DBLP", false, false, 1, 0.8, 21, false, 1, $$57)
+                      -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          assign [$$57] <- [array: [ "transactions", "for", "cooperative", "environments" ]]
                           -- ASSIGN  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/joins/inner_right_corr.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/joins/inner_right_corr.plan
index 409f99b..3b990cd 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/joins/inner_right_corr.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/joins/inner_right_corr.plan
@@ -1,51 +1,96 @@
+distribute result [$$75]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$75] <- [{"a": $$73}] project: [$$75]
     -- ASSIGN  |PARTITIONED|
+      project ([$$73])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- PRE_CLUSTERED_GROUP_BY[$$76]  |PARTITIONED|
-                  {
+          group by ([$$94 := $$76]) decor ([]) {
+                    aggregate [$$73] <- [listify($$78)]
                     -- AGGREGATE  |LOCAL|
+                      aggregate [$$78] <- [agg-sql-count(1)]
                       -- AGGREGATE  |LOCAL|
+                        select (not(is-missing($$93)))
                         -- STREAM_SELECT  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 }
+          -- PRE_CLUSTERED_GROUP_BY[$$76]  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$76)
               -- STABLE_SORT [$$76(ASC)]  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$93, $$76])
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      left outer join (eq($$76, $$92))
                       -- HYBRID_HASH_JOIN [$$76][$$92]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$76]  |PARTITIONED|
+                          project ([$$76])
                           -- STREAM_PROJECT  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+                              data-scan []<-[$$76, $$t1] <- test.t1
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$92]  |PARTITIONED|
+                          assign [$$93] <- [true]
                           -- ASSIGN  |PARTITIONED|
+                            unnest $$82 <- scan-collection($$83) project: [$$92]
                             -- UNNEST  |PARTITIONED|
+                              project ([$$92, $$83])
                               -- STREAM_PROJECT  |PARTITIONED|
-                                -- SUBPLAN  |PARTITIONED|
-                                        {
+                                subplan {
+                                          aggregate [$$83] <- [listify($$85)]
                                           -- AGGREGATE  |LOCAL|
+                                            select (eq($$87, $$88))
                                             -- STREAM_SELECT  |LOCAL|
+                                              assign [$$88] <- [$$85.getField("b")]
                                               -- ASSIGN  |LOCAL|
+                                                unnest $$85 <- scan-collection($$90)
                                                 -- UNNEST  |LOCAL|
+                                                  nested tuple source
                                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- SUBPLAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (true) [cardinality: 1.0E12, op-cost: 1.0E12, total-cost: 1.000006E12]
                                     -- NESTED_LOOP  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        assign [$$90] <- [$$91.getField("x")] project: [$$92, $$90]
                                         -- ASSIGN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (test.t1)  |PARTITIONED|
+                                            data-scan []<-[$$92, $$91] <- test.t1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        assign [$$87] <- [$$81.getField("y")] project: [$$87]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$81])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.t2)  |PARTITIONED|
+                                              data-scan []<-[$$84, $$81] <- test.t2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/joins/nlj_partitioning_property_1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/joins/nlj_partitioning_property_1.plan
index 2bb3346..59ba862 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/joins/nlj_partitioning_property_1.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/joins/nlj_partitioning_property_1.plan
@@ -1,28 +1,56 @@
+distribute result [$$75] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$75] <- [{"count": $$82}] project: [$$75] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$82] <- [agg-sql-sum($$84)] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$84] <- [agg-sql-count(1)] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
           -- AGGREGATE  |PARTITIONED|
+            exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 2.000015E12]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (eq($$76, $$78)) [cardinality: 9.223372036854776E16, op-cost: 1.000004E12, total-cost: 2.000015E12]
               -- HYBRID_HASH_JOIN [$$76][$$78]  |PARTITIONED|
+                exchange [cardinality: 1.0E12, op-cost: 0.0, total-cost: 1.000006E12]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (true) [cardinality: 1.0E12, op-cost: 1.0E12, total-cost: 1.000006E12]
                   -- NESTED_LOOP  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$76]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (tpch.Supplier)  |PARTITIONED|
+                          data-scan []<-[$$76, $$s] <- tpch.Supplier [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                      project ([]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (tpch.Part)  |PARTITIONED|
+                          data-scan []<-[$$79, $$p] <- tpch.Part [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  project ([$$78]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (tpch.Partsupp)  |PARTITIONED|
+                      data-scan []<-[$$77, $$78, $$ps] <- tpch.Partsupp [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/joins/nlj_partitioning_property_2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/joins/nlj_partitioning_property_2.plan
index 5d9a2c0..8339bf1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/joins/nlj_partitioning_property_2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/joins/nlj_partitioning_property_2.plan
@@ -1,28 +1,56 @@
+distribute result [$$72] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$72] <- [{"count": $$77}] project: [$$72] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$77] <- [agg-sql-sum($$78)] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$78] <- [agg-sql-count(1)] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
           -- AGGREGATE  |PARTITIONED|
+            exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              join (true) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
               -- NESTED_LOOP  |PARTITIONED|
+                exchange [cardinality: 1.0E12, op-cost: 0.0, total-cost: 1.000006E12]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (true) [cardinality: 1.0E12, op-cost: 1.0E12, total-cost: 1.000006E12]
                   -- NESTED_LOOP  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (tpch.Supplier)  |PARTITIONED|
+                          data-scan []<-[$$73, $$s] <- tpch.Supplier [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                      project ([]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (tpch.Partsupp)  |PARTITIONED|
+                          data-scan []<-[$$74, $$75, $$ps] <- tpch.Partsupp [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  project ([]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (tpch.Part)  |PARTITIONED|
+                      data-scan []<-[$$76, $$p] <- tpch.Part [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/leftouterjoin/loj-03-no-listify.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/leftouterjoin/loj-03-no-listify.plan
index b39c0dd..78ef07b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/leftouterjoin/loj-03-no-listify.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/leftouterjoin/loj-03-no-listify.plan
@@ -1,117 +1,210 @@
+distribute result [$$256] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$256] <- [{"taskId": $$taskId, "cnt_all": $$266, "cnt_x": $$283, "cnt_y": $$284, "cnt_z": $$243.getField(0)}] project: [$$256] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$taskId(ASC) ]  |PARTITIONED|
+        order (ASC, $$taskId) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$taskId(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$taskId, $$266, $$283, $$284, $$243]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                left outer join (eq($$taskId, $$taskId)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                 -- HYBRID_HASH_JOIN [$$taskId][$$taskId]  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$taskId, $$266, $$283, $$284]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        left outer join (eq($$taskId, $$taskId)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00015E11]
                         -- HYBRID_HASH_JOIN [$$taskId][$$taskId]  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$taskId, $$266, $$283]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                left outer join (eq($$taskId, $$taskId)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                 -- HYBRID_HASH_JOIN [$$taskId][$$taskId]  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$taskId(ASC)] HASH:[$$taskId]  |PARTITIONED|
+                                    group by ([$$taskId := $$295]) decor ([]) {
+                                              aggregate [$$266] <- [agg-sql-sum($$294)]
+                                              -- AGGREGATE  |LOCAL|
+                                                nested tuple source
+                                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                           } [cardinality: 0.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- SORT_GROUP_BY[$$295]  |PARTITIONED|
-                                            {
-                                              -- AGGREGATE  |LOCAL|
-                                                -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- HASH_PARTITION_EXCHANGE [$$295]  |PARTITIONED|
+                                        group by ([$$295 := $$258]) decor ([]) {
+                                                  aggregate [$$294] <- [agg-sql-count(1)]
+                                                  -- AGGREGATE  |LOCAL|
+                                                    nested tuple source
+                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                               } [cardinality: 0.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- SORT_GROUP_BY[$$258]  |PARTITIONED|
-                                                {
-                                                  -- AGGREGATE  |LOCAL|
-                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            assign [$$tasks, $$258] <- [$$tasks, $$259] project: [$$258] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    assign [$$259] <- [$$tasks.getField("taskId")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- ASSIGN  |PARTITIONED|
+                                                      project ([$$tasks]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (test.tasks)  |PARTITIONED|
+                                                          data-scan []<-[$$263, $$tasks] <- test.tasks [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$283] <- [{"taskId": $$taskId, "cnt_x": $$274}.getField(0)] project: [$$283, $$taskId]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- SORT_GROUP_BY[$$297]  |PARTITIONED|
-                                                {
+                                        group by ([$$taskId := $$297]) decor ([]) {
+                                                  aggregate [$$274] <- [agg-sql-sum($$296)]
                                                   -- AGGREGATE  |LOCAL|
+                                                    nested tuple source
                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                               }
+                                        -- SORT_GROUP_BY[$$297]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$297]  |PARTITIONED|
-                                            -- SORT_GROUP_BY[$$259]  |PARTITIONED|
-                                                    {
+                                            group by ([$$297 := $$259]) decor ([]) {
+                                                      aggregate [$$296] <- [agg-sql-count(1)]
                                                       -- AGGREGATE  |LOCAL|
+                                                        nested tuple source
                                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                    }
+                                                   }
+                                            -- SORT_GROUP_BY[$$259]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                select (eq($$tasks.getField("status"), "x")) project: [$$259] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- REPLICATE  |PARTITIONED|
+                                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        assign [$$259] <- [$$tasks.getField("taskId")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          project ([$$tasks]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN (test.tasks)  |PARTITIONED|
+                                                              data-scan []<-[$$263, $$tasks] <- test.tasks [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [$$284] <- [{"taskId": $$taskId, "cnt_y": $$275}.getField(0)] project: [$$284, $$taskId]
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- SORT_GROUP_BY[$$299]  |PARTITIONED|
-                                        {
+                                group by ([$$taskId := $$299]) decor ([]) {
+                                          aggregate [$$275] <- [agg-sql-sum($$298)]
                                           -- AGGREGATE  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       }
+                                -- SORT_GROUP_BY[$$299]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$299]  |PARTITIONED|
-                                    -- SORT_GROUP_BY[$$260]  |PARTITIONED|
-                                            {
+                                    group by ([$$299 := $$260]) decor ([]) {
+                                              aggregate [$$298] <- [agg-sql-count(1)]
                                               -- AGGREGATE  |LOCAL|
+                                                nested tuple source
                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                           }
+                                    -- SORT_GROUP_BY[$$260]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        select (eq($$tasks.getField("status"), "y")) project: [$$260] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$tasks, $$260] <- [$$tasks, $$259] project: [$$tasks, $$260]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- REPLICATE  |PARTITIONED|
+                                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  assign [$$259] <- [$$tasks.getField("taskId")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    project ([$$tasks]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (test.tasks)  |PARTITIONED|
+                                                        data-scan []<-[$$263, $$tasks] <- test.tasks [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    assign [$$243] <- [{"taskId": $$taskId, "cnt_z": $$276}] project: [$$243, $$taskId]
                     -- ASSIGN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$301]  |PARTITIONED|
-                                {
+                        group by ([$$taskId := $$301]) decor ([]) {
+                                  aggregate [$$276] <- [agg-sql-sum($$300)]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$301]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$301]  |PARTITIONED|
-                            -- SORT_GROUP_BY[$$261]  |PARTITIONED|
-                                    {
+                            group by ([$$301 := $$261]) decor ([]) {
+                                      aggregate [$$300] <- [agg-sql-count(1)]
                                       -- AGGREGATE  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- SORT_GROUP_BY[$$261]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (eq($$tasks.getField("status"), "z")) project: [$$261] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$tasks, $$261] <- [$$tasks, $$259] project: [$$tasks, $$261]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- REPLICATE  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$259] <- [$$tasks.getField("taskId")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- ASSIGN  |PARTITIONED|
+                                            project ([$$tasks]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- STREAM_PROJECT  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (test.tasks)  |PARTITIONED|
+                                                data-scan []<-[$$263, $$tasks] <- test.tasks [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/leftouterjoin/query-ASTERIXDB-2857.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/leftouterjoin/query-ASTERIXDB-2857.plan
index 79d50d8..11c1c97 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/leftouterjoin/query-ASTERIXDB-2857.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/leftouterjoin/query-ASTERIXDB-2857.plan
@@ -1,34 +1,68 @@
+distribute result [$$133] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$133] <- [{"t0_unique1": $$145, "t1_unique1": $$146, "t2_unique1": $#3}] project: [$$133] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
       -- SORT_MERGE_EXCHANGE [$$145(ASC), $$146(ASC), $#3(ASC) ]  |PARTITIONED|
+        order (ASC, $$145) (ASC, $$146) (ASC, $#3) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
         -- STABLE_SORT [$$145(ASC), $$146(ASC), $#3(ASC)]  |PARTITIONED|
+          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$145, $$146, $#3]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                left outer join (eq(numeric-add($$136, $$138), $$159)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00015E11]
                 -- NESTED_LOOP  |PARTITIONED|
+                  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    assign [$$159] <- [numeric-multiply(2, $$137)] project: [$$145, $$146, $$136, $$159] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                     -- ASSIGN  |PARTITIONED|
+                      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$136, $$137)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                         -- HYBRID_HASH_JOIN [$$136][$$137]  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                           -- HASH_PARTITION_EXCHANGE [$$136]  |PARTITIONED|
+                            assign [$$145] <- [$$tenk.getField(0)] project: [$$145, $$136] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ASSIGN  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                                unnest-map [$$136, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 0, 1, $$160, true, false, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$160] <- [2]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                           -- HASH_PARTITION_EXCHANGE [$$137]  |PARTITIONED|
+                            assign [$$146] <- [$$tenk.getField(0)] project: [$$146, $$137] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ASSIGN  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                                unnest-map [$$137, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 0, 1, $$163, true, false, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                -- BTREE_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$163] <- [4]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                    assign [$#3] <- [{"unique1": $$tenk.getField(0), "unique2": $$138}.getField(0)] project: [$#3, $$138]
                     -- ASSIGN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.tenk.tenk)  |PARTITIONED|
+                        unnest-map [$$138, $$tenk] <- index-search("tenk", 0, "Default", "test", "tenk", false, false, 0, 1, $$166, true, false, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            assign [$$166] <- [6]
                             -- ASSIGN  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/meta/indexes_on_dataset_with_meta_05.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/meta/indexes_on_dataset_with_meta_05.plan
index d7a81cb..2394068 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/meta/indexes_on_dataset_with_meta_05.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/meta/indexes_on_dataset_with_meta_05.plan
@@ -1,19 +1,38 @@
+distribute result [$$29] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$29] <- [{"ds2": $$ds2, "ds1": $$ds1}] project: [$$29] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
     -- ASSIGN  |PARTITIONED|
+      project ([$$ds2, $$ds1]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
         -- SORT_MERGE_EXCHANGE [$$31(ASC) ]  |PARTITIONED|
+          order (ASC, $$31) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
           -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+            exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$ds2, $$ds1, $$31]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (test.DS2.DS2)  |PARTITIONED|
+                  unnest-map [$$31, $$ds2, $$32] <- index-search("DS2", 0, "Default", "test", "DS2", true, true, 1, $$36, 1, $$36, true, true, true) [cardinality: 5.0E11, op-cost: 5.00004E11, total-cost: 5.00009E11]
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      order (ASC, $$36) [cardinality: 5.0E11, op-cost: 5.00004E11, total-cost: 5.00009E11]
                       -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
+                        exchange
                         -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                          assign [$$36] <- [$$ds1.getField(0)]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$ds1])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (test.DS1)  |PARTITIONED|
+                                data-scan []<-[$$33, $$ds1, $$34] <- test.DS1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/meta/indexes_on_dataset_with_meta_08.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/meta/indexes_on_dataset_with_meta_08.plan
index 9dbe5c2..d491acb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/meta/indexes_on_dataset_with_meta_08.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/meta/indexes_on_dataset_with_meta_08.plan
@@ -1,9 +1,18 @@
+distribute result [$$16] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$16] <- [{"DS1": $$DS1}] project: [$$16] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$DS1.getField(0), "2")) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$DS1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (test.DS1)  |PARTITIONED|
+            data-scan []<-[$$17, $$DS1, $$18] <- test.DS1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/multipart-dataverse/index/index-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/multipart-dataverse/index/index-01.plan
index a794105..78851a9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/multipart-dataverse/index/index-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/multipart-dataverse/index/index-01.plan
@@ -1,8 +1,16 @@
+distribute result [$$l]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(eq($$l.getField(1), "Julio"), eq($$l.getField(2), "Isa")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$l])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (x.y.employee)  |PARTITIONED|
+          data-scan []<-[$$17, $$l] <- x.y.employee
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/multipart-dataverse/index/index-02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/multipart-dataverse/index/index-02.plan
index a794105..78851a9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/multipart-dataverse/index/index-02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/multipart-dataverse/index/index-02.plan
@@ -1,8 +1,16 @@
+distribute result [$$l]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(eq($$l.getField(1), "Julio"), eq($$l.getField(2), "Isa")))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$l])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (x.y.employee)  |PARTITIONED|
+          data-scan []<-[$$17, $$l] <- x.y.employee
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/btree-index-join/ASTERIXDB-2199.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/btree-index-join/ASTERIXDB-2199.plan
index 9887b10..efb7ea3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/btree-index-join/ASTERIXDB-2199.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/btree-index-join/ASTERIXDB-2199.plan
@@ -1,14 +1,28 @@
+distribute result [$$35] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"first": $$first, "second": $$second}] project: [$$35] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
     -- ASSIGN  |PARTITIONED|
+      project ([$$first, $$second]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$36, $$37)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
           -- HYBRID_HASH_JOIN [$$36][$$37]  |PARTITIONED|
+            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
             -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
-              -- DATASOURCE_SCAN (Facebook.Friendship)  |PARTITIONED|
+              data-scan []<-[$$36, $$first] <- Facebook.Friendship [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
             -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
-              -- DATASOURCE_SCAN (Facebook.Friendship)  |PARTITIONED|
+              data-scan []<-[$$37, $$second] <- Facebook.Friendship [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-basic/ngram-contains_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-basic/ngram-contains_ps.plan
index 5a051c1..06cbf5e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-basic/ngram-contains_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-basic/ngram-contains_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$17)
         -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$17(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$23
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField(0).getField(2), "Multimedia"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                        data-scan []<-[$$17, $$o] <- test.DBLP
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$23] <- [agg-range-map($$21, $$22)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$21, $$22] <- [agg-local-sampling($$17), agg-null-writer($$17)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$17])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField(0).getField(2), "Multimedia"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                  data-scan []<-[$$17, $$o] <- test.DBLP
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-basic/olist-edit-distance-check_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-basic/olist-edit-distance-check_ps.plan
index 7597fd2..4cf12e1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-basic/olist-edit-distance-check_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-basic/olist-edit-distance-check_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$20) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$20(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$28 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$20, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$25, 1, $$25, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$25)
                             -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$25] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$24)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$24] <- [array: [ "computers", "wine", "walking" ]]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$28] <- [agg-range-map($$26, $$27)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$26, $$27] <- [agg-local-sampling($$20), agg-null-writer($$20)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$20])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- REPLICATE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                                  unnest-map [$$20, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$25, 1, $$25, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$25)
                                       -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                          unnest-map [$$25] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$24)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$24] <- [array: [ "computers", "wine", "walking" ]]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-basic/olist-edit-distance_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-basic/olist-edit-distance_ps.plan
index 7597fd2..4cf12e1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-basic/olist-edit-distance_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-basic/olist-edit-distance_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$20) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$20(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$28 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$20, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$25, 1, $$25, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$25)
                             -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$25] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$24)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$24] <- [array: [ "computers", "wine", "walking" ]]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$28] <- [agg-range-map($$26, $$27)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$26, $$27] <- [agg-local-sampling($$20), agg-null-writer($$20)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$20])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- REPLICATE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                                  unnest-map [$$20, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$25, 1, $$25, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$25)
                                       -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                          unnest-map [$$25] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$24)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$24] <- [array: [ "computers", "wine", "walking" ]]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-basic/olist-fuzzyeq-edit-distance_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-basic/olist-fuzzyeq-edit-distance_ps.plan
index 6e8c23d..4451428 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-basic/olist-fuzzyeq-edit-distance_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-basic/olist-fuzzyeq-edit-distance_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$19) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$19(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$19(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$27 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$19, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$24, 1, $$24, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$24)
                             -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$24] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$23)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$23] <- [array: [ "computers", "wine", "walking" ]]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$27] <- [agg-range-map($$25, $$26)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$25, $$26] <- [agg-local-sampling($$19), agg-null-writer($$19)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$19])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- REPLICATE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                                  unnest-map [$$19, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$24, 1, $$24, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$24)
                                       -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                          unnest-map [$$24] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$23)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$23] <- [array: [ "computers", "wine", "walking" ]]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-complex/olist-edit-distance-check-let_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-complex/olist-edit-distance-check-let_ps.plan
index 5c43154..6199354 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-complex/olist-edit-distance-check-let_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-index/inverted-index-complex/olist-edit-distance-check-let_ps.plan
@@ -1,38 +1,76 @@
+distribute result [$$c] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$31) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$31(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$39 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                        unnest-map [$$31, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$36, 1, $$36, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$36)
                             -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                unnest-map [$$36] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$35)
+                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    assign [$$35] <- [array: [ "computers", "wine", "walking" ]]
                                     -- ASSIGN  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$39] <- [agg-range-map($$37, $$38)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$37, $$38] <- [agg-local-sampling($$31), agg-null-writer($$31)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$31])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- REPLICATE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (get-item(edit-distance-check($$c.getField(0).getField(4), array: [ "computers", "wine", "walking" ], 1), 0)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH (test.Customers.Customers)  |PARTITIONED|
+                                  unnest-map [$$31, $$c] <- index-search("Customers", 0, "Default", "test", "Customers", false, false, 1, $$36, 1, $$36, true, true, true)
+                                  -- BTREE_SEARCH  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      order (ASC, $$36)
                                       -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH (test.Customers.interests_index)  |PARTITIONED|
+                                          unnest-map [$$36] <- index-search("interests_index", 4, "Default", "test", "Customers", false, false, 2, 1, 21, false, 1, $$35)
+                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              assign [$$35] <- [array: [ "computers", "wine", "walking" ]]
                                               -- ASSIGN  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/05.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/05.plan
index 6af09d7..3796265 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/05.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index-join/non-enforced-composite-key-equi-join/05.plan
@@ -1,25 +1,50 @@
+distribute result [$$36] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$36] <- [{"c1": $$48, "c2": $$49}] project: [$$36] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
       -- SORT_MERGE_EXCHANGE [$$48(ASC), $$49(ASC) ]  |PARTITIONED|
+        order (ASC, $$48) (ASC, $$49) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
         -- STABLE_SORT [$$48(ASC), $$49(ASC)]  |PARTITIONED|
+          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$48, $$49]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (eq($$45, $$46)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                 -- HYBRID_HASH_JOIN [$$45][$$46]  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                   -- HASH_PARTITION_EXCHANGE [$$45]  |PARTITIONED|
+                    assign [$$45, $$48] <- [to-string($$52.getField("c_s")), $$52.getField("c_x")] project: [$$48, $$45] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ASSIGN  |PARTITIONED|
+                      assign [$$52] <- [$$t1.getField("nested")] project: [$$52] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                            data-scan []<-[$$43, $$t1] <- test.TestOpen1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                   -- HASH_PARTITION_EXCHANGE [$$46]  |PARTITIONED|
+                    assign [$$49, $$46] <- [$$53.getField("c_x"), $$53.getField("c_s")] project: [$$49, $$46] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ASSIGN  |PARTITIONED|
+                      assign [$$53] <- [$$t2.getField("nested")] project: [$$53] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t2]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen2)  |PARTITIONED|
+                            data-scan []<-[$$44, $$t2] <- test.TestOpen2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/01.plan
index 5454dab..cf5f353 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/01.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (gt($$emp.getField("nested").getField("fname"), "Roger"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$15, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/02.plan
index 5454dab..4457e66 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/02.plan
@@ -1,8 +1,16 @@
+distribute result [$$emp]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (gt($$emp.getField("nested").getField("address").getField("zip"), "97777"))
     -- STREAM_SELECT  |PARTITIONED|
+      project ([$$emp])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+          data-scan []<-[$$16, $$emp] <- test.testdst
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/03.plan
index e831481..d3ed290 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/03.plan
@@ -1,13 +1,26 @@
+distribute result [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$18] <- [{"res": $$22}] project: [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$22(ASC) ]  |PARTITIONED|
+        order (ASC, $$22) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$t.getField("nested").getField("c_i64"), 2)) project: [$$22] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$22] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                    data-scan []<-[$$20, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/04.plan
index a90a4f1..bd61c00 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/04.plan
@@ -1,14 +1,28 @@
+distribute result [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"res": $$25}] project: [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+        order (ASC, $$25) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$27.getField("c_s"), "world")) project: [$$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25] <- [$$27.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                assign [$$27] <- [$$t.getField("nested")] project: [$$27] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                      data-scan []<-[$$23, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/05.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/05.plan
index a90a4f1..60d0425 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/05.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/05.plan
@@ -1,14 +1,28 @@
+distribute result [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"res": $$25}] project: [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+        order (ASC, $$25) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$27.getField("c_i64"), 2)) project: [$$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25] <- [$$27.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                assign [$$27] <- [$$t.getField("nested")] project: [$$27] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                      data-scan []<-[$$23, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/06.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/06.plan
index a90a4f1..da8cc39 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/06.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/06.plan
@@ -1,14 +1,28 @@
+distribute result [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"res": $$25}] project: [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+        order (ASC, $$25) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$27.getField("c_i64"), 2)) project: [$$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25] <- [$$27.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                assign [$$27] <- [$$t.getField("nested")] project: [$$27] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                      data-scan []<-[$$23, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/07.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/07.plan
index a90a4f1..fb6f841 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/07.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/07.plan
@@ -1,14 +1,28 @@
+distribute result [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"res": $$25}] project: [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+        order (ASC, $$25) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$27.getField("c_i64"), 2.0)) project: [$$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25] <- [$$27.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                assign [$$27] <- [$$t.getField("nested")] project: [$$27] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                      data-scan []<-[$$23, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/08.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/08.plan
index a90a4f1..e5b2616 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/08.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/08.plan
@@ -1,14 +1,28 @@
+distribute result [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"res": $$25}] project: [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+        order (ASC, $$25) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$27.getField("c_i8"), 2)) project: [$$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25] <- [$$27.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                assign [$$27] <- [$$t.getField("nested")] project: [$$27] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                      data-scan []<-[$$23, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/09.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/09.plan
index a90a4f1..3b12403 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/09.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/09.plan
@@ -1,14 +1,28 @@
+distribute result [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"res": $$25}] project: [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+        order (ASC, $$25) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$27.getField("c_i8"), 2.5)) project: [$$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25] <- [$$27.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                assign [$$27] <- [$$t.getField("nested")] project: [$$27] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                      data-scan []<-[$$23, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/10.plan
index a90a4f1..61875a6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/10.plan
@@ -1,14 +1,28 @@
+distribute result [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$19] <- [{"res": $$25}] project: [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+        order (ASC, $$25) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (ge($$27.getField("c_d"), 3.25)) project: [$$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25] <- [$$27.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                assign [$$27] <- [$$t.getField("nested")] project: [$$27] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                      data-scan []<-[$$23, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/11.plan
index eacac4b..93f26df 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/11.plan
@@ -1,14 +1,28 @@
+distribute result [$$23] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$23] <- [{"res": $$30}] project: [$$23] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$30(ASC) ]  |PARTITIONED|
+        order (ASC, $$30) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$30(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$26, 499), lt($$26, 99999))) project: [$$30] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$30, $$26] <- [$$32.getField("c_x"), $$32.getField("c_i8")] project: [$$30, $$26] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                assign [$$32] <- [$$t.getField("nested")] project: [$$32] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                      data-scan []<-[$$28, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/12.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/12.plan
index eacac4b..942114b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/12.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/btree-index/non-enforced-composite-key/12.plan
@@ -1,14 +1,28 @@
+distribute result [$$23] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$23] <- [{"res": $$30}] project: [$$23] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$30(ASC) ]  |PARTITIONED|
+        order (ASC, $$30) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$30(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$32.getField("c_i8"), 2), lt($$32.getField("c_i64"), 3))) project: [$$30] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$30] <- [$$32.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                assign [$$32] <- [$$t.getField("nested")] project: [$$32] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ASSIGN  |PARTITIONED|
+                  project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                      data-scan []<-[$$27, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/inverted-index-basic/ngram-contains_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/inverted-index-basic/ngram-contains_ps.plan
index 5a051c1..36c0dff 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/inverted-index-basic/ngram-contains_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/inverted-index-basic/ngram-contains_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$17)
         -- STABLE_SORT [$$17(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$17(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$23
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField(0).getField("title"), "Multimedia"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                        data-scan []<-[$$17, $$o] <- test.DBLP
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$23] <- [agg-range-map($$21, $$22)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$21, $$22] <- [agg-local-sampling($$17), agg-null-writer($$17)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$17])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField(0).getField("title"), "Multimedia"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                  data-scan []<-[$$17, $$o] <- test.DBLP
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/inverted-index-join/ngram-contains_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/inverted-index-join/ngram-contains_01_ps.plan
index 523165d..e592d71 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/inverted-index-join/ngram-contains_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/inverted-index-join/ngram-contains_01_ps.plan
@@ -1,39 +1,78 @@
+distribute result [$$35] [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"title1": $$38, "title2": $$39}] project: [$$35] [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
     -- ASSIGN  |PARTITIONED|
+      project ([$$38, $$39]) [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$40) (ASC, $$41) [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
           -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+            exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
             -- RANGE_PARTITION_EXCHANGE [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$51 [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
               -- FORWARD  |PARTITIONED|
+                exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
                   -- REPLICATE  |PARTITIONED|
+                    exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (contains($$38, $$39)) [cardinality: 2.5E11, op-cost: 2.50004E11, total-cost: 2.50009E11]
                       -- STREAM_SELECT  |PARTITIONED|
+                        assign [$$39] <- [$$o2.getField(2)] project: [$$40, $$38, $$41, $$39] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ASSIGN  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                            unnest-map [$$41, $$o2] <- index-search("CSX", 0, "Default", "test", "CSX", true, true, 1, $$40, 0, false, true, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$38] <- [$$o1.getField("title")] project: [$$40, $$38]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                    data-scan []<-[$$40, $$o1] <- test.DBLP [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$51] <- [agg-range-map($$48, $$49, $$50)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$48, $$49, $$50] <- [agg-local-sampling($$40, $$41), agg-null-writer($$40), agg-null-writer($$41)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$40, $$41])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
                             -- REPLICATE  |PARTITIONED|
+                              exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (contains($$38, $$39)) [cardinality: 2.5E11, op-cost: 2.50004E11, total-cost: 2.50009E11]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$39] <- [$$o2.getField(2)] project: [$$40, $$38, $$41, $$39] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                                      unnest-map [$$41, $$o2] <- index-search("CSX", 0, "Default", "test", "CSX", true, true, 1, $$40, 0, false, true, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          assign [$$38] <- [$$o1.getField("title")] project: [$$40, $$38]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                              data-scan []<-[$$40, $$o1] <- test.DBLP [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/inverted-index-join/ngram-contains_02_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/inverted-index-join/ngram-contains_02_ps.plan
index a48bd9a..63e9cd3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/inverted-index-join/ngram-contains_02_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested-open-index/inverted-index-join/ngram-contains_02_ps.plan
@@ -1,39 +1,78 @@
+distribute result [$$35] [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"title1": $$38, "title2": $$39}] project: [$$35] [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
     -- ASSIGN  |PARTITIONED|
+      project ([$$38, $$39]) [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$40) (ASC, $$41) [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
           -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+            exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
             -- RANGE_PARTITION_EXCHANGE [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$51 [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
               -- FORWARD  |PARTITIONED|
+                exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
                   -- REPLICATE  |PARTITIONED|
+                    exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (contains($$38, $$39)) [cardinality: 2.5E11, op-cost: 2.50004E11, total-cost: 2.50009E11]
                       -- STREAM_SELECT  |PARTITIONED|
+                        assign [$$39] <- [$$o2.getField(2)] project: [$$40, $$38, $$41, $$39] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ASSIGN  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                            unnest-map [$$41, $$o2] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, true, 1, $$40, 0, false, true, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$38] <- [$$o1.getField("title")] project: [$$40, $$38]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                                    data-scan []<-[$$40, $$o1] <- test.CSX [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$51] <- [agg-range-map($$48, $$49, $$50)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$48, $$49, $$50] <- [agg-local-sampling($$40, $$41), agg-null-writer($$40), agg-null-writer($$41)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$40, $$41])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
                             -- REPLICATE  |PARTITIONED|
+                              exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (contains($$38, $$39)) [cardinality: 2.5E11, op-cost: 2.50004E11, total-cost: 2.50009E11]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$39] <- [$$o2.getField(2)] project: [$$40, $$38, $$41, $$39] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.DBLP.DBLP)  |PARTITIONED|
+                                      unnest-map [$$41, $$o2] <- index-search("DBLP", 0, "Default", "test", "DBLP", true, true, 1, $$40, 0, false, true, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          assign [$$38] <- [$$o1.getField("title")] project: [$$40, $$38]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.CSX)  |PARTITIONED|
+                                              data-scan []<-[$$40, $$o1] <- test.CSX [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested_loj2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested_loj2.plan
index f607474..cb92f5a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested_loj2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/nested_loj2.plan
@@ -1,42 +1,78 @@
+distribute result [$$70] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$70] <- [{"cust": $$c, "orders": $$68}] project: [$$70] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      project ([$$68, $$c]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- PRE_CLUSTERED_GROUP_BY[$$71]  |PARTITIONED|
-                  {
+          group by ([$$82 := $$71]) decor ([$$c]) {
+                    aggregate [$$68] <- [listify({"order": $$o, "items": $$62})]
                     -- AGGREGATE  |LOCAL|
-                      -- MICRO_PRE_CLUSTERED_GROUP_BY[$$72]  |LOCAL|
-                              {
+                      group by ([$$80 := $$72]) decor ([$$c; $$o; $$71; $$75]) {
+                                aggregate [$$62] <- [listify($$l)]
                                 -- AGGREGATE  |LOCAL|
+                                  select (not(is-missing($$79)))
                                   -- STREAM_SELECT  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             }
+                      -- MICRO_PRE_CLUSTERED_GROUP_BY[$$72]  |LOCAL|
+                        select (not(is-missing($$81)))
                         -- STREAM_SELECT  |LOCAL|
+                          nested tuple source
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
+                 } [cardinality: 0.0, op-cost: 0.0, total-cost: 1000000.0]
+          -- PRE_CLUSTERED_GROUP_BY[$$71]  |PARTITIONED|
+            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (ASC, $$71) (ASC, $$72) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STABLE_SORT [$$71(ASC), $$72(ASC)]  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  project ([$$c, $$o, $$l, $$79, $$72, $$71, $$75, $$81]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      left outer join (eq($$73, $$72)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00015E11]
                       -- HYBRID_HASH_JOIN [$$72][$$73]  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          left outer join (eq($$75, $$71)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                           -- HYBRID_HASH_JOIN [$$71][$$75]  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- HASH_PARTITION_EXCHANGE [$$71]  |PARTITIONED|
-                              -- DATASOURCE_SCAN (tpch.Customers)  |PARTITIONED|
+                              data-scan []<-[$$71, $$c] <- tpch.Customers [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$75]  |PARTITIONED|
+                              assign [$$81, $$75] <- [true, $$o.getField(1)]
                               -- ASSIGN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                  data-scan []<-[$$72, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        exchange
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                          assign [$$79] <- [true]
                           -- ASSIGN  |PARTITIONED|
+                            project ([$$73, $$l])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (tpch.LineItems)  |PARTITIONED|
+                                data-scan []<-[$$73, $$74, $$l] <- tpch.LineItems [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    empty-tuple-source
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-enforced/inverted-index-basic/ngram-contains_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-enforced/inverted-index-basic/ngram-contains_ps.plan
index 93ca5bd..f138fa5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-enforced/inverted-index-basic/ngram-contains_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-enforced/inverted-index-basic/ngram-contains_ps.plan
@@ -1,28 +1,56 @@
+distribute result [$$o]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$o])
     -- STREAM_PROJECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$15)
         -- STABLE_SORT [$$15(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$15(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$20
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (contains($$o.getField("title"), "Multimedia"))
                     -- STREAM_SELECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                        data-scan []<-[$$15, $$o] <- test.DBLP
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$20] <- [agg-range-map($$18, $$19)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$18, $$19] <- [agg-local-sampling($$15), agg-null-writer($$15)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$15])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (contains($$o.getField("title"), "Multimedia"))
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                  data-scan []<-[$$15, $$o] <- test.DBLP
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-enforced/inverted-index-join/ngram-contains_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-enforced/inverted-index-join/ngram-contains_01_ps.plan
index 523165d..e592d71 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-enforced/inverted-index-join/ngram-contains_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-enforced/inverted-index-join/ngram-contains_01_ps.plan
@@ -1,39 +1,78 @@
+distribute result [$$35] [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$35] <- [{"title1": $$38, "title2": $$39}] project: [$$35] [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
     -- ASSIGN  |PARTITIONED|
+      project ([$$38, $$39]) [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$40) (ASC, $$41) [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
           -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+            exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
             -- RANGE_PARTITION_EXCHANGE [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$51 [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
               -- FORWARD  |PARTITIONED|
+                exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
                   -- REPLICATE  |PARTITIONED|
+                    exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (contains($$38, $$39)) [cardinality: 2.5E11, op-cost: 2.50004E11, total-cost: 2.50009E11]
                       -- STREAM_SELECT  |PARTITIONED|
+                        assign [$$39] <- [$$o2.getField(2)] project: [$$40, $$38, $$41, $$39] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ASSIGN  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                            unnest-map [$$41, $$o2] <- index-search("CSX", 0, "Default", "test", "CSX", true, true, 1, $$40, 0, false, true, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$38] <- [$$o1.getField("title")] project: [$$40, $$38]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                    data-scan []<-[$$40, $$o1] <- test.DBLP [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$51] <- [agg-range-map($$48, $$49, $$50)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$48, $$49, $$50] <- [agg-local-sampling($$40, $$41), agg-null-writer($$40), agg-null-writer($$41)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$40, $$41])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
                             -- REPLICATE  |PARTITIONED|
+                              exchange [cardinality: 2.5E11, op-cost: 0.0, total-cost: 2.50009E11]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (contains($$38, $$39)) [cardinality: 2.5E11, op-cost: 2.50004E11, total-cost: 2.50009E11]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$39] <- [$$o2.getField(2)] project: [$$40, $$38, $$41, $$39] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ASSIGN  |PARTITIONED|
+                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- BTREE_SEARCH (test.CSX.CSX)  |PARTITIONED|
+                                      unnest-map [$$41, $$o2] <- index-search("CSX", 0, "Default", "test", "CSX", true, true, 1, $$40, 0, false, true, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                      -- BTREE_SEARCH  |PARTITIONED|
+                                        exchange
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          assign [$$38] <- [$$o1.getField("title")] project: [$$40, $$38]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (test.DBLP)  |PARTITIONED|
+                                              data-scan []<-[$$40, $$o1] <- test.DBLP [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-03.plan
index 3af30be..6a30aaa 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-03.plan
@@ -1,9 +1,18 @@
+distribute result [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(eq($$t.getField("c_x"), "x2"), eq($$t.getField("c_z"), "z2"))) project: [$$19] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$19] <- [$$t.getField("c_value")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ASSIGN  |PARTITIONED|
+        project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+            data-scan []<-[$$20, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-04.plan
index 3af30be..fa1c21c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-04.plan
@@ -1,9 +1,18 @@
+distribute result [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(eq($$t.getField("c_x"), "x2"), gt($$t.getField("c_y"), 1), eq($$t.getField("c_z"), "z2"))) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$21] <- [$$t.getField("c_value")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ASSIGN  |PARTITIONED|
+        project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+            data-scan []<-[$$22, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-07.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-07.plan
index 09a9501..0c0f7c2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-07.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-07.plan
@@ -1,23 +1,46 @@
+distribute result [$$32] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"c1": $$40, "c2": $$41}] project: [$$32] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
       -- SORT_MERGE_EXCHANGE [$$40(ASC), $$41(ASC) ]  |PARTITIONED|
+        order (ASC, $$40) (ASC, $$41) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
         -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$40, $$41]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
             -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                join (eq($$37, $$38)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                 -- HYBRID_HASH_JOIN [$$37][$$38]  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                   -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                    assign [$$37, $$40] <- [to-string($$t1.getField("c_s")), $$t1.getField("c_x")] project: [$$40, $$37] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$t1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                          data-scan []<-[$$35, $$t1] <- test.TestOpen1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                   -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+                    assign [$$41, $$38] <- [$$t2.getField("c_x"), $$t2.getField("c_s")] project: [$$41, $$38] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- ASSIGN  |PARTITIONED|
+                      project ([$$t2]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (test.TestOpen2)  |PARTITIONED|
+                          data-scan []<-[$$36, $$t2] <- test.TestOpen2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-07_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-07_ps.plan
index df1a86f..2c05cdd 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-07_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-equi-join-non-enforced/btree-equi-join-non-enforced-07_ps.plan
@@ -1,51 +1,102 @@
+distribute result [$$32] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$32] <- [{"c1": $$40, "c2": $$41}] project: [$$32] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$40) (ASC, $$41) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
         -- STABLE_SORT [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$40(ASC), $$41(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$47 [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$40, $$41]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        join (eq($$37, $$38)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                         -- HYBRID_HASH_JOIN [$$37][$$38]  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                           -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                            assign [$$37, $$40] <- [to-string($$t1.getField("c_s")), $$t1.getField("c_x")] project: [$$40, $$37] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$t1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                                  data-scan []<-[$$35, $$t1] <- test.TestOpen1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                           -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+                            assign [$$41, $$38] <- [$$t2.getField("c_x"), $$t2.getField("c_s")] project: [$$41, $$38] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ASSIGN  |PARTITIONED|
+                              project ([$$t2]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (test.TestOpen2)  |PARTITIONED|
+                                  data-scan []<-[$$36, $$t2] <- test.TestOpen2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$47] <- [agg-range-map($$44, $$45, $$46)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$44, $$45, $$46] <- [agg-local-sampling($$40, $$41), agg-null-writer($$40), agg-null-writer($$41)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                         -- REPLICATE  |PARTITIONED|
+                          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$40, $$41]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$37, $$38)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                 -- HYBRID_HASH_JOIN [$$37][$$38]  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                   -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                                    assign [$$37, $$40] <- [to-string($$t1.getField("c_s")), $$t1.getField("c_x")] project: [$$40, $$37] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$t1]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.TestOpen1)  |PARTITIONED|
+                                          data-scan []<-[$$35, $$t1] <- test.TestOpen1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                   -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+                                    assign [$$41, $$38] <- [$$t2.getField("c_x"), $$t2.getField("c_s")] project: [$$41, $$38] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- ASSIGN  |PARTITIONED|
+                                      project ([$$t2]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (test.TestOpen2)  |PARTITIONED|
+                                          data-scan []<-[$$36, $$t2] <- test.TestOpen2 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-04.plan
index 735ca65..ccdd351 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-04.plan
@@ -1,13 +1,26 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$t.getField("c_s"), "world")) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                    data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-04_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-04_ps.plan
index 953f6e6..acb34f5 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-04_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-04_ps.plan
@@ -1,31 +1,62 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$25 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (eq($$t.getField("c_s"), "world")) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                            data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$25] <- [agg-range-map($$23, $$24)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$23, $$24] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- REPLICATE  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (eq($$t.getField("c_s"), "world")) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                                    data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-05.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-05.plan
index 735ca65..bcbacb2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-05.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-05.plan
@@ -1,13 +1,26 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$t.getField("c_i64"), 2)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                    data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-05_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-05_ps.plan
index 953f6e6..316772e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-05_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-05_ps.plan
@@ -1,31 +1,62 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$25 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (eq($$t.getField("c_i64"), 2)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                            data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$25] <- [agg-range-map($$23, $$24)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$23, $$24] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- REPLICATE  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (eq($$t.getField("c_i64"), 2)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                                    data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-06.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-06.plan
index 735ca65..2b7051a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-06.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-06.plan
@@ -1,13 +1,26 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$t.getField("c_i64"), 2)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                    data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-06_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-06_ps.plan
index 953f6e6..605942c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-06_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-06_ps.plan
@@ -1,31 +1,62 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$25 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (gt($$t.getField("c_i64"), 2)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                            data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$25] <- [agg-range-map($$23, $$24)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$23, $$24] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- REPLICATE  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (gt($$t.getField("c_i64"), 2)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                                    data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-07.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-07.plan
index 735ca65..93dc00f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-07.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-07.plan
@@ -1,13 +1,26 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$t.getField("c_i64"), 2.0)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                    data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-07_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-07_ps.plan
index 953f6e6..9963b05 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-07_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-07_ps.plan
@@ -1,31 +1,62 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$25 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (gt($$t.getField("c_i64"), 2.0)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                            data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$25] <- [agg-range-map($$23, $$24)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$23, $$24] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- REPLICATE  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (gt($$t.getField("c_i64"), 2.0)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                                    data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-08.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-08.plan
index 735ca65..0be4920 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-08.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-08.plan
@@ -1,13 +1,26 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$t.getField("c_i8"), 2)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                    data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-08_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-08_ps.plan
index 953f6e6..e959fff 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-08_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-08_ps.plan
@@ -1,31 +1,62 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$25 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (gt($$t.getField("c_i8"), 2)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                            data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$25] <- [agg-range-map($$23, $$24)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$23, $$24] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- REPLICATE  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (gt($$t.getField("c_i8"), 2)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                                    data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-09.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-09.plan
index 735ca65..ef9acd8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-09.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-09.plan
@@ -1,13 +1,26 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$t.getField("c_i8"), 2.5)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                    data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-09_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-09_ps.plan
index 953f6e6..ff3cdeb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-09_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-09_ps.plan
@@ -1,31 +1,62 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$25 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (gt($$t.getField("c_i8"), 2.5)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                            data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$25] <- [agg-range-map($$23, $$24)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$23, $$24] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- REPLICATE  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (gt($$t.getField("c_i8"), 2.5)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                                    data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-10.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-10.plan
index 735ca65..afbbead 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-10.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-10.plan
@@ -1,13 +1,26 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (ge($$t.getField("c_d"), 3.25)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                    data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-105.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-105.plan
index 8c3f7ca..e75a4c1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-105.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-105.plan
@@ -1,13 +1,26 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$20] <- [{"res": $$25}] project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+        order (ASC, $$25) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$t.getField("c_i8"), 2), lt($$t.getField("c_i64"), 3))) project: [$$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$25] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                    data-scan []<-[$$22, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-105_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-105_ps.plan
index 54d9469..b3a817f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-105_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-105_ps.plan
@@ -1,31 +1,62 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$20] <- [{"res": $$25}] project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$25) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$25(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$29 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (and(gt($$t.getField("c_i8"), 2), lt($$t.getField("c_i64"), 3))) project: [$$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$25] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                            data-scan []<-[$$22, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$29] <- [agg-range-map($$27, $$28)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$27, $$28] <- [agg-local-sampling($$25), agg-null-writer($$25)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- REPLICATE  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (and(gt($$t.getField("c_i8"), 2), lt($$t.getField("c_i64"), 3))) project: [$$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$25] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                                    data-scan []<-[$$22, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-10_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-10_ps.plan
index 953f6e6..785fb38 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-10_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-10_ps.plan
@@ -1,31 +1,62 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"res": $$21}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$21) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$21(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$25 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (ge($$t.getField("c_d"), 3.25)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                            data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$25] <- [agg-range-map($$23, $$24)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$23, $$24] <- [agg-local-sampling($$21), agg-null-writer($$21)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- REPLICATE  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (ge($$t.getField("c_d"), 3.25)) project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$21] <- [$$t.getField("c_x")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                                    data-scan []<-[$$19, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-11.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-11.plan
index efb563b..bfed8ff 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-11.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-11.plan
@@ -1,13 +1,26 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$20] <- [{"res": $$24}] project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+        order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$22, 499), lt($$22, 99999))) project: [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$24, $$22] <- [$$t.getField("c_x"), $$t.getField("c_i8")] project: [$$24, $$22] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                    data-scan []<-[$$23, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        empty-tuple-source
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-11_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-11_ps.plan
index 4df11b8..2c42d3d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-11_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/open-index-non-enforced/btree-index-non-enforced/btree-index-non-enforced-11_ps.plan
@@ -1,31 +1,62 @@
+distribute result [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$20] <- [{"res": $$24}] project: [$$20] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$24(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$28 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (and(gt($$22, 499), lt($$22, 99999))) project: [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$24, $$22] <- [$$t.getField("c_x"), $$t.getField("c_i8")] project: [$$24, $$22] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                            data-scan []<-[$$23, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$28] <- [agg-range-map($$26, $$27)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$26, $$27] <- [agg-local-sampling($$24), agg-null-writer($$24)]
                     -- AGGREGATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- REPLICATE  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            select (and(gt($$22, 499), lt($$22, 99999))) project: [$$24] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- STREAM_SELECT  |PARTITIONED|
+                              assign [$$24, $$22] <- [$$t.getField("c_x"), $$t.getField("c_i8")] project: [$$24, $$22] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$t]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+                                    data-scan []<-[$$23, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive-open_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive-open_01.plan
index 623713a..cbe65b6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive-open_01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive-open_01.plan
@@ -1,25 +1,24 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$21] <- [{"o_orderkey": $$24, "o_custkey": $$23}] project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+        order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$o.getField(3), 150000.0), eq($$23, 40))) project: [$$24, $$23] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$23] <- [$$o.getField(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                  data-scan []<-[$$24, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive-open_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive-open_01_ps.plan
index bab6397..1b22e9d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive-open_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive-open_01_ps.plan
@@ -1,43 +1,60 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$21] <- [{"o_orderkey": $$24, "o_custkey": $$23}] project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$24(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$30 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (and(gt($$o.getField(3), 150000.0), eq($$23, 40))) project: [$$24, $$23] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$23] <- [$$o.getField(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                          data-scan []<-[$$24, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$30] <- [agg-range-map($$28, $$29)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$28, $$29] <- [agg-local-sampling($$24), agg-null-writer($$24)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$24])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- REPLICATE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (and(gt($$o.getField(3), 150000.0), eq($$23, 40))) project: [$$24, $$23] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$23] <- [$$o.getField(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                    data-scan []<-[$$24, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive-open_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive-open_02.plan
index 1ea9571..e5157b6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive-open_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive-open_02.plan
@@ -1,25 +1,24 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$22] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$22] <- [{"o_orderkey": $$26, "o_custkey": $$24, "o_totalprice": $$25}] project: [$$22] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$26(ASC) ]  |PARTITIONED|
+        order (ASC, $$26) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$25, 150000.0), eq($$24, 40))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$24, $$25] <- [$$o.getField(1), $$o.getField(3)] project: [$$26, $$24, $$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                  data-scan []<-[$$26, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive-open_02_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive-open_02_ps.plan
index d6fbaae..698d673 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive-open_02_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive-open_02_ps.plan
@@ -1,43 +1,60 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$22] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$22] <- [{"o_orderkey": $$26, "o_custkey": $$24, "o_totalprice": $$25}] project: [$$22] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$26) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$26(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$31 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (and(gt($$25, 150000.0), eq($$24, 40))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$24, $$25] <- [$$o.getField(1), $$o.getField(3)] project: [$$26, $$24, $$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                          data-scan []<-[$$26, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$31] <- [agg-range-map($$29, $$30)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$29, $$30] <- [agg-local-sampling($$26), agg-null-writer($$26)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$26])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- REPLICATE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (and(gt($$25, 150000.0), eq($$24, 40))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$24, $$25] <- [$$o.getField(1), $$o.getField(3)] project: [$$26, $$24, $$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                    data-scan []<-[$$26, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive_01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive_01.plan
index 623713a..cbe65b6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive_01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive_01.plan
@@ -1,25 +1,24 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$21] <- [{"o_orderkey": $$24, "o_custkey": $$23}] project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+        order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$o.getField(3), 150000.0), eq($$23, 40))) project: [$$24, $$23] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$23] <- [$$o.getField(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                  data-scan []<-[$$24, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive_01_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive_01_ps.plan
index bab6397..1b22e9d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive_01_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive_01_ps.plan
@@ -1,43 +1,60 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$21] <- [{"o_orderkey": $$24, "o_custkey": $$23}] project: [$$21] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$24) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$24(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$30 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (and(gt($$o.getField(3), 150000.0), eq($$23, 40))) project: [$$24, $$23] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$23] <- [$$o.getField(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                          data-scan []<-[$$24, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$30] <- [agg-range-map($$28, $$29)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$28, $$29] <- [agg-local-sampling($$24), agg-null-writer($$24)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$24])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- REPLICATE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (and(gt($$o.getField(3), 150000.0), eq($$23, 40))) project: [$$24, $$23] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$23] <- [$$o.getField(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                    data-scan []<-[$$24, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive_02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive_02.plan
index 1ea9571..e5157b6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive_02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive_02.plan
@@ -1,25 +1,24 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$22] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$22] <- [{"o_orderkey": $$26, "o_custkey": $$24, "o_totalprice": $$25}] project: [$$22] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$26(ASC) ]  |PARTITIONED|
+        order (ASC, $$26) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$25, 150000.0), eq($$24, 40))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$24, $$25] <- [$$o.getField(1), $$o.getField(3)] project: [$$26, $$24, $$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                  data-scan []<-[$$26, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive_02_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive_02_ps.plan
index d6fbaae..698d673 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive_02_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/orders-index-search-conjunctive_02_ps.plan
@@ -1,43 +1,60 @@
--- SINK  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- BULKLOAD  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- STABLE_SORT [$$2(ASC)]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$2]  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- DATASOURCE_SCAN (loadable_dv.loadable_ds)  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+distribute result [$$22] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$22] <- [{"o_orderkey": $$26, "o_custkey": $$24, "o_totalprice": $$25}] project: [$$22] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$26) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- RANGE_PARTITION_EXCHANGE [$$26(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$31 [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (and(gt($$25, 150000.0), eq($$24, 40))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$24, $$25] <- [$$o.getField(1), $$o.getField(3)] project: [$$26, $$24, $$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                          data-scan []<-[$$26, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$31] <- [agg-range-map($$29, $$30)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$29, $$30] <- [agg-local-sampling($$26), agg-null-writer($$26)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$26])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- REPLICATE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (and(gt($$25, 150000.0), eq($$24, 40))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$24, $$25] <- [$$o.getField(1), $$o.getField(3)] project: [$$26, $$24, $$25] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                    data-scan []<-[$$26, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/q08_group_by.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/q08_group_by.plan
index 9f0d653..898dc72 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/q08_group_by.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/q08_group_by.plan
@@ -1,70 +1,140 @@
+distribute result [$$203] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$203] <- [{"o_orderdate": $$228, "l_discount": $$231, "l_extendedprice": $$232, "l_suppkey": $$233, "s_nationkey": $$242}] project: [$$203] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
     -- ASSIGN  |PARTITIONED|
+      project ([$$228, $$231, $$232, $$233, $$242]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$212, $$230)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
           -- HYBRID_HASH_JOIN [$$230][$$212]  |PARTITIONED|
+            exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$228, $$231, $$232, $$233, $$242, $$230]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$216, $$211)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                   -- HYBRID_HASH_JOIN [$$216][$$211]  |PARTITIONED|
+                    exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$228, $$231, $$232, $$233, $$242, $$230, $$216]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          join (eq($$218, $$210)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                           -- HYBRID_HASH_JOIN [$$218][$$210]  |PARTITIONED|
+                            exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$228, $$231, $$232, $$233, $$242, $$230, $$218]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  join (eq($$209, $$221)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                                   -- HYBRID_HASH_JOIN [$$221][$$209]  |PARTITIONED|
+                                    exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$228, $$231, $$232, $$233, $$242, $$230, $$221]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          join (eq($$206, $$208)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00015E11]
                                           -- HYBRID_HASH_JOIN [$$206][$$208]  |PARTITIONED|
+                                            exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$231, $$232, $$233, $$242, $$230, $$206]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  join (eq($$205, $$233)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                   -- HYBRID_HASH_JOIN [$$205][$$233]  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                     -- HASH_PARTITION_EXCHANGE [$$205]  |PARTITIONED|
+                                                      assign [$$242] <- [$$s.getField(3)] project: [$$242, $$205] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (q08_group_by.Supplier)  |PARTITIONED|
+                                                          data-scan []<-[$$205, $$s] <- q08_group_by.Supplier [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                     -- HASH_PARTITION_EXCHANGE [$$233]  |PARTITIONED|
+                                                      assign [$$233, $$232, $$231, $$230] <- [$$l.getField(2), $$l.getField(5), $$l.getField(6), $$l.getField(1)] project: [$$231, $$232, $$233, $$230, $$206] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$206, $$l]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (q08_group_by.LineItem)  |PARTITIONED|
+                                                            data-scan []<-[$$206, $$207, $$l] <- q08_group_by.LineItem [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              select (and(ge($$228, "1995-01-01"), le($$228, "1996-12-31"))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- STREAM_SELECT  |PARTITIONED|
+                                                assign [$$228, $$221] <- [$$o.getField(4), $$o.getField(1)] project: [$$208, $$228, $$221] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- ASSIGN  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (q08_group_by.Orders)  |PARTITIONED|
+                                                    data-scan []<-[$$208, $$o] <- q08_group_by.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                      assign [$$218] <- [$$c.getField(3)] project: [$$218, $$209] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (q08_group_by.Customer)  |PARTITIONED|
+                                          data-scan []<-[$$209, $$c] <- q08_group_by.Customer [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                              assign [$$216] <- [$$n1.getField(2)] project: [$$216, $$210] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ASSIGN  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (q08_group_by.Nation)  |PARTITIONED|
+                                  data-scan []<-[$$210, $$n1] <- q08_group_by.Nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                      select (eq($$r1.getField(1), "AMERICA")) project: [$$211] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- STREAM_SELECT  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (q08_group_by.Region)  |PARTITIONED|
+                          data-scan []<-[$$211, $$r1] <- q08_group_by.Region [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
             -- BROADCAST_EXCHANGE  |PARTITIONED|
+              select (eq($$p.getField(4), "ECONOMY ANODIZED STEEL")) project: [$$212] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_SELECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (q08_group_by.Part)  |PARTITIONED|
+                  data-scan []<-[$$212, $$p] <- q08_group_by.Part [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/q09_group_by.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/q09_group_by.plan
index 0e70665..9ff9fad 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/q09_group_by.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/q09_group_by.plan
@@ -1,49 +1,98 @@
+distribute result [$$145] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$145] <- [{"l_extendedprice": $$166, "l_discount": $$167, "l_quantity": $$168, "l_orderkey": $$152, "n_name": $$165, "ps_supplycost": $$177}] project: [$$145] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
     -- ASSIGN  |PARTITIONED|
+      project ([$$166, $$167, $$168, $$152, $$177, $$165]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$151, $$157)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
           -- HYBRID_HASH_JOIN [$$157][$$151]  |PARTITIONED|
+            exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.0002E11]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$166, $$167, $$168, $$152, $$177, $$157]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.0002E11]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.0002E11]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$150, $$154)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.0002E11]
                   -- HYBRID_HASH_JOIN [$$154][$$150]  |PARTITIONED|
+                    exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$166, $$167, $$168, $$152, $$177, $$154]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          join (eq($$147, $$169)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 1.1E7]
                           -- HYBRID_HASH_JOIN [$$169][$$147]  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 7000000.0]
                             -- HASH_PARTITION_EXCHANGE [$$169]  |PARTITIONED|
+                              project ([$$166, $$167, $$168, $$152, $$177, $$154, $$169]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 7000000.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  join (and(eq($$148, $$169), eq($$149, $$154))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 6000000.0]
                                   -- HYBRID_HASH_JOIN [$$148, $$149][$$169, $$154]  |PARTITIONED|
+                                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                     -- HASH_PARTITION_EXCHANGE [$$148, $$149]  |PARTITIONED|
+                                      assign [$$177] <- [$$ps.getField(3)] project: [$$177, $$148, $$149] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (q09_group_by.Partsupp)  |PARTITIONED|
+                                          data-scan []<-[$$148, $$149, $$ps] <- q09_group_by.Partsupp [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                     -- HASH_PARTITION_EXCHANGE [$$169, $$154]  |PARTITIONED|
+                                      assign [$$169, $$168, $$167, $$166, $$154] <- [$$l.getField(1), $$l.getField(4), $$l.getField(6), $$l.getField(5), $$l.getField(2)] project: [$$166, $$167, $$168, $$152, $$154, $$169] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- ASSIGN  |PARTITIONED|
+                                        project ([$$152, $$l]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (q09_group_by.LineItem)  |PARTITIONED|
+                                            data-scan []<-[$$152, $$153, $$l] <- q09_group_by.LineItem [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                             -- HASH_PARTITION_EXCHANGE [$$147]  |PARTITIONED|
+                              select (contains($$p.getField(1), "green")) project: [$$147] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- DATASOURCE_SCAN (q09_group_by.Part)  |PARTITIONED|
+                                  data-scan []<-[$$147, $$p] <- q09_group_by.Part [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                      assign [$$157] <- [$$s.getField(3)] project: [$$157, $$150] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- DATASOURCE_SCAN (q09_group_by.Supplier)  |PARTITIONED|
+                          data-scan []<-[$$150, $$s] <- q09_group_by.Supplier [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
             -- BROADCAST_EXCHANGE  |PARTITIONED|
+              assign [$$165] <- [$$n.getField(1)] project: [$$165, $$151] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (q09_group_by.Nation)  |PARTITIONED|
+                  data-scan []<-[$$151, $$n] <- q09_group_by.Nation [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query-ASTERIXDB-2700.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query-ASTERIXDB-2700.plan
index 1f5b867..06b300c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query-ASTERIXDB-2700.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query-ASTERIXDB-2700.plan
@@ -1,25 +1,50 @@
+distribute result [$$46] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$46] <- [{"uname": $$55, "message": $$msg.getField("message")}] project: [$$46] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$msg.getField("author_id"), $$48)) project: [$$55, $$msg] [cardinality: 5.0E11, op-cost: 5.00004E11, total-cost: 5.00009E11]
       -- STREAM_SELECT  |PARTITIONED|
+        project ([$$55, $$48, $$msg]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (bigfun.GleambookMessagesComposite.GleambookMessagesComposite)  |PARTITIONED|
+            unnest-map [$$49, $$50, $$msg] <- index-search("GleambookMessagesComposite", 0, "Default", "bigfun", "GleambookMessagesComposite", true, false, 2, $$58, $$59, 2, $$58, $$59, true, true, true) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$58) (ASC, $$59)
                 -- STABLE_SORT [$$58(ASC), $$59(ASC)]  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    project ([$$55, $$48, $$58, $$59])
                     -- STREAM_PROJECT  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- BTREE_SEARCH (bigfun.GleambookMessagesComposite.authorIdIx)  |PARTITIONED|
+                        unnest-map [$$57, $$58, $$59] <- index-search("authorIdIx", 0, "Default", "bigfun", "GleambookMessagesComposite", true, true, 1, $$48, 1, $$48, true, true, true)
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange
                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                            assign [] <- []
                             -- ASSIGN  |PARTITIONED|
+                              exchange
                               -- SORT_MERGE_EXCHANGE [$$48(ASC) ]  |PARTITIONED|
+                                order (ASC, $$48)
                                 -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    select (ge($$u.getField("user_since"), "2008-07-22T00:00:00")) project: [$$55, $$48] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      assign [$$55] <- [$$u.getField("name")]
                                       -- ASSIGN  |PARTITIONED|
+                                        project ([$$48, $$u])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (bigfun.GleambookUsersComposite)  |PARTITIONED|
+                                            data-scan []<-[$$47, $$48, $$u] <- bigfun.GleambookUsersComposite [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query-ASTERIXDB-3334.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query-ASTERIXDB-3334.plan
index 54dec5e..82fedb1 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query-ASTERIXDB-3334.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query-ASTERIXDB-3334.plan
@@ -1,56 +1,100 @@
+distribute result [$$800] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$800] <- [{"Employee Name": $$Employee Name, "avg:Employee Salary:ok": $$812}] project: [$$800] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- SORT_GROUP_BY[$$1120]  |PARTITIONED|
-                {
+        group by ([$$Employee Name := $$1120]) decor ([]) {
+                  aggregate [$$812] <- [agg-global-sql-avg($$1119)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               } [cardinality: 0.0, op-cost: 0.0, total-cost: 6000000.0]
+        -- SORT_GROUP_BY[$$1120]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
           -- HASH_PARTITION_EXCHANGE [$$1120]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$1121]  |PARTITIONED|
-                    {
+            group by ([$$1120 := $$1121]) decor ([]) {
+                      aggregate [$$1119] <- [agg-local-sql-avg($$1126)]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   } [cardinality: 0.0, op-cost: 0.0, total-cost: 6000000.0]
+            -- SORT_GROUP_BY[$$1121]  |PARTITIONED|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$1126, $$1121]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 6000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (and(eq($$1121, $$Employee Name), eq($$1122, $$Call Center Region))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 6000000.0]
                     -- HYBRID_HASH_JOIN [$$1121, $$1122][$$Employee Name, $$Call Center Region]  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                       -- HASH_PARTITION_EXCHANGE [$$1122, $$1121]  |PARTITIONED|
+                        select (and(not(is-null(int64-default-null($#6.getField("Item Count")))), not(is-null(string-default-null($#6.getField("Ship Priority")))), not(is-null(string-default-null($#6.getField("Order Priority")))), not(is-null(string-default-null($#6.getField("Order Status")))), not(is-null(double-default-null($#6.getField("Order Quantity")))), not(is-null(double-default-null($#6.getField("Sales Total")))), not(is-null(double-default-null($#6.getField("Discount")))), not(is-null(double-default-null($#6.getField("Tax Rate")))), not(is-null(string-default-null($#6.getField("Ship Mode")))), not(is-null(double-default-null($#6.getField("Fill Time")))), not(is-null(double-default-null($#6.getField("Gross Profit")))), not(is-null(double-default-null($#6.getField("Price")))), not(is-null(double-default-null($#6.getField("Ship Handle Cost")))), not(is-null($$1121)), not(is-null(string-default-null($#6.getField("Employee Dept")))), not(is-null(string-default-null($#6.getField("Manager Name")))), not(is-null(double-default-null($#6.getField("Employee Yrs Exp")))), not(is-null($$1126)), not(is-null(string-default-null($#6.getField("Customer Name")))), not(is-null(string-default-null($#6.getField("Customer State")))), not(is-null($$1122)), not(is-null(double-default-null($#6.getField("Customer Balance")))), not(is-null(string-default-null($#6.getField("Customer Segment")))), not(is-null(string-default-null($#6.getField("Prod Type1")))), not(is-null(string-default-null($#6.getField("Prod Type2")))), not(is-null(string-default-null($#6.getField("Prod Type3")))), not(is-null(string-default-null($#6.getField("Prod Type4")))), not(is-null(string-default-null($#6.getField("Product Name")))), not(is-null(string-default-null($#6.getField("Product Container")))), not(is-null(string-default-null($#6.getField("Ship Promo")))), not(is-null(string-default-null($#6.getField("Supplier Name")))), not(is-null(double-default-null($#6.getField("Supplier Balance")))), not(is-null(string-default-null($#6.getField("Supplier Region")))), not(is-null(string-default-null($#6.getField("Supplier State")))), not(is-null(string-default-null($#6.getField("Order ID")))), not(is-null(int64-default-null($#6.getField("Order Year")))), not(is-null(int64-default-null($#6.getField("Order Month")))), not(is-null(int64-default-null($#6.getField("Order Day")))), not(is-null(datetime-default-null($#6.getField("Order Date")))), not(is-null(string-default-null($#6.getField("Order Quarter")))), not(is-null(double-default-null($#6.getField("Product Base Margin")))), not(is-null(string-default-null($#6.getField("Product ID")))), not(is-null(double-default-null($#6.getField("Receive Time")))), not(is-null(datetime-default-null($#6.getField("Received Date")))), not(is-null(datetime-default-null($#6.getField("Ship Date")))), not(is-null(double-default-null($#6.getField("Ship Charge")))), not(is-null(double-default-null($#6.getField("Total Cycle Time")))), not(is-null(string-default-null($#6.getField("Product In Stock")))), not(is-null(int64-default-null($#6.getField("PID")))), not(is-null(string-default-null($#6.getField("Market Segment")))))) project: [$$1126, $$1121, $$1122] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- STREAM_SELECT  |PARTITIONED|
+                          assign [$$1126, $$1122, $$1121] <- [double-default-null($#6.getField("Employee Salary")), string-default-null($#6.getField("Call Center Region")), string-default-null($#6.getField("Employee Name"))] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ASSIGN  |PARTITIONED|
+                            assign [$#6] <- [$#6] project: [$#6] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                             -- ASSIGN  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- REPLICATE  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$#6]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                        data-scan []<-[$$806, $#6] <- test.collection0 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        select (and(ge($$811, 102499.99999999898), le($$810, 110000.0000000011))) project: [$$Employee Name, $$Call Center Region] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- STREAM_SELECT  |PARTITIONED|
+                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- SORT_GROUP_BY[$$1117, $$1118]  |PARTITIONED|
-                                    {
+                            group by ([$$Call Center Region := $$1117; $$Employee Name := $$1118]) decor ([]) {
+                                      aggregate [$$810, $$811] <- [agg-global-sql-avg($$1115), agg-global-sql-avg($$1116)]
                                       -- AGGREGATE  |LOCAL|
+                                        nested tuple source
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   } [cardinality: 0.0, op-cost: 0.0, total-cost: 1000000.0]
+                            -- SORT_GROUP_BY[$$1117, $$1118]  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                               -- HASH_PARTITION_EXCHANGE [$$1117, $$1118]  |PARTITIONED|
-                                -- SORT_GROUP_BY[$$1125, $$1124]  |PARTITIONED|
-                                        {
+                                group by ([$$1117 := $$1125; $$1118 := $$1124]) decor ([]) {
+                                          aggregate [$$1115, $$1116] <- [agg-local-sql-avg($$1123), agg-local-sql-avg($$1123)]
                                           -- AGGREGATE  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
+                                       } [cardinality: 0.0, op-cost: 0.0, total-cost: 1000000.0]
+                                -- SORT_GROUP_BY[$$1125, $$1124]  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    select (and(not(is-null(int64-default-null($#6.getField("Item Count")))), not(is-null(string-default-null($#6.getField("Ship Priority")))), not(is-null(string-default-null($#6.getField("Order Priority")))), not(is-null(string-default-null($#6.getField("Order Status")))), not(is-null(double-default-null($#6.getField("Order Quantity")))), not(is-null(double-default-null($#6.getField("Sales Total")))), not(is-null(double-default-null($#6.getField("Discount")))), not(is-null(double-default-null($#6.getField("Tax Rate")))), not(is-null(string-default-null($#6.getField("Ship Mode")))), not(is-null(double-default-null($#6.getField("Fill Time")))), not(is-null(double-default-null($#6.getField("Gross Profit")))), not(is-null(double-default-null($#6.getField("Price")))), not(is-null(double-default-null($#6.getField("Ship Handle Cost")))), not(is-null($$1124)), not(is-null(string-default-null($#6.getField("Employee Dept")))), not(is-null(string-default-null($#6.getField("Manager Name")))), not(is-null(double-default-null($#6.getField("Employee Yrs Exp")))), not(is-null($$1123)), not(is-null(string-default-null($#6.getField("Customer Name")))), not(is-null(string-default-null($#6.getField("Customer State")))), not(is-null($$1125)), not(is-null(double-default-null($#6.getField("Customer Balance")))), not(is-null(string-default-null($#6.getField("Customer Segment")))), not(is-null(string-default-null($#6.getField("Prod Type1")))), not(is-null(string-default-null($#6.getField("Prod Type2")))), not(is-null(string-default-null($#6.getField("Prod Type3")))), not(is-null(string-default-null($#6.getField("Prod Type4")))), not(is-null(string-default-null($#6.getField("Product Name")))), not(is-null(string-default-null($#6.getField("Product Container")))), not(is-null(string-default-null($#6.getField("Ship Promo")))), not(is-null(string-default-null($#6.getField("Supplier Name")))), not(is-null(double-default-null($#6.getField("Supplier Balance")))), not(is-null(string-default-null($#6.getField("Supplier Region")))), not(is-null(string-default-null($#6.getField("Supplier State")))), not(is-null(string-default-null($#6.getField("Order ID")))), not(is-null(int64-default-null($#6.getField("Order Year")))), not(is-null(int64-default-null($#6.getField("Order Month")))), not(is-null(int64-default-null($#6.getField("Order Day")))), not(is-null(datetime-default-null($#6.getField("Order Date")))), not(is-null(string-default-null($#6.getField("Order Quarter")))), not(is-null(double-default-null($#6.getField("Product Base Margin")))), not(is-null(string-default-null($#6.getField("Product ID")))), not(is-null(double-default-null($#6.getField("Receive Time")))), not(is-null(datetime-default-null($#6.getField("Received Date")))), not(is-null(datetime-default-null($#6.getField("Ship Date")))), not(is-null(double-default-null($#6.getField("Ship Charge")))), not(is-null(double-default-null($#6.getField("Total Cycle Time")))), not(is-null(string-default-null($#6.getField("Product In Stock")))), not(is-null(int64-default-null($#6.getField("PID")))), not(is-null(string-default-null($#6.getField("Market Segment")))))) project: [$$1123, $$1125, $$1124]
                                     -- STREAM_SELECT  |PARTITIONED|
+                                      assign [$$1125, $$1124, $$1123] <- [string-default-null($#6.getField("Call Center Region")), string-default-null($#6.getField("Employee Name")), double-default-null($#6.getField("Employee Salary"))] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- ASSIGN  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- REPLICATE  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$#6]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                  data-scan []<-[$$806, $#6] <- test.collection0 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query_issue3316.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query_issue3316.plan
index 3d62392..6b739e2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query_issue3316.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query_issue3316.plan
@@ -1,900 +1,1755 @@
+distribute result [$$192]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    distinct ([$$192])
     -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$192)
         -- STABLE_SORT [$$192(ASC)]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$192]  |PARTITIONED|
+            assign [$$192] <- [object-concat-strict(to-object-var-str($$116), {"sub_query1": $$156, "sub_query2": $$191})] project: [$$192]
             -- ASSIGN  |PARTITIONED|
+              project ([$$191, $$116, $$156])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- PRE_CLUSTERED_GROUP_BY[$$227]  |PARTITIONED|
-                          {
+                  group by ([$$318 := $$227]) decor ([$$116; $$156]) {
+                            aggregate [$$191] <- [listify($$190)]
                             -- AGGREGATE  |LOCAL|
+                              select (not(is-missing($$317)))
                               -- STREAM_SELECT  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                          }
+                         }
+                  -- PRE_CLUSTERED_GROUP_BY[$$227]  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$116, $$156, $$190, $$317, $$227])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          left outer join (eq($$227, $$388))
                           -- HYBRID_HASH_JOIN [$$227][$$388]  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$193]  |PARTITIONED|
-                                      {
+                              group by ([$$227 := $$193]) decor ([$$116]) {
+                                        aggregate [$$156] <- [listify($$155)]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$226)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- PRE_CLUSTERED_GROUP_BY[$$193]  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  order (ASC, $$193)
                                   -- STABLE_SORT [$$193(ASC)]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$116, $$155, $$226, $$193])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          left outer join (eq($$193, $$240))
                                           -- HYBRID_HASH_JOIN [$$193][$$240]  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$193]  |PARTITIONED|
+                                              assign [$$116] <- [{"x_id": $$T0.getField("x_id")}] project: [$$116, $$193]
                                               -- ASSIGN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                  data-scan []<-[$$193, $$T0] <- test.collection0
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- HASH_PARTITION_EXCHANGE [$$240]  |PARTITIONED|
+                                              assign [$$226, $$155] <- [true, {"u": $$213}] project: [$$155, $$226, $$240]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$240, $$213])
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    join (eq($$199, $$126))
                                                     -- HYBRID_HASH_JOIN [$$126][$$199]  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        select ($$151) project: [$$240, $$213, $$126]
                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                          project ([$$151, $$240, $$213, $$126])
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- PRE_CLUSTERED_GROUP_BY[$$225, $$194]  |PARTITIONED|
-                                                                      {
+                                                              group by ([$$240 := $$225; $$241 := $$194]) decor ([$$213; $$126]) {
+                                                                        aggregate [$$151] <- [non-empty-stream()]
                                                                         -- AGGREGATE  |LOCAL|
+                                                                          select (not(is-missing($$239)))
                                                                           -- STREAM_SELECT  |LOCAL|
+                                                                            nested tuple source
                                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                      }
+                                                                     }
+                                                              -- PRE_CLUSTERED_GROUP_BY[$$225, $$194]  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  order (ASC, $$225) (ASC, $$194)
                                                                   -- STABLE_SORT [$$225(ASC), $$194(ASC)]  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      project ([$$213, $$126, $$239, $$225, $$194])
                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          left outer join (and(eq($$225, $$254), eq($$194, $$255)))
                                                                           -- HYBRID_HASH_JOIN [$$225, $$194][$$254, $$255]  |PARTITIONED|
+                                                                            exchange
                                                                             -- HASH_PARTITION_EXCHANGE [$$225, $$194]  |PARTITIONED|
+                                                                              project ([$$213, $$126, $$225, $$194])
                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  join (eq($$207, $$223)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                                                   -- HYBRID_HASH_JOIN [$$223][$$207]  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      assign [$$225, $$223] <- [$$409, $$417] project: [$$225, $$223]
                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                          replicate
                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                              assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                  replicate
                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                      assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                          -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                          data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                              empty-tuple-source
                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- HASH_PARTITION_EXCHANGE [$$207]  |PARTITIONED|
+                                                                                      select (eq($$H.getField("to_u"), "aaaaa")) project: [$$213, $$126, $$194, $$207] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                                        assign [$$213, $$126, $$207] <- [$$H.getField("u"), $$H.getField("a"), $$H.getField("y_id")]
                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                          assign [$$194, $$H] <- [$$411, $$413] project: [$$194, $$H]
                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              replicate
                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                  -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                  data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                      empty-tuple-source
                                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              assign [$$239] <- [true]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                select (eq($$233, $#7)) project: [$$254, $$255]
                                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                                  unnest $#7 <- scan-collection($$148) project: [$$254, $$255, $$233, $#7]
                                                                                   -- UNNEST  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$238, $$235]  |PARTITIONED|
-                                                                                              {
+                                                                                      group by ([$$254 := $$238; $$255 := $$235]) decor ([$$233]) {
+                                                                                                aggregate [$$148] <- [listify($$203)]
                                                                                                 -- AGGREGATE  |LOCAL|
+                                                                                                  aggregate [$$203] <- [agg-sql-max($$145)]
                                                                                                   -- AGGREGATE  |LOCAL|
+                                                                                                    select (not(is-missing($$253)))
                                                                                                     -- STREAM_SELECT  |LOCAL|
+                                                                                                      nested tuple source
                                                                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                              }
+                                                                                             }
+                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$238, $$235]  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                          order (ASC, $$238) (ASC, $$235)
                                                                                           -- STABLE_SORT [$$238(ASC), $$235(ASC)]  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              project ([$$233, $$145, $$253, $$238, $$235])
                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                  left outer join (and(eq($$238, $$252), eq($$235, $$249)))
                                                                                                   -- HYBRID_HASH_JOIN [$$238, $$235][$$252, $$249]  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                      assign [$$233, $$238, $$235] <- [$$422, $$425, $$426] project: [$$233, $$238, $$235]
                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                          replicate
                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- HASH_PARTITION_EXCHANGE [$$425, $$426]  |PARTITIONED|
+                                                                                                              project ([$$422, $$425, $$426])
                                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                exchange
                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                  join (eq($$427, $$428)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                                                                                   -- HYBRID_HASH_JOIN [$$428][$$427]  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                      assign [$$425, $$428] <- [$$409, $$417] project: [$$425, $$428]
                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                        exchange
                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                          replicate
                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                              assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                exchange
                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                  replicate
                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                    exchange
                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                      assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                        exchange
                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                          -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                          data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                            exchange
                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                              empty-tuple-source
                                                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$427]  |PARTITIONED|
+                                                                                                                      select (eq($$430.getField("to_u"), "aaaaa")) project: [$$422, $$426, $$427] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                        exchange
                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                          replicate
                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                              assign [$$427, $$422] <- [$$430.getField("y_id"), $$430.getField("b")]
                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                assign [$$426, $$430] <- [$$411, $$413] project: [$$426, $$430]
                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                  exchange
                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                    replicate
                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                      exchange
                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                        -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                        data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                          exchange
                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                            empty-tuple-source
                                                                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- HASH_PARTITION_EXCHANGE [$$252, $$249]  |PARTITIONED|
+                                                                                                      assign [$$253] <- [true]
                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                        project ([$$145, $$252, $$249])
                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                          exchange
                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                            join (eq($$198, $$135))
                                                                                                             -- HYBRID_HASH_JOIN [$$135][$$198]  |PARTITIONED|
+                                                                                                              exchange
                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                project ([$$145, $$252, $$249, $$135])
                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                  exchange
                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                    join (eq($$210, $$243)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00015E11]
                                                                                                                     -- HYBRID_HASH_JOIN [$$243][$$210]  |PARTITIONED|
+                                                                                                                      exchange
                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                        assign [$$252, $$249, $$243] <- [$$435, $$436, $$445] project: [$$252, $$249, $$243]
                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                          exchange
                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                            replicate
                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                              exchange
                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                project ([$$435, $$436, $$445])
                                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                  exchange
                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                    join (eq($$448, $$445)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                                                                                                     -- HYBRID_HASH_JOIN [$$445][$$448]  |PARTITIONED|
+                                                                                                                                      exchange
                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                        assign [$$435, $$445] <- [$$409, $$417] project: [$$435, $$445]
                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                          exchange
                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                            replicate
                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                              exchange
                                                                                                                                               -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                  exchange
                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                    replicate
                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                      exchange
                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                        assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                          exchange
                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                            -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                            data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                              exchange
                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                empty-tuple-source
                                                                                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                      exchange
                                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$448]  |PARTITIONED|
+                                                                                                                                        select (eq($$450.getField("to_u"), "aaaaa")) project: [$$436, $$448] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                          exchange
                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                            replicate
                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                              exchange
                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                assign [$$448] <- [$$450.getField("y_id")]
                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                  assign [$$436, $$450] <- [$$411, $$413] project: [$$436, $$450]
                                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                                    exchange
                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                      replicate
                                                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                                                        exchange
                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                          -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                          data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                            exchange
                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                              empty-tuple-source
                                                                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                      exchange
                                                                                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                                        select (eq($$L.getField("to_u"), "aaaaa")) project: [$$145, $$135, $$210] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                          assign [$$135, $$210, $$145] <- [$$L.getField("a"), $$L.getField("y_id"), $$L.getField("b")]
                                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                                            assign [$$L] <- [$$441] project: [$$L]
                                                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                                                              exchange
                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                replicate
                                                                                                                                 -- REPLICATE  |PARTITIONED|
+                                                                                                                                  exchange
                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                    assign [$$447, $$441] <- [$$411, $$413] project: [$$441]
                                                                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                                                                      exchange
                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                        replicate
                                                                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                                                                          exchange
                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                            -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                            data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                              exchange
                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                empty-tuple-source
                                                                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                              exchange
                                                                                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                                unnest $$198 <- scan-collection(array: [ 66, 67, 26, 12, 13 ])
                                                                                                                 -- UNNEST  |UNPARTITIONED|
+                                                                                                                  empty-tuple-source
                                                                                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                      exchange
                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        unnest $$199 <- scan-collection(array: [ 66, 67, 26, 12, 13 ])
                                                         -- UNNEST  |UNPARTITIONED|
+                                                          empty-tuple-source
                                                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$388]  |PARTITIONED|
+                              assign [$$317, $$190] <- [true, {"u": $$219}] project: [$$190, $$317, $$388]
                               -- ASSIGN  |PARTITIONED|
+                                project ([$$388, $$219])
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (eq($$202, $$162))
                                     -- HYBRID_HASH_JOIN [$$162][$$202]  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        project ([$$388, $$219, $$162])
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            join (eq($$201, $$165))
                                             -- HYBRID_HASH_JOIN [$$165][$$201]  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                select ($$186) project: [$$388, $$219, $$162, $$165]
                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                  project ([$$186, $$388, $$162, $$165, $$219])
                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- PRE_CLUSTERED_GROUP_BY[$$256, $$196]  |PARTITIONED|
-                                                              {
+                                                      group by ([$$388 := $$256; $$389 := $$196]) decor ([$$162; $$165; $$219]) {
+                                                                aggregate [$$186] <- [non-empty-stream()]
                                                                 -- AGGREGATE  |LOCAL|
+                                                                  select (not(is-missing($$387)))
                                                                   -- STREAM_SELECT  |LOCAL|
+                                                                    nested tuple source
                                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                              }
+                                                             }
+                                                      -- PRE_CLUSTERED_GROUP_BY[$$256, $$196]  |PARTITIONED|
+                                                        exchange
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          order (ASC, $$256) (ASC, $$196)
                                                           -- STABLE_SORT [$$256(ASC), $$196(ASC)]  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              project ([$$219, $$162, $$165, $$387, $$256, $$196])
                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  left outer join (and(eq($$256, $$459), eq($$196, $$460)))
                                                                   -- HYBRID_HASH_JOIN [$$256, $$196][$$459, $$460]  |PARTITIONED|
+                                                                    exchange
                                                                     -- HASH_PARTITION_EXCHANGE [$$256, $$196]  |PARTITIONED|
+                                                                      project ([$$219, $$162, $$165, $$256, $$196])
                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          join (eq($$214, $$260))
                                                                           -- HYBRID_HASH_JOIN [$$260][$$214]  |PARTITIONED|
+                                                                            exchange
                                                                             -- HASH_PARTITION_EXCHANGE [$$260]  |PARTITIONED|
-                                                                              -- PRE_CLUSTERED_GROUP_BY[$$257]  |PARTITIONED|
-                                                                                      {
+                                                                              group by ([$$256 := $$257]) decor ([$$260]) {
+                                                                                        aggregate [] <- []
                                                                                         -- AGGREGATE  |LOCAL|
+                                                                                          select (not(is-missing($$262)))
                                                                                           -- STREAM_SELECT  |LOCAL|
+                                                                                            nested tuple source
                                                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                      }
+                                                                                     }
+                                                                              -- PRE_CLUSTERED_GROUP_BY[$$257]  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  order (ASC, $$257)
                                                                                   -- STABLE_SORT [$$257(ASC)]  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      project ([$$260, $$262, $$257])
                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                          left outer join (eq($$257, $$261))
                                                                                           -- HYBRID_HASH_JOIN [$$257][$$261]  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              assign [$$260, $$257] <- [$$391, $$399] project: [$$260, $$257]
                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                  replicate
                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- HASH_PARTITION_EXCHANGE [$$399]  |PARTITIONED|
+                                                                                                      replicate
                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                          assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                              -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                              data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                exchange
                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                  empty-tuple-source
                                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- HASH_PARTITION_EXCHANGE [$$261]  |PARTITIONED|
+                                                                                              assign [$$262] <- [true]
                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                project ([$$261])
                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    join (eq($$265, $$266))
                                                                                                     -- HYBRID_HASH_JOIN [$$266][$$265]  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                        select ($$267) project: [$$261, $$266]
                                                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                                                          project ([$$267, $$261, $$266])
                                                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                              -- PRE_CLUSTERED_GROUP_BY[$$268, $$270]  |PARTITIONED|
-                                                                                                                      {
+                                                                                                              group by ([$$261 := $$268; $$269 := $$270]) decor ([$$266]) {
+                                                                                                                        aggregate [$$267] <- [non-empty-stream()]
                                                                                                                         -- AGGREGATE  |LOCAL|
+                                                                                                                          select (not(is-missing($$280)))
                                                                                                                           -- STREAM_SELECT  |LOCAL|
+                                                                                                                            nested tuple source
                                                                                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                      }
+                                                                                                                     }
+                                                                                                              -- PRE_CLUSTERED_GROUP_BY[$$268, $$270]  |PARTITIONED|
+                                                                                                                exchange
                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                  order (ASC, $$268) (ASC, $$270)
                                                                                                                   -- STABLE_SORT [$$268(ASC), $$270(ASC)]  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                      project ([$$266, $$280, $$268, $$270])
                                                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                        exchange
                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                          left outer join (and(eq($$268, $$278), eq($$270, $$279)))
                                                                                                                           -- HYBRID_HASH_JOIN [$$268, $$270][$$278, $$279]  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                              assign [$$266, $$268, $$270] <- [$$407, $$409, $$411] project: [$$266, $$268, $$270]
                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                exchange
                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                  replicate
                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                    exchange
                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$409, $$411]  |PARTITIONED|
+                                                                                                                                      project ([$$407, $$409, $$411])
                                                                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                        exchange
                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                          join (eq($$418, $$417)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                                                                                                           -- HYBRID_HASH_JOIN [$$417][$$418]  |PARTITIONED|
+                                                                                                                                            exchange
                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                              replicate
                                                                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                                                                exchange
                                                                                                                                                 -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                  assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                                    exchange
                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                      replicate
                                                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                                                        exchange
                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                          assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                                                                            exchange
                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                              -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                              data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                exchange
                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                  empty-tuple-source
                                                                                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                            exchange
                                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$418]  |PARTITIONED|
+                                                                                                                                              select (eq($$413.getField("to_u"), "aaaaa")) project: [$$407, $$411, $$418] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                                                               -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                assign [$$418, $$407] <- [$$413.getField("y_id"), $$413.getField("a")]
                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                  exchange
                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                    replicate
                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                      exchange
                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                        -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                        data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                          exchange
                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                            empty-tuple-source
                                                                                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                              assign [$$280] <- [true]
                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                select (eq($$281, $$282)) project: [$$278, $$279]
                                                                                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                  unnest $$282 <- scan-collection($$283) project: [$$278, $$279, $$281, $$282]
                                                                                                                                   -- UNNEST  |PARTITIONED|
+                                                                                                                                    exchange
                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$284, $$285]  |PARTITIONED|
-                                                                                                                                              {
+                                                                                                                                      group by ([$$278 := $$284; $$279 := $$285]) decor ([$$281]) {
+                                                                                                                                                aggregate [$$283] <- [listify($$315)]
                                                                                                                                                 -- AGGREGATE  |LOCAL|
+                                                                                                                                                  aggregate [$$315] <- [agg-sql-max($$297)]
                                                                                                                                                   -- AGGREGATE  |LOCAL|
+                                                                                                                                                    select (not(is-missing($$296)))
                                                                                                                                                     -- STREAM_SELECT  |LOCAL|
+                                                                                                                                                      nested tuple source
                                                                                                                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                                              }
+                                                                                                                                             }
+                                                                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$284, $$285]  |PARTITIONED|
+                                                                                                                                        exchange
                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                          order (ASC, $$284) (ASC, $$285)
                                                                                                                                           -- STABLE_SORT [$$284(ASC), $$285(ASC)]  |PARTITIONED|
+                                                                                                                                            exchange
                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                              project ([$$281, $$297, $$296, $$284, $$285])
                                                                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                exchange
                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                  left outer join (and(eq($$284, $$294), eq($$285, $$295)))
                                                                                                                                                   -- HYBRID_HASH_JOIN [$$284, $$285][$$294, $$295]  |PARTITIONED|
+                                                                                                                                                    exchange
                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                      assign [$$281, $$284, $$285] <- [$$422, $$425, $$426] project: [$$281, $$284, $$285]
                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                        exchange
                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                          replicate
                                                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                                                            exchange
                                                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$425, $$426]  |PARTITIONED|
+                                                                                                                                                              project ([$$422, $$425, $$426])
                                                                                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                exchange
                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                  join (eq($$427, $$428)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                                                                                                                                   -- HYBRID_HASH_JOIN [$$428][$$427]  |PARTITIONED|
+                                                                                                                                                                    exchange
                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                      assign [$$425, $$428] <- [$$409, $$417] project: [$$425, $$428]
                                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                        exchange
                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                          replicate
                                                                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                            exchange
                                                                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                                              assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                exchange
                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                  replicate
                                                                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                    exchange
                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                      assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                        exchange
                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                          -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                                                          data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                            exchange
                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                              empty-tuple-source
                                                                                                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                    exchange
                                                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$427]  |PARTITIONED|
+                                                                                                                                                                      select (eq($$430.getField("to_u"), "aaaaa")) project: [$$422, $$426, $$427] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                        exchange
                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                          replicate
                                                                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                            exchange
                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                              assign [$$427, $$422] <- [$$430.getField("y_id"), $$430.getField("b")]
                                                                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                assign [$$426, $$430] <- [$$411, $$413] project: [$$426, $$430]
                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                  exchange
                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                    replicate
                                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                      exchange
                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                        -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                        data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                          exchange
                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                            empty-tuple-source
                                                                                                                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                    exchange
                                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$294, $$295]  |PARTITIONED|
+                                                                                                                                                      assign [$$296] <- [true]
                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                        project ([$$297, $$294, $$295])
                                                                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                          exchange
                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                            join (eq($$301, $$302))
                                                                                                                                                             -- HYBRID_HASH_JOIN [$$302][$$301]  |PARTITIONED|
+                                                                                                                                                              exchange
                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                project ([$$297, $$294, $$295, $$302])
                                                                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                  exchange
                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                    join (eq($$303, $$304)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00015E11]
                                                                                                                                                                     -- HYBRID_HASH_JOIN [$$304][$$303]  |PARTITIONED|
+                                                                                                                                                                      exchange
                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                        assign [$$294, $$295, $$304] <- [$$435, $$436, $$445] project: [$$294, $$295, $$304]
                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                          exchange
                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                            replicate
                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                              exchange
                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                project ([$$435, $$436, $$445])
                                                                                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                  exchange
                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                    join (eq($$448, $$445)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                                                                                                                                                     -- HYBRID_HASH_JOIN [$$445][$$448]  |PARTITIONED|
+                                                                                                                                                                                      exchange
                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                        assign [$$435, $$445] <- [$$409, $$417] project: [$$435, $$445]
                                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                          exchange
                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                            replicate
                                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                              exchange
                                                                                                                                                                                               -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                                                                assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                  exchange
                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                    replicate
                                                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                      exchange
                                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                        assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                          exchange
                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                            -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                                                                            data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                              exchange
                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                empty-tuple-source
                                                                                                                                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                      exchange
                                                                                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$448]  |PARTITIONED|
+                                                                                                                                                                                        select (eq($$450.getField("to_u"), "aaaaa")) project: [$$436, $$448] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                                                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                          exchange
                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                            replicate
                                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                              exchange
                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                assign [$$448] <- [$$450.getField("y_id")]
                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                  assign [$$436, $$450] <- [$$411, $$413] project: [$$436, $$450]
                                                                                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                    exchange
                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                      replicate
                                                                                                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                        exchange
                                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                          -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                                          data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                            exchange
                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                              empty-tuple-source
                                                                                                                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                      exchange
                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                        assign [$$297, $$302, $$303] <- [$$438, $$443, $$444] project: [$$297, $$302, $$303]
                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                          exchange
                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                            replicate
                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                              exchange
                                                                                                                                                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                select (eq($$441.getField("to_u"), "aaaaa")) project: [$$438, $$443, $$444] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                                                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                  assign [$$444, $$443, $$438] <- [$$441.getField("y_id"), $$441.getField("a"), $$441.getField("b")]
                                                                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                    exchange
                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                      replicate
                                                                                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                        exchange
                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                          assign [$$447, $$441] <- [$$411, $$413] project: [$$441]
                                                                                                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                            exchange
                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                              replicate
                                                                                                                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                exchange
                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                  -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                                  data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                    exchange
                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                      empty-tuple-source
                                                                                                                                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                              exchange
                                                                                                                                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                unnest $$301 <- scan-collection(array: [ 66, 67, 26, 12, 13 ])
                                                                                                                                                                 -- UNNEST  |UNPARTITIONED|
+                                                                                                                                                                  empty-tuple-source
                                                                                                                                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                                                                      exchange
                                                                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                        unnest $$265 <- scan-collection(array: [ 66, 67, 26, 12, 13 ])
                                                                                                         -- UNNEST  |UNPARTITIONED|
+                                                                                                          empty-tuple-source
                                                                                                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                                            exchange
                                                                             -- HASH_PARTITION_EXCHANGE [$$214]  |PARTITIONED|
+                                                                              assign [$$219, $$165, $$162, $$214] <- [$$H.getField("u"), $$H.getField("posi"), $$H.getField("a"), $$H.getField("y_id")] project: [$$219, $$162, $$165, $$196, $$214]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                assign [$$196, $$H] <- [$$411, $$413] project: [$$196, $$H]
                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                  exchange
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    replicate
                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                        -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                        data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            empty-tuple-source
                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      assign [$$387] <- [true]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        select (eq($$324, $#11)) project: [$$459, $$460]
                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                          unnest $#11 <- scan-collection($$183) project: [$$459, $$460, $$324, $#11]
                                                                           -- UNNEST  |PARTITIONED|
+                                                                            exchange
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                              -- PRE_CLUSTERED_GROUP_BY[$$327, $$326]  |PARTITIONED|
-                                                                                      {
+                                                                              group by ([$$459 := $$327; $$460 := $$326]) decor ([$$324]) {
+                                                                                        aggregate [$$183] <- [listify($$204)]
                                                                                         -- AGGREGATE  |LOCAL|
+                                                                                          aggregate [$$204] <- [agg-sql-max($$180)]
                                                                                           -- AGGREGATE  |LOCAL|
+                                                                                            select (not(is-missing($$458)))
                                                                                             -- STREAM_SELECT  |LOCAL|
+                                                                                              nested tuple source
                                                                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                      }
+                                                                                     }
+                                                                              -- PRE_CLUSTERED_GROUP_BY[$$327, $$326]  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  order (ASC, $$327) (ASC, $$326)
                                                                                   -- STABLE_SORT [$$327(ASC), $$326(ASC)]  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      project ([$$324, $$180, $$458, $$327, $$326])
                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                        exchange
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                          left outer join (and(eq($$327, $$398), eq($$326, $$397)))
                                                                                           -- HYBRID_HASH_JOIN [$$327, $$326][$$398, $$397]  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- HASH_PARTITION_EXCHANGE [$$327, $$326]  |PARTITIONED|
+                                                                                              project ([$$324, $$327, $$326])
                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                  join (eq($$319, $$320))
                                                                                                   -- HYBRID_HASH_JOIN [$$320][$$319]  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- HASH_PARTITION_EXCHANGE [$$320]  |PARTITIONED|
-                                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$328]  |PARTITIONED|
-                                                                                                              {
+                                                                                                      group by ([$$327 := $$328]) decor ([$$320]) {
+                                                                                                                aggregate [] <- []
                                                                                                                 -- AGGREGATE  |LOCAL|
+                                                                                                                  select (not(is-missing($$332)))
                                                                                                                   -- STREAM_SELECT  |LOCAL|
+                                                                                                                    nested tuple source
                                                                                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                              }
+                                                                                                             }
+                                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$328]  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                          order (ASC, $$328)
                                                                                                           -- STABLE_SORT [$$328(ASC)]  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                              project ([$$320, $$332, $$328])
                                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                exchange
                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                  left outer join (eq($$328, $$331))
                                                                                                                   -- HYBRID_HASH_JOIN [$$328][$$331]  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                      assign [$$320, $$328] <- [$$391, $$399] project: [$$320, $$328]
                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                        exchange
                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                          replicate
                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$399]  |PARTITIONED|
+                                                                                                                              replicate
                                                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                                                exchange
                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                  assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                    exchange
                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                      -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                      data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                        exchange
                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                          empty-tuple-source
                                                                                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$331]  |PARTITIONED|
+                                                                                                                      assign [$$332] <- [true]
                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                        project ([$$331])
                                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                          exchange
                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                            join (eq($$335, $$336))
                                                                                                                             -- HYBRID_HASH_JOIN [$$336][$$335]  |PARTITIONED|
+                                                                                                                              exchange
                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                select ($$337) project: [$$331, $$336]
                                                                                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                  project ([$$337, $$331, $$336])
                                                                                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                    exchange
                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$338, $$340]  |PARTITIONED|
-                                                                                                                                              {
+                                                                                                                                      group by ([$$331 := $$338; $$339 := $$340]) decor ([$$336]) {
+                                                                                                                                                aggregate [$$337] <- [non-empty-stream()]
                                                                                                                                                 -- AGGREGATE  |LOCAL|
+                                                                                                                                                  select (not(is-missing($$350)))
                                                                                                                                                   -- STREAM_SELECT  |LOCAL|
+                                                                                                                                                    nested tuple source
                                                                                                                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                                              }
+                                                                                                                                             }
+                                                                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$338, $$340]  |PARTITIONED|
+                                                                                                                                        exchange
                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                          order (ASC, $$338) (ASC, $$340)
                                                                                                                                           -- STABLE_SORT [$$338(ASC), $$340(ASC)]  |PARTITIONED|
+                                                                                                                                            exchange
                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                              project ([$$336, $$350, $$338, $$340])
                                                                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                exchange
                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                  left outer join (and(eq($$338, $$348), eq($$340, $$349)))
                                                                                                                                                   -- HYBRID_HASH_JOIN [$$338, $$340][$$348, $$349]  |PARTITIONED|
+                                                                                                                                                    exchange
                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                      assign [$$336, $$338, $$340] <- [$$407, $$409, $$411] project: [$$336, $$338, $$340]
                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                        exchange
                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                          replicate
                                                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                                                            exchange
                                                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$409, $$411]  |PARTITIONED|
+                                                                                                                                                              project ([$$407, $$409, $$411])
                                                                                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                exchange
                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                  join (eq($$418, $$417)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                                                                                                                                   -- HYBRID_HASH_JOIN [$$417][$$418]  |PARTITIONED|
+                                                                                                                                                                    exchange
                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                      replicate
                                                                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                        exchange
                                                                                                                                                                         -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                                          assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                            exchange
                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                              replicate
                                                                                                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                exchange
                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                  assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                    exchange
                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                      -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                                                      data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                        exchange
                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                          empty-tuple-source
                                                                                                                                                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                    exchange
                                                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$418]  |PARTITIONED|
+                                                                                                                                                                      select (eq($$413.getField("to_u"), "aaaaa")) project: [$$407, $$411, $$418] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                        assign [$$418, $$407] <- [$$413.getField("y_id"), $$413.getField("a")]
                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                          exchange
                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                            replicate
                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                              exchange
                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                  exchange
                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                    empty-tuple-source
                                                                                                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                    exchange
                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                      assign [$$350] <- [true]
                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                        select (eq($$351, $$352)) project: [$$348, $$349]
                                                                                                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                          unnest $$352 <- scan-collection($$353) project: [$$348, $$349, $$351, $$352]
                                                                                                                                                           -- UNNEST  |PARTITIONED|
+                                                                                                                                                            exchange
                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                              -- PRE_CLUSTERED_GROUP_BY[$$354, $$355]  |PARTITIONED|
-                                                                                                                                                                      {
+                                                                                                                                                              group by ([$$348 := $$354; $$349 := $$355]) decor ([$$351]) {
+                                                                                                                                                                        aggregate [$$353] <- [listify($$385)]
                                                                                                                                                                         -- AGGREGATE  |LOCAL|
+                                                                                                                                                                          aggregate [$$385] <- [agg-sql-max($$367)]
                                                                                                                                                                           -- AGGREGATE  |LOCAL|
+                                                                                                                                                                            select (not(is-missing($$366)))
                                                                                                                                                                             -- STREAM_SELECT  |LOCAL|
+                                                                                                                                                                              nested tuple source
                                                                                                                                                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                                                                      }
+                                                                                                                                                                     }
+                                                                                                                                                              -- PRE_CLUSTERED_GROUP_BY[$$354, $$355]  |PARTITIONED|
+                                                                                                                                                                exchange
                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                  order (ASC, $$354) (ASC, $$355)
                                                                                                                                                                   -- STABLE_SORT [$$354(ASC), $$355(ASC)]  |PARTITIONED|
+                                                                                                                                                                    exchange
                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                      project ([$$351, $$367, $$366, $$354, $$355])
                                                                                                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                        exchange
                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                          left outer join (and(eq($$354, $$364), eq($$355, $$365)))
                                                                                                                                                                           -- HYBRID_HASH_JOIN [$$354, $$355][$$364, $$365]  |PARTITIONED|
+                                                                                                                                                                            exchange
                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                              assign [$$351, $$354, $$355] <- [$$422, $$425, $$426] project: [$$351, $$354, $$355]
                                                                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                exchange
                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                  replicate
                                                                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                    exchange
                                                                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$425, $$426]  |PARTITIONED|
+                                                                                                                                                                                      project ([$$422, $$425, $$426])
                                                                                                                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                        exchange
                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                          join (eq($$427, $$428)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                                                                                                                                                           -- HYBRID_HASH_JOIN [$$428][$$427]  |PARTITIONED|
+                                                                                                                                                                                            exchange
                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                              assign [$$425, $$428] <- [$$409, $$417] project: [$$425, $$428]
                                                                                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                exchange
                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                  replicate
                                                                                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                    exchange
                                                                                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                                                                      assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                        exchange
                                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                          replicate
                                                                                                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                            exchange
                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                              assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                  -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                                                                                  data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                    exchange
                                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                      empty-tuple-source
                                                                                                                                                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                            exchange
                                                                                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$427]  |PARTITIONED|
+                                                                                                                                                                                              select (eq($$430.getField("to_u"), "aaaaa")) project: [$$422, $$426, $$427] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                                                                                                               -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                                exchange
                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                  replicate
                                                                                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                    exchange
                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                      assign [$$427, $$422] <- [$$430.getField("y_id"), $$430.getField("b")]
                                                                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                        assign [$$426, $$430] <- [$$411, $$413] project: [$$426, $$430]
                                                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                          exchange
                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                            replicate
                                                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                              exchange
                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                                                data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                    empty-tuple-source
                                                                                                                                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                            exchange
                                                                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$364, $$365]  |PARTITIONED|
+                                                                                                                                                                              assign [$$366] <- [true]
                                                                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                project ([$$367, $$364, $$365])
                                                                                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                  exchange
                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                    join (eq($$371, $$372))
                                                                                                                                                                                     -- HYBRID_HASH_JOIN [$$372][$$371]  |PARTITIONED|
+                                                                                                                                                                                      exchange
                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                        project ([$$367, $$364, $$365, $$372])
                                                                                                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                          exchange
                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                            join (eq($$373, $$374)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00015E11]
                                                                                                                                                                                             -- HYBRID_HASH_JOIN [$$374][$$373]  |PARTITIONED|
+                                                                                                                                                                                              exchange
                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                assign [$$364, $$365, $$374] <- [$$435, $$436, $$445] project: [$$364, $$365, $$374]
                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                  exchange
                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                    replicate
                                                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                      exchange
                                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                        project ([$$435, $$436, $$445])
                                                                                                                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                                          exchange
                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                            join (eq($$448, $$445)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                                                                                                                                                                             -- HYBRID_HASH_JOIN [$$445][$$448]  |PARTITIONED|
+                                                                                                                                                                                                              exchange
                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                assign [$$435, $$445] <- [$$409, $$417] project: [$$435, $$445]
                                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                    replicate
                                                                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                      exchange
                                                                                                                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                                                                                        assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                          exchange
                                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                            replicate
                                                                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                              exchange
                                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                                    -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                                                                                                    data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                                                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                                      exchange
                                                                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                        empty-tuple-source
                                                                                                                                                                                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                                              exchange
                                                                                                                                                                                                               -- HASH_PARTITION_EXCHANGE [$$448]  |PARTITIONED|
+                                                                                                                                                                                                                select (eq($$450.getField("to_u"), "aaaaa")) project: [$$436, $$448] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                                                                                                                                 -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                    replicate
                                                                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                      exchange
                                                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                        assign [$$448] <- [$$450.getField("y_id")]
                                                                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                          assign [$$436, $$450] <- [$$411, $$413] project: [$$436, $$450]
                                                                                                                                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                            exchange
                                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                              replicate
                                                                                                                                                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                                  -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                                                                  data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                                                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                                    exchange
                                                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                      empty-tuple-source
                                                                                                                                                                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                              exchange
                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                assign [$$367, $$372, $$373] <- [$$438, $$443, $$444] project: [$$367, $$372, $$373]
                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                  exchange
                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                    replicate
                                                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                      exchange
                                                                                                                                                                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                        select (eq($$441.getField("to_u"), "aaaaa")) project: [$$438, $$443, $$444] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                                                                                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                                          assign [$$444, $$443, $$438] <- [$$441.getField("y_id"), $$441.getField("a"), $$441.getField("b")]
                                                                                                                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                            exchange
                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                              replicate
                                                                                                                                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                  assign [$$447, $$441] <- [$$411, $$413] project: [$$441]
                                                                                                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                    exchange
                                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                      replicate
                                                                                                                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                        exchange
                                                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                          -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                                                          data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                            exchange
                                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                              empty-tuple-source
                                                                                                                                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                      exchange
                                                                                                                                                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                        unnest $$371 <- scan-collection(array: [ 66, 67, 26, 12, 13 ])
                                                                                                                                                                                         -- UNNEST  |UNPARTITIONED|
+                                                                                                                                                                                          empty-tuple-source
                                                                                                                                                                                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                                                                                              exchange
                                                                                                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                                                unnest $$335 <- scan-collection(array: [ 66, 67, 26, 12, 13 ])
                                                                                                                                 -- UNNEST  |UNPARTITIONED|
+                                                                                                                                  empty-tuple-source
                                                                                                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                                                                    exchange
                                                                                                     -- HASH_PARTITION_EXCHANGE [$$319]  |PARTITIONED|
+                                                                                                      assign [$$326, $$321, $$319, $$324] <- [$$426, $$430, $$427, $$422] project: [$$324, $$326, $$319]
                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                          replicate
                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                              assign [$$427, $$422] <- [$$430.getField("y_id"), $$430.getField("b")]
                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                assign [$$426, $$430] <- [$$411, $$413] project: [$$426, $$430]
                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                  exchange
                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                    replicate
                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                      exchange
                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                        -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                        data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                          exchange
                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                            empty-tuple-source
                                                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- HASH_PARTITION_EXCHANGE [$$398, $$397]  |PARTITIONED|
+                                                                                              assign [$$458] <- [true]
                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                project ([$$180, $$398, $$397])
                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    join (eq($$200, $$172))
                                                                                                     -- HYBRID_HASH_JOIN [$$172][$$200]  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                        project ([$$180, $$398, $$397, $$172])
                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                          exchange
                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                            join (eq($$216, $$391))
                                                                                                             -- HYBRID_HASH_JOIN [$$391][$$216]  |PARTITIONED|
+                                                                                                              exchange
                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                project ([$$398, $$397, $$391])
                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                  exchange
                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                    join (eq($$390, $$391))
                                                                                                                     -- HYBRID_HASH_JOIN [$$391][$$390]  |PARTITIONED|
+                                                                                                                      exchange
                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$391]  |PARTITIONED|
-                                                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$399]  |PARTITIONED|
-                                                                                                                                {
+                                                                                                                        group by ([$$398 := $$399]) decor ([$$391]) {
+                                                                                                                                  aggregate [] <- []
                                                                                                                                   -- AGGREGATE  |LOCAL|
+                                                                                                                                    select (not(is-missing($$403)))
                                                                                                                                     -- STREAM_SELECT  |LOCAL|
+                                                                                                                                      nested tuple source
                                                                                                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                                }
+                                                                                                                               }
+                                                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$399]  |PARTITIONED|
+                                                                                                                          exchange
                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                            order (ASC, $$399)
                                                                                                                             -- STABLE_SORT [$$399(ASC)]  |PARTITIONED|
+                                                                                                                              exchange
                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                project ([$$391, $$403, $$399])
                                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                  exchange
                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                    left outer join (eq($$399, $$402))
                                                                                                                                     -- HYBRID_HASH_JOIN [$$399][$$402]  |PARTITIONED|
+                                                                                                                                      exchange
                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                        replicate
                                                                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                                                                          exchange
                                                                                                                                           -- HASH_PARTITION_EXCHANGE [$$399]  |PARTITIONED|
+                                                                                                                                            replicate
                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                              exchange
                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                  exchange
                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                    -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                    data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                      exchange
                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                        empty-tuple-source
                                                                                                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                      exchange
                                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$402]  |PARTITIONED|
+                                                                                                                                        assign [$$403] <- [true]
                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                          project ([$$402])
                                                                                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                            exchange
                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                              join (eq($$406, $$407))
                                                                                                                                               -- HYBRID_HASH_JOIN [$$407][$$406]  |PARTITIONED|
+                                                                                                                                                exchange
                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                  select ($$408) project: [$$402, $$407]
                                                                                                                                                   -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                    project ([$$408, $$402, $$407])
                                                                                                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                      exchange
                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$409, $$411]  |PARTITIONED|
-                                                                                                                                                                {
+                                                                                                                                                        group by ([$$402 := $$409; $$410 := $$411]) decor ([$$407]) {
+                                                                                                                                                                  aggregate [$$408] <- [non-empty-stream()]
                                                                                                                                                                   -- AGGREGATE  |LOCAL|
+                                                                                                                                                                    select (not(is-missing($$421)))
                                                                                                                                                                     -- STREAM_SELECT  |LOCAL|
+                                                                                                                                                                      nested tuple source
                                                                                                                                                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                                                                }
+                                                                                                                                                               }
+                                                                                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$409, $$411]  |PARTITIONED|
+                                                                                                                                                          exchange
                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                            order (ASC, $$409) (ASC, $$411)
                                                                                                                                                             -- STABLE_SORT [$$409(ASC), $$411(ASC)]  |PARTITIONED|
+                                                                                                                                                              exchange
                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                project ([$$407, $$421, $$409, $$411])
                                                                                                                                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                  exchange
                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                    left outer join (and(eq($$409, $$419), eq($$411, $$420)))
                                                                                                                                                                     -- HYBRID_HASH_JOIN [$$409, $$411][$$419, $$420]  |PARTITIONED|
+                                                                                                                                                                      exchange
                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                        replicate
                                                                                                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                          exchange
                                                                                                                                                                           -- HASH_PARTITION_EXCHANGE [$$409, $$411]  |PARTITIONED|
+                                                                                                                                                                            project ([$$407, $$409, $$411])
                                                                                                                                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                              exchange
                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                join (eq($$418, $$417)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                                                                                                                                                 -- HYBRID_HASH_JOIN [$$417][$$418]  |PARTITIONED|
+                                                                                                                                                                                  exchange
                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                    replicate
                                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                      exchange
                                                                                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                                                        assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                          exchange
                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                            replicate
                                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                              exchange
                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                  exchange
                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                    -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                                                                    data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                      exchange
                                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                        empty-tuple-source
                                                                                                                                                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                  exchange
                                                                                                                                                                                   -- HASH_PARTITION_EXCHANGE [$$418]  |PARTITIONED|
+                                                                                                                                                                                    select (eq($$413.getField("to_u"), "aaaaa")) project: [$$407, $$411, $$418] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                                                                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                      assign [$$418, $$407] <- [$$413.getField("y_id"), $$413.getField("a")]
                                                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                        exchange
                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                          replicate
                                                                                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                            exchange
                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                              -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                              data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                exchange
                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                  empty-tuple-source
                                                                                                                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                      exchange
                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                        assign [$$421] <- [true]
                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                          select (eq($$422, $$423)) project: [$$419, $$420]
                                                                                                                                                                           -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                            unnest $$423 <- scan-collection($$424) project: [$$419, $$420, $$422, $$423]
                                                                                                                                                                             -- UNNEST  |PARTITIONED|
+                                                                                                                                                                              exchange
                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                -- PRE_CLUSTERED_GROUP_BY[$$425, $$426]  |PARTITIONED|
-                                                                                                                                                                                        {
+                                                                                                                                                                                group by ([$$419 := $$425; $$420 := $$426]) decor ([$$422]) {
+                                                                                                                                                                                          aggregate [$$424] <- [listify($$456)]
                                                                                                                                                                                           -- AGGREGATE  |LOCAL|
+                                                                                                                                                                                            aggregate [$$456] <- [agg-sql-max($$438)]
                                                                                                                                                                                             -- AGGREGATE  |LOCAL|
+                                                                                                                                                                                              select (not(is-missing($$437)))
                                                                                                                                                                                               -- STREAM_SELECT  |LOCAL|
+                                                                                                                                                                                                nested tuple source
                                                                                                                                                                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                                                                                                        }
+                                                                                                                                                                                       }
+                                                                                                                                                                                -- PRE_CLUSTERED_GROUP_BY[$$425, $$426]  |PARTITIONED|
+                                                                                                                                                                                  exchange
                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                    order (ASC, $$425) (ASC, $$426)
                                                                                                                                                                                     -- STABLE_SORT [$$425(ASC), $$426(ASC)]  |PARTITIONED|
+                                                                                                                                                                                      exchange
                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                        project ([$$422, $$438, $$437, $$425, $$426])
                                                                                                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                          exchange
                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                            left outer join (and(eq($$425, $$435), eq($$426, $$436)))
                                                                                                                                                                                             -- HYBRID_HASH_JOIN [$$425, $$426][$$435, $$436]  |PARTITIONED|
+                                                                                                                                                                                              exchange
                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                replicate
                                                                                                                                                                                                 -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                  exchange
                                                                                                                                                                                                   -- HASH_PARTITION_EXCHANGE [$$425, $$426]  |PARTITIONED|
+                                                                                                                                                                                                    project ([$$422, $$425, $$426])
                                                                                                                                                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                                      exchange
                                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                        join (eq($$427, $$428)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                                                                                                                                                                         -- HYBRID_HASH_JOIN [$$428][$$427]  |PARTITIONED|
+                                                                                                                                                                                                          exchange
                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                            assign [$$425, $$428] <- [$$409, $$417] project: [$$425, $$428]
                                                                                                                                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                              exchange
                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                replicate
                                                                                                                                                                                                                 -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                   -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                                                                                    assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                      exchange
                                                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                        replicate
                                                                                                                                                                                                                         -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                          exchange
                                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                            assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                              exchange
                                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                                -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                                                                                                data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                    empty-tuple-source
                                                                                                                                                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                                          exchange
                                                                                                                                                                                                           -- HASH_PARTITION_EXCHANGE [$$427]  |PARTITIONED|
+                                                                                                                                                                                                            select (eq($$430.getField("to_u"), "aaaaa")) project: [$$422, $$426, $$427] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                                                                                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                                              exchange
                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                replicate
                                                                                                                                                                                                                 -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                    assign [$$427, $$422] <- [$$430.getField("y_id"), $$430.getField("b")]
                                                                                                                                                                                                                     -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                      assign [$$426, $$430] <- [$$411, $$413] project: [$$426, $$430]
                                                                                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                        exchange
                                                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                          replicate
                                                                                                                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                            exchange
                                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                              -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                                                              data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                                                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                  empty-tuple-source
                                                                                                                                                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                              exchange
                                                                                                                                                                                               -- HASH_PARTITION_EXCHANGE [$$435, $$436]  |PARTITIONED|
+                                                                                                                                                                                                assign [$$437] <- [true]
                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                  project ([$$438, $$435, $$436])
                                                                                                                                                                                                   -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                                    exchange
                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                      join (eq($$442, $$443))
                                                                                                                                                                                                       -- HYBRID_HASH_JOIN [$$443][$$442]  |PARTITIONED|
+                                                                                                                                                                                                        exchange
                                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                          project ([$$438, $$435, $$436, $$443])
                                                                                                                                                                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                                            exchange
                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                              join (eq($$444, $$445)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00015E11]
                                                                                                                                                                                                               -- HYBRID_HASH_JOIN [$$445][$$444]  |PARTITIONED|
+                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                  replicate
                                                                                                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                    exchange
                                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                      project ([$$435, $$436, $$445])
                                                                                                                                                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                                                                                                                                        exchange
                                                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                          join (eq($$448, $$445)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                                                                                                                                                                                           -- HYBRID_HASH_JOIN [$$445][$$448]  |PARTITIONED|
+                                                                                                                                                                                                                            exchange
                                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                              assign [$$435, $$445] <- [$$409, $$417] project: [$$435, $$445]
                                                                                                                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                  replicate
                                                                                                                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                                    exchange
                                                                                                                                                                                                                                     -- HASH_PARTITION_EXCHANGE [$$417]  |PARTITIONED|
+                                                                                                                                                                                                                                      assign [$$417, $$409] <- [$$391, $$399] project: [$$417, $$409]
                                                                                                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                                        exchange
                                                                                                                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                          replicate
                                                                                                                                                                                                                                           -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                                            exchange
                                                                                                                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                              assign [$$391] <- [$$400.getField("x_id")] project: [$$391, $$399]
                                                                                                                                                                                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                                                  -- DATASOURCE_SCAN (test.collection0)  |PARTITIONED|
+                                                                                                                                                                                                                                                  data-scan []<-[$$399, $$400] <- test.collection0
+                                                                                                                                                                                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                                                    exchange
                                                                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                                      empty-tuple-source
                                                                                                                                                                                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                                                            exchange
                                                                                                                                                                                                                             -- HASH_PARTITION_EXCHANGE [$$448]  |PARTITIONED|
+                                                                                                                                                                                                                              select (eq($$450.getField("to_u"), "aaaaa")) project: [$$436, $$448] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                                                                                                                                               -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                  replicate
                                                                                                                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                                    exchange
                                                                                                                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                      assign [$$448] <- [$$450.getField("y_id")]
                                                                                                                                                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                                        assign [$$436, $$450] <- [$$411, $$413] project: [$$436, $$450]
                                                                                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                                          exchange
                                                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                            replicate
                                                                                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                                              exchange
                                                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                                                -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                                                                                data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                                                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                                    empty-tuple-source
                                                                                                                                                                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                                                exchange
                                                                                                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                  replicate
                                                                                                                                                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                    exchange
                                                                                                                                                                                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                      select (eq($$441.getField("to_u"), "aaaaa")) project: [$$438, $$443, $$444] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                                                                                                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                                                                                                                                                                                        assign [$$444, $$443, $$438] <- [$$441.getField("y_id"), $$441.getField("a"), $$441.getField("b")]
                                                                                                                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                          exchange
                                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                            replicate
                                                                                                                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                              exchange
                                                                                                                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                assign [$$447, $$441] <- [$$411, $$413] project: [$$441]
                                                                                                                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                                                                                                                  exchange
                                                                                                                                                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                    replicate
                                                                                                                                                                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                                                                                                                                                                      exchange
                                                                                                                                                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                                                                                                                        -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                                                                                                                        data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                                                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                                                                                                                          exchange
                                                                                                                                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                                                            empty-tuple-source
                                                                                                                                                                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                                                                                                                        exchange
                                                                                                                                                                                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                                                                                                                          unnest $$442 <- scan-collection(array: [ 66, 67, 26, 12, 13 ])
                                                                                                                                                                                                           -- UNNEST  |UNPARTITIONED|
+                                                                                                                                                                                                            empty-tuple-source
                                                                                                                                                                                                             -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                                                                                                                exchange
                                                                                                                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                                                                  unnest $$406 <- scan-collection(array: [ 66, 67, 26, 12, 13 ])
                                                                                                                                                   -- UNNEST  |UNPARTITIONED|
+                                                                                                                                                    empty-tuple-source
                                                                                                                                                     -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                                                                                      exchange
                                                                                                                       -- HASH_PARTITION_EXCHANGE [$$390]  |PARTITIONED|
+                                                                                                                        assign [$$397, $$392, $$390] <- [$$436, $$450, $$448] project: [$$397, $$390]
                                                                                                                         -- ASSIGN  |PARTITIONED|
+                                                                                                                          exchange
                                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                            replicate
                                                                                                                             -- REPLICATE  |PARTITIONED|
+                                                                                                                              exchange
                                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                assign [$$448] <- [$$450.getField("y_id")]
                                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                                  assign [$$436, $$450] <- [$$411, $$413] project: [$$436, $$450]
                                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                                    exchange
                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                      replicate
                                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                                        exchange
                                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                          -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                          data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                            exchange
                                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                              empty-tuple-source
                                                                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                              exchange
                                                                                                               -- HASH_PARTITION_EXCHANGE [$$216]  |PARTITIONED|
+                                                                                                                assign [$$172, $$216, $$180] <- [$$L.getField("posi"), $$L.getField("y_id"), $$L.getField("b")] project: [$$180, $$172, $$216]
                                                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                                                  assign [$$L] <- [$$441] project: [$$L]
                                                                                                                   -- ASSIGN  |PARTITIONED|
+                                                                                                                    exchange
                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                      replicate
                                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                                        exchange
                                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                          assign [$$447, $$441] <- [$$411, $$413] project: [$$441]
                                                                                                                           -- ASSIGN  |PARTITIONED|
+                                                                                                                            exchange
                                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                              replicate
                                                                                                                               -- REPLICATE  |PARTITIONED|
+                                                                                                                                exchange
                                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                                  -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                                                                                                                  data-scan []<-[$$411, $$413] <- test.collection1 [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                                    exchange
                                                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                                      empty-tuple-source
                                                                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                      exchange
                                                                                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                        unnest $$200 <- scan-collection(array: [ "a", "b" ])
                                                                                                         -- UNNEST  |UNPARTITIONED|
+                                                                                                          empty-tuple-source
                                                                                                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                              exchange
                                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                unnest $$201 <- scan-collection(array: [ "a", "b" ])
                                                 -- UNNEST  |UNPARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        unnest $$202 <- scan-collection(array: [ 66, 67, 12, 13 ])
                                         -- UNNEST  |UNPARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query_issue849-2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query_issue849-2.plan
index a73a314..3863ad7 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query_issue849-2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query_issue849-2.plan
@@ -1,30 +1,28 @@
--- COMMIT  |PARTITIONED|
-  -- STREAM_PROJECT  |PARTITIONED|
-    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-      -- INSERT_DELETE  |PARTITIONED|
-        -- HASH_PARTITION_EXCHANGE [$$3]  |PARTITIONED|
-          -- ASSIGN  |UNPARTITIONED|
-            -- ASSIGN  |UNPARTITIONED|
-              -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
--- COMMIT  |PARTITIONED|
-  -- STREAM_PROJECT  |PARTITIONED|
-    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-      -- INSERT_DELETE  |PARTITIONED|
-        -- HASH_PARTITION_EXCHANGE [$$3]  |PARTITIONED|
-          -- ASSIGN  |UNPARTITIONED|
-            -- ASSIGN  |UNPARTITIONED|
-              -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+distribute result [$$46]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$46] <- [{"x": $$x, "y": $$43}] project: [$$46]
     -- ASSIGN  |PARTITIONED|
+      project ([$$x, $$43])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$47, $$49))
           -- HYBRID_HASH_JOIN [$$47][$$49]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
-              -- DATASOURCE_SCAN (test.s)  |PARTITIONED|
+              data-scan []<-[$$47, $$x] <- test.s
+              -- DATASOURCE_SCAN  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$49]  |PARTITIONED|
+              assign [$$43, $$49] <- [$$z.getField("c"), $$z.getField("a")] project: [$$43, $$49]
               -- ASSIGN  |UNPARTITIONED|
+                unnest $$z <- scan-collection(unordered-list-constructor({"a": 1, "c": 1}, {"a": 2, "c": 2}, {"a": 1, "c": null}))
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query_issue849.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query_issue849.plan
index 131d733..b2cb6eb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query_issue849.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/query_issue849.plan
@@ -1,32 +1,32 @@
--- COMMIT  |PARTITIONED|
-  -- STREAM_PROJECT  |PARTITIONED|
-    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-      -- INSERT_DELETE  |PARTITIONED|
-        -- HASH_PARTITION_EXCHANGE [$$3]  |PARTITIONED|
-          -- ASSIGN  |UNPARTITIONED|
-            -- ASSIGN  |UNPARTITIONED|
-              -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
--- COMMIT  |PARTITIONED|
-  -- STREAM_PROJECT  |PARTITIONED|
-    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-      -- INSERT_DELETE  |PARTITIONED|
-        -- HASH_PARTITION_EXCHANGE [$$3]  |PARTITIONED|
-          -- ASSIGN  |UNPARTITIONED|
-            -- ASSIGN  |UNPARTITIONED|
-              -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+distribute result [$$45]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$45] <- [{"x": $$x, "y": $$47}] project: [$$45]
     -- ASSIGN  |PARTITIONED|
+      project ([$$x, $$47])
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          join (eq($$48, $$47))
           -- HYBRID_HASH_JOIN [$$48][$$47]  |PARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+              assign [$$48] <- [$$x.getField(0)]
               -- ASSIGN  |UNPARTITIONED|
+                unnest $$x <- scan-collection(multiset: {{ { "a": 1 }, { "a": 2 } }})
                 -- UNNEST  |UNPARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+            exchange
             -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
+              project ([$$47])
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.s)  |PARTITIONED|
+                  data-scan []<-[$$47, $$z] <- test.s
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-01.plan
index e981647..8283baf 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-01.plan
@@ -1,7 +1,14 @@
+distribute result [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-intersects($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- DATASOURCE_SCAN (IndexGeoJSON.Geometries)  |PARTITIONED|
+        data-scan []<-[$$18, $$geo] <- IndexGeoJSON.Geometries [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+        -- DATASOURCE_SCAN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            empty-tuple-source
             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-02.plan
index e981647..f868788 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-02.plan
@@ -1,7 +1,14 @@
+distribute result [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-contains($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- DATASOURCE_SCAN (IndexGeoJSON.Geometries)  |PARTITIONED|
+        data-scan []<-[$$18, $$geo] <- IndexGeoJSON.Geometries [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+        -- DATASOURCE_SCAN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            empty-tuple-source
             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-03.plan
index e981647..f33cc35 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-03.plan
@@ -1,7 +1,14 @@
+distribute result [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-crosses($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- DATASOURCE_SCAN (IndexGeoJSON.Geometries)  |PARTITIONED|
+        data-scan []<-[$$18, $$geo] <- IndexGeoJSON.Geometries [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+        -- DATASOURCE_SCAN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            empty-tuple-source
             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-04.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-04.plan
index e981647..ec0ca81 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-04.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-04.plan
@@ -1,7 +1,14 @@
+distribute result [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-overlaps($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- DATASOURCE_SCAN (IndexGeoJSON.Geometries)  |PARTITIONED|
+        data-scan []<-[$$18, $$geo] <- IndexGeoJSON.Geometries [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+        -- DATASOURCE_SCAN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            empty-tuple-source
             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-05.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-05.plan
index e981647..5b51a8d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-05.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-05.plan
@@ -1,7 +1,14 @@
+distribute result [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-touches($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- DATASOURCE_SCAN (IndexGeoJSON.Geometries)  |PARTITIONED|
+        data-scan []<-[$$18, $$geo] <- IndexGeoJSON.Geometries [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+        -- DATASOURCE_SCAN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            empty-tuple-source
             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-06.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-06.plan
index e981647..8c546df 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-06.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-06.plan
@@ -1,7 +1,14 @@
+distribute result [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-within($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- DATASOURCE_SCAN (IndexGeoJSON.Geometries)  |PARTITIONED|
+        data-scan []<-[$$18, $$geo] <- IndexGeoJSON.Geometries [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+        -- DATASOURCE_SCAN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            empty-tuple-source
             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-07.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-07.plan
index e981647..210250c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-07.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index-geometry/rtree-sidx-idxonly-07.plan
@@ -1,7 +1,14 @@
+distribute result [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (st-disjoint($$geo.getField(1), POLYGON ((1 1, 5 1, 5 5, 1 5, 1 1)))) project: [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- DATASOURCE_SCAN (IndexGeoJSON.Geometries)  |PARTITIONED|
+        data-scan []<-[$$18, $$geo] <- IndexGeoJSON.Geometries [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+        -- DATASOURCE_SCAN  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            empty-tuple-source
             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index/rtree-sidx-idxonly-01-disable-idxonly.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index/rtree-sidx-idxonly-01-disable-idxonly.plan
index c885e05..87284a0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index/rtree-sidx-idxonly-01-disable-idxonly.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index/rtree-sidx-idxonly-01-disable-idxonly.plan
@@ -1,12 +1,24 @@
+distribute result [$$53] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$53] <- [{"$1": $$56}] project: [$$53] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$56] <- [agg-sql-sum($$57)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$57] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (spatial-intersect($$x.getField(8), polygon: [ point: { x: 0.0, y: 0.0 }, point: { x: 2.0, y: 2.0 }, point: { x: 0.0, y: 2.0 }, point: { x: 2.0, y: 0.0 } ])) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$x]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.Fragile_raw)  |PARTITIONED|
+                  data-scan []<-[$$55, $$x] <- test.Fragile_raw [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index/rtree-sidx-idxonly-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index/rtree-sidx-idxonly-01.plan
index c885e05..87284a0 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index/rtree-sidx-idxonly-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/rtree-index/rtree-sidx-idxonly-01.plan
@@ -1,12 +1,24 @@
+distribute result [$$53] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$53] <- [{"$1": $$56}] project: [$$53] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$56] <- [agg-sql-sum($$57)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$57] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- AGGREGATE  |PARTITIONED|
+            select (spatial-intersect($$x.getField(8), polygon: [ point: { x: 0.0, y: 0.0 }, point: { x: 2.0, y: 2.0 }, point: { x: 0.0, y: 2.0 }, point: { x: 2.0, y: 0.0 } ])) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              project ([$$x]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.Fragile_raw)  |PARTITIONED|
+                  data-scan []<-[$$55, $$x] <- test.Fragile_raw [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/skip-index/skip-secondary-btree-index-2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/skip-index/skip-secondary-btree-index-2.plan
index c823a61..e13e99a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/skip-index/skip-secondary-btree-index-2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/skip-index/skip-secondary-btree-index-2.plan
@@ -1,9 +1,18 @@
+distribute result [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    select (and(ge($$18, "Max"), le($$18, "Roger"))) project: [$$emp] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- STREAM_SELECT  |PARTITIONED|
+      assign [$$18] <- [$$emp.getField(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- ASSIGN  |PARTITIONED|
+        project ([$$emp]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN (test.testdst)  |PARTITIONED|
+            data-scan []<-[$$19, $$emp] <- test.testdst [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+            -- DATASOURCE_SCAN  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                empty-tuple-source
                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/split-materialization.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/split-materialization.plan
index 0a7b276..e9db6d8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/split-materialization.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/split-materialization.plan
@@ -1,17 +1,34 @@
+distribute result [$$92] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$92] <- [{"user1": {"id": $$97, "name": $$103}, "user2": {"id": $$98, "name": $$104}}] project: [$$92] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
       -- SORT_MERGE_EXCHANGE [$$97(ASC), $$98(ASC) ]  |PARTITIONED|
+        order (ASC, $$97) (ASC, $$98) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
         -- STABLE_SORT [$$97(ASC), $$98(ASC)]  |PARTITIONED|
+          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (lt(count($$d.getField(4)), 2)) project: [$$97, $$103, $$98, $$104] [cardinality: 5.0E11, op-cost: 5.00004E11, total-cost: 5.00009E11]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$104] <- [$$d.getField(2)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- BTREE_SEARCH (TinySocial.FacebookUsers.FacebookUsers)  |PARTITIONED|
+                  unnest-map [$$98, $$d] <- index-search("FacebookUsers", 0, "Default", "TinySocial", "FacebookUsers", true, true, 1, $$97, 0, false, true, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- BTREE_SEARCH  |PARTITIONED|
+                    exchange
                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                      select (lt(count($$d.getField(4)), 2)) project: [$$97, $$103] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- STREAM_SELECT  |PARTITIONED|
+                        assign [$$103] <- [$$d.getField(2)]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+                            data-scan []<-[$$97, $$d] <- TinySocial.FacebookUsers [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/split-materialization_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/split-materialization_ps.plan
index 57bd09d..d78656a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/split-materialization_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/split-materialization_ps.plan
@@ -1,40 +1,80 @@
+distribute result [$$92] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$92] <- [{"user1": {"id": $$97, "name": $$103}, "user2": {"id": $$98, "name": $$104}}] project: [$$92] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$97) (ASC, $$98) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
         -- STABLE_SORT [$$97(ASC), $$98(ASC)]  |PARTITIONED|
+          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
           -- RANGE_PARTITION_EXCHANGE [$$97(ASC), $$98(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$110 [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
             -- FORWARD  |PARTITIONED|
+              exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
                 -- REPLICATE  |PARTITIONED|
+                  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    select (lt(count($$d.getField(4)), 2)) project: [$$97, $$103, $$98, $$104] [cardinality: 5.0E11, op-cost: 5.00004E11, total-cost: 5.00009E11]
                     -- STREAM_SELECT  |PARTITIONED|
+                      assign [$$104] <- [$$d.getField(2)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ASSIGN  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- BTREE_SEARCH (TinySocial.FacebookUsers.FacebookUsers)  |PARTITIONED|
+                          unnest-map [$$98, $$d] <- index-search("FacebookUsers", 0, "Default", "TinySocial", "FacebookUsers", true, true, 1, $$97, 0, false, true, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange
                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                              select (lt(count($$d.getField(4)), 2)) project: [$$97, $$103] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$103] <- [$$d.getField(2)]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+                                    data-scan []<-[$$97, $$d] <- TinySocial.FacebookUsers [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$110] <- [agg-range-map($$107, $$108, $$109)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$107, $$108, $$109] <- [agg-local-sampling($$97, $$98), agg-null-writer($$97), agg-null-writer($$98)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$97, $$98])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
                           -- REPLICATE  |PARTITIONED|
+                            exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 5.00009E11]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              select (lt(count($$d.getField(4)), 2)) project: [$$97, $$103, $$98, $$104] [cardinality: 5.0E11, op-cost: 5.00004E11, total-cost: 5.00009E11]
                               -- STREAM_SELECT  |PARTITIONED|
+                                assign [$$104] <- [$$d.getField(2)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH (TinySocial.FacebookUsers.FacebookUsers)  |PARTITIONED|
+                                    unnest-map [$$98, $$d] <- index-search("FacebookUsers", 0, "Default", "TinySocial", "FacebookUsers", true, true, 1, $$97, 0, false, true, false) [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      exchange
                                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        select (lt(count($$d.getField(4)), 2)) project: [$$97, $$103] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$103] <- [$$d.getField(2)]
                                           -- ASSIGN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN (TinySocial.FacebookUsers)  |PARTITIONED|
+                                              data-scan []<-[$$97, $$d] <- TinySocial.FacebookUsers [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-01.plan
index ea8f0d5..ebf5c9e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-01.plan
@@ -1,8 +1,16 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"c_id": $$18}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$t.getField("c_s"), "hello")) project: [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+          data-scan []<-[$$18, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-02.plan
index ea8f0d5..ebf5c9e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-02.plan
@@ -1,8 +1,16 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"c_id": $$18}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$t.getField("c_s"), "hello")) project: [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+          data-scan []<-[$$18, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-03.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-03.plan
index ea8f0d5..ebf5c9e 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-03.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-03.plan
@@ -1,8 +1,16 @@
+distribute result [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$17] <- [{"c_id": $$18}] project: [$$17] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      select (eq($$t.getField("c_s"), "hello")) project: [$$18] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- STREAM_SELECT  |PARTITIONED|
+        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- DATASOURCE_SCAN (test.TestOpen)  |PARTITIONED|
+          data-scan []<-[$$18, $$t] <- test.TestOpen [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+          -- DATASOURCE_SCAN  |PARTITIONED|
+            exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              empty-tuple-source
               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-index-01.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-index-01.plan
index dd532c2..ea9caf2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-index-01.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-index-01.plan
@@ -1,12 +1,24 @@
+distribute result [$$27] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$27] <- [{"id": $$30, "fname": $$29, "lname": $$33, "age": $$34}] project: [$$27] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$30(ASC) ]  |PARTITIONED|
+        order (ASC, $$30) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$30(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$29, "Julio")) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$34, $$33, $$29] <- [$$l.getField(3), $$l.getField(2), $$l.getField(1)] project: [$$30, $$34, $$33, $$29] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.employee)  |PARTITIONED|
+                  data-scan []<-[$$30, $$l] <- test.employee [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-index-02.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-index-02.plan
index ae51cc2..05b6f20 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-index-02.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/statement-params/statement-params-index-02.plan
@@ -1,12 +1,24 @@
+distribute result [$$27] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$27] <- [{"id": $$31, "fname": $$29, "lname": $$30, "age": $$34}] project: [$$27] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
     -- ASSIGN  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- SORT_MERGE_EXCHANGE [$$31(ASC) ]  |PARTITIONED|
+        order (ASC, $$31) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(eq($$30, "Isa"), eq($$29, "Julio"))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- STREAM_SELECT  |PARTITIONED|
+              assign [$$34, $$29, $$30] <- [$$l.getField(3), $$l.getField(1), $$l.getField(2)] project: [$$31, $$34, $$29, $$30] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ASSIGN  |PARTITIONED|
+                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- DATASOURCE_SCAN (test.employee)  |PARTITIONED|
+                  data-scan []<-[$$31, $$l] <- test.employee [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_2.plan
index ed5067c..7869a45 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_2.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_2.plan
@@ -1,26 +1,49 @@
+distribute result [$$26]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$26(ASC) ]  |PARTITIONED|
+    select ($$18) project: [$$26]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
-                {
+        group by ([$$26 := $$22]) decor ([]) {
+                  aggregate [$$18] <- [non-empty-stream()]
                   -- AGGREGATE  |LOCAL|
+                    select (not(is-missing($$25)))
                     -- STREAM_SELECT  |LOCAL|
+                      nested tuple source
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$22)
             -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                project ([$$25, $$22])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    left outer join (eq($$23, $#1))
                     -- HYBRID_HASH_JOIN [$$23][$#1]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
+                        assign [$$23] <- [$$c.getField(1)] project: [$$22, $$23]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                            data-scan []<-[$$22, $$c] <- tpch.Customer
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                        assign [$$25] <- [true]
                         -- ASSIGN  |UNPARTITIONED|
+                          unnest $#1 <- scan-collection(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ])
                           -- UNNEST  |UNPARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_2_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_2_ps.plan
index d587010..22cc503 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_2_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_2_ps.plan
@@ -1,63 +1,120 @@
+distribute result [$$26]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    order (ASC, $$26)
     -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+      exchange
       -- RANGE_PARTITION_EXCHANGE [$$26(ASC)]  |PARTITIONED|
+        forward: shared-variable = $$29
         -- FORWARD  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            replicate
             -- REPLICATE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select ($$18) project: [$$26]
                 -- STREAM_SELECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
-                            {
+                    group by ([$$26 := $$22]) decor ([]) {
+                              aggregate [$$18] <- [non-empty-stream()]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$25)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$22)
                         -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                            project ([$$25, $$22])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                left outer join (eq($$23, $#1))
                                 -- HYBRID_HASH_JOIN [$$23][$#1]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
+                                    assign [$$23] <- [$$c.getField(1)] project: [$$22, $$23]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                        data-scan []<-[$$22, $$c] <- tpch.Customer
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                                    assign [$$25] <- [true]
                                     -- ASSIGN  |UNPARTITIONED|
+                                      unnest $#1 <- scan-collection(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ])
                                       -- UNNEST  |UNPARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+          exchange
           -- BROADCAST_EXCHANGE  |PARTITIONED|
+            aggregate [$$29] <- [agg-range-map($$27, $$28)]
             -- AGGREGATE  |UNPARTITIONED|
+              exchange
               -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                aggregate [$$27, $$28] <- [agg-local-sampling($$26), agg-null-writer($$26)]
                 -- AGGREGATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    replicate
                     -- REPLICATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        select ($$18) project: [$$26]
                         -- STREAM_SELECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
-                                    {
+                            group by ([$$26 := $$22]) decor ([]) {
+                                      aggregate [$$18] <- [non-empty-stream()]
                                       -- AGGREGATE  |LOCAL|
+                                        select (not(is-missing($$25)))
                                         -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$22)
                                 -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                                    project ([$$25, $$22])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        left outer join (eq($$23, $#1))
                                         -- HYBRID_HASH_JOIN [$$23][$#1]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
+                                            assign [$$23] <- [$$c.getField(1)] project: [$$22, $$23]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                                data-scan []<-[$$22, $$c] <- tpch.Customer
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                                            assign [$$25] <- [true]
                                             -- ASSIGN  |UNPARTITIONED|
+                                              unnest $#1 <- scan-collection(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ])
                                               -- UNNEST  |UNPARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_4.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_4.plan
index 0f33a1e..a4e3699 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_4.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_4.plan
@@ -1,26 +1,49 @@
+distribute result [$$25]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+    select ($$17) project: [$$25]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$21]  |PARTITIONED|
-                {
+        group by ([$$25 := $$21]) decor ([]) {
+                  aggregate [$$17] <- [non-empty-stream()]
                   -- AGGREGATE  |LOCAL|
+                    select (not(is-missing($$24)))
                     -- STREAM_SELECT  |LOCAL|
+                      nested tuple source
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$21]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$21)
             -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$21]  |PARTITIONED|
+                project ([$$24, $$21])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    left outer join (eq($$22, $#1))
                     -- HYBRID_HASH_JOIN [$$22][$#1]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                        assign [$$22] <- [$$c.getField(1)] project: [$$21, $$22]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                            data-scan []<-[$$21, $$c] <- tpch.Customer
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                        assign [$$24] <- [true]
                         -- ASSIGN  |UNPARTITIONED|
+                          unnest $#1 <- scan-collection(cast(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ]))
                           -- UNNEST  |UNPARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_4_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_4_ps.plan
index 55d6709..6c20d83 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_4_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_4_ps.plan
@@ -1,63 +1,120 @@
+distribute result [$$25]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    order (ASC, $$25)
     -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+      exchange
       -- RANGE_PARTITION_EXCHANGE [$$25(ASC)]  |PARTITIONED|
+        forward: shared-variable = $$28
         -- FORWARD  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            replicate
             -- REPLICATE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select ($$17) project: [$$25]
                 -- STREAM_SELECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$21]  |PARTITIONED|
-                            {
+                    group by ([$$25 := $$21]) decor ([]) {
+                              aggregate [$$17] <- [non-empty-stream()]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$24)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$21]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$21)
                         -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$21]  |PARTITIONED|
+                            project ([$$24, $$21])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                left outer join (eq($$22, $#1))
                                 -- HYBRID_HASH_JOIN [$$22][$#1]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                                    assign [$$22] <- [$$c.getField(1)] project: [$$21, $$22]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                        data-scan []<-[$$21, $$c] <- tpch.Customer
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                                    assign [$$24] <- [true]
                                     -- ASSIGN  |UNPARTITIONED|
+                                      unnest $#1 <- scan-collection(cast(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ]))
                                       -- UNNEST  |UNPARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+          exchange
           -- BROADCAST_EXCHANGE  |PARTITIONED|
+            aggregate [$$28] <- [agg-range-map($$26, $$27)]
             -- AGGREGATE  |UNPARTITIONED|
+              exchange
               -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                aggregate [$$26, $$27] <- [agg-local-sampling($$25), agg-null-writer($$25)]
                 -- AGGREGATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    replicate
                     -- REPLICATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        select ($$17) project: [$$25]
                         -- STREAM_SELECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- PRE_CLUSTERED_GROUP_BY[$$21]  |PARTITIONED|
-                                    {
+                            group by ([$$25 := $$21]) decor ([]) {
+                                      aggregate [$$17] <- [non-empty-stream()]
                                       -- AGGREGATE  |LOCAL|
+                                        select (not(is-missing($$24)))
                                         -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- PRE_CLUSTERED_GROUP_BY[$$21]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$21)
                                 -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$21]  |PARTITIONED|
+                                    project ([$$24, $$21])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        left outer join (eq($$22, $#1))
                                         -- HYBRID_HASH_JOIN [$$22][$#1]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                                            assign [$$22] <- [$$c.getField(1)] project: [$$21, $$22]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                                data-scan []<-[$$21, $$c] <- tpch.Customer
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                                            assign [$$24] <- [true]
                                             -- ASSIGN  |UNPARTITIONED|
+                                              unnest $#1 <- scan-collection(cast(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ]))
                                               -- UNNEST  |UNPARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_6.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_6.plan
index ed5067c..7869a45 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_6.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_6.plan
@@ -1,26 +1,49 @@
+distribute result [$$26]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- SORT_MERGE_EXCHANGE [$$26(ASC) ]  |PARTITIONED|
+    select ($$18) project: [$$26]
     -- STREAM_SELECT  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
-                {
+        group by ([$$26 := $$22]) decor ([]) {
+                  aggregate [$$18] <- [non-empty-stream()]
                   -- AGGREGATE  |LOCAL|
+                    select (not(is-missing($$25)))
                     -- STREAM_SELECT  |LOCAL|
+                      nested tuple source
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            order (ASC, $$22)
             -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+              exchange
               -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                project ([$$25, $$22])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    left outer join (eq($$23, $#1))
                     -- HYBRID_HASH_JOIN [$$23][$#1]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
+                        assign [$$23] <- [$$c.getField(1)] project: [$$22, $$23]
                         -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                            data-scan []<-[$$22, $$c] <- tpch.Customer
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                        assign [$$25] <- [true]
                         -- ASSIGN  |UNPARTITIONED|
+                          unnest $#1 <- scan-collection(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ])
                           -- UNNEST  |UNPARTITIONED|
+                            empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_6_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_6_ps.plan
index d587010..22cc503 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_6_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/subquery/in_as_or_6_ps.plan
@@ -1,63 +1,120 @@
+distribute result [$$26]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    order (ASC, $$26)
     -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
+      exchange
       -- RANGE_PARTITION_EXCHANGE [$$26(ASC)]  |PARTITIONED|
+        forward: shared-variable = $$29
         -- FORWARD  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            replicate
             -- REPLICATE  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                select ($$18) project: [$$26]
                 -- STREAM_SELECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
-                            {
+                    group by ([$$26 := $$22]) decor ([]) {
+                              aggregate [$$18] <- [non-empty-stream()]
                               -- AGGREGATE  |LOCAL|
+                                select (not(is-missing($$25)))
                                 -- STREAM_SELECT  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        order (ASC, $$22)
                         -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                          exchange
                           -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                            project ([$$25, $$22])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                left outer join (eq($$23, $#1))
                                 -- HYBRID_HASH_JOIN [$$23][$#1]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
+                                    assign [$$23] <- [$$c.getField(1)] project: [$$22, $$23]
                                     -- ASSIGN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                        data-scan []<-[$$22, $$c] <- tpch.Customer
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                                    assign [$$25] <- [true]
                                     -- ASSIGN  |UNPARTITIONED|
+                                      unnest $#1 <- scan-collection(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ])
                                       -- UNNEST  |UNPARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+          exchange
           -- BROADCAST_EXCHANGE  |PARTITIONED|
+            aggregate [$$29] <- [agg-range-map($$27, $$28)]
             -- AGGREGATE  |UNPARTITIONED|
+              exchange
               -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                aggregate [$$27, $$28] <- [agg-local-sampling($$26), agg-null-writer($$26)]
                 -- AGGREGATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    replicate
                     -- REPLICATE  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        select ($$18) project: [$$26]
                         -- STREAM_SELECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
-                                    {
+                            group by ([$$26 := $$22]) decor ([]) {
+                                      aggregate [$$18] <- [non-empty-stream()]
                                       -- AGGREGATE  |LOCAL|
+                                        select (not(is-missing($$25)))
                                         -- STREAM_SELECT  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   }
+                            -- PRE_CLUSTERED_GROUP_BY[$$22]  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                order (ASC, $$22)
                                 -- STABLE_SORT [$$22(ASC)]  |PARTITIONED|
+                                  exchange
                                   -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                                    project ([$$25, $$22])
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        left outer join (eq($$23, $#1))
                                         -- HYBRID_HASH_JOIN [$$23][$#1]  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
+                                            assign [$$23] <- [$$c.getField(1)] project: [$$22, $$23]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpch.Customer)  |PARTITIONED|
+                                                data-scan []<-[$$22, $$c] <- tpch.Customer
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- HASH_PARTITION_EXCHANGE [$#1]  |PARTITIONED|
+                                            assign [$$25] <- [true]
                                             -- ASSIGN  |UNPARTITIONED|
+                                              unnest $#1 <- scan-collection(array: [ "Customer#000000001", "Customer#000000002", "Customer#000000003" ])
                                               -- UNNEST  |UNPARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1580.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1580.plan
index aaac258..de575ef 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1580.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1580.plan
@@ -1,69 +1,132 @@
+distribute result [$$125] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 100 [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
     -- STREAM_LIMIT  |UNPARTITIONED|
+      assign [$$125] <- [{"state": $$ca_state, "cnt": $$136}] project: [$$125] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
       -- ASSIGN  |PARTITIONED|
+        exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
         -- SORT_MERGE_EXCHANGE [$$136(ASC) ]  |PARTITIONED|
+          limit 100 [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
           -- STREAM_LIMIT  |PARTITIONED|
+            exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              order (topK: 100) (ASC, $$136) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
               -- STABLE_SORT [topK: 100] [$$136(ASC)]  |PARTITIONED|
+                exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (ge($$135, 10)) project: [$$ca_state, $$136]
                   -- STREAM_SELECT  |PARTITIONED|
+                    exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- SORT_GROUP_BY[$$145]  |PARTITIONED|
-                              {
+                      group by ([$$ca_state := $$145]) decor ([]) {
+                                aggregate [$$135, $$136] <- [agg-sql-sum($$143), agg-sql-sum($$144)]
                                 -- AGGREGATE  |LOCAL|
+                                  nested tuple source
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
+                             } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+                      -- SORT_GROUP_BY[$$145]  |PARTITIONED|
+                        exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                         -- HASH_PARTITION_EXCHANGE [$$145]  |PARTITIONED|
-                          -- SORT_GROUP_BY[$$126]  |PARTITIONED|
-                                  {
+                          group by ([$$145 := $$126]) decor ([]) {
+                                    aggregate [$$143, $$144] <- [agg-sql-count($$a), agg-sql-count($$a)]
                                     -- AGGREGATE  |LOCAL|
+                                      nested tuple source
                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
+                                 } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+                          -- SORT_GROUP_BY[$$126]  |PARTITIONED|
+                            exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              project ([$$a, $$126]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  join (eq($$129, $$132)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                                   -- HYBRID_HASH_JOIN [$$129][$$132]  |PARTITIONED|
+                                    exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$a, $$126, $$129]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          join (eq($$137, $$131)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                                           -- HYBRID_HASH_JOIN [$$137][$$131]  |PARTITIONED|
+                                            exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$a, $$126, $$129, $$137]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 5.00015E11]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  join (eq($$128, $$142)) [cardinality: 9.223372036854776E16, op-cost: 5.00004E11, total-cost: 5.00015E11]
                                                   -- HYBRID_HASH_JOIN [$$128][$$142]  |PARTITIONED|
+                                                    exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      project ([$$a, $$126, $$128]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                        exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          join (eq($$127, $$140)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                           -- HYBRID_HASH_JOIN [$$127][$$140]  |PARTITIONED|
+                                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                             -- HASH_PARTITION_EXCHANGE [$$127]  |PARTITIONED|
+                                                              assign [$$126] <- [$$a.getField(8)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- DATASOURCE_SCAN (tpcds.customer_address)  |PARTITIONED|
+                                                                  data-scan []<-[$$127, $$a] <- tpcds.customer_address [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                             -- HASH_PARTITION_EXCHANGE [$$140]  |PARTITIONED|
+                                                              assign [$$140] <- [$$c.getField(4)] project: [$$128, $$140] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                               -- ASSIGN  |PARTITIONED|
+                                                                exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- DATASOURCE_SCAN (tpcds.customer)  |PARTITIONED|
+                                                                  data-scan []<-[$$128, $$c] <- tpcds.customer [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      empty-tuple-source
                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                      assign [$$137, $$142] <- [$$s.getField(0), $$s.getField(3)] project: [$$129, $$137, $$142] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        project ([$$129, $$s]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                          exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                            data-scan []<-[$$129, $$130, $$s] <- tpcds.store_sales [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source
                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              project ([$$131]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN (tpcds.date_dim)  |PARTITIONED|
+                                                  data-scan []<-[$$131, $$d] <- tpcds.date_dim [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      empty-tuple-source
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                      project ([$$132]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN (tpcds.item)  |PARTITIONED|
+                                          data-scan []<-[$$132, $$i] <- tpcds.item [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1581.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1581.plan
index 6b377c1..41884c8 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1581.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1581.plan
@@ -1,184 +1,359 @@
+distribute result [$$149]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    join (true)
     -- NESTED_LOOP  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        project ([])
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- BTREE_SEARCH (tpcds.item.item)  |PARTITIONED|
+            unnest-map [$$153, $$item] <- index-search("item", 0, "Default", "tpcds", "item", false, false, 1, $$208, 1, $$209, true, true, true)
+            -- BTREE_SEARCH  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                assign [$$208, $$209] <- [1, 1]
                 -- ASSIGN  |PARTITIONED|
+                  empty-tuple-source
                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
       -- BROADCAST_EXCHANGE  |LOCAL|
+        assign [$$149] <- [{"bucket1": $$147}] project: [$$149] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
         -- ASSIGN  |LOCAL|
+          unnest $$147 <- scan-collection($$146) project: [$$147] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
           -- UNNEST  |LOCAL|
+            assign [$$146] <- [switch-case(true, lt(get-item($$200, 0), 25437), cast($$128), cast($$145))] project: [$$146] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
             -- ASSIGN  |LOCAL|
+              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
               -- ONE_TO_ONE_EXCHANGE  |LOCAL|
-                -- PRE_CLUSTERED_GROUP_BY[$$173]  |LOCAL|
-                        {
+                group by ([$$200 := $$173]) decor ([$$128]) {
+                          aggregate [$$145] <- [listify($$144)]
                           -- AGGREGATE  |LOCAL|
+                            aggregate [$$144] <- [listify($$143)]
                             -- AGGREGATE  |LOCAL|
+                              select (not(is-missing($$199)))
                               -- STREAM_SELECT  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
+                       } [cardinality: 0.0, op-cost: 0.0, total-cost: 1000000.0]
+                -- PRE_CLUSTERED_GROUP_BY[$$173]  |LOCAL|
+                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                   -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                    project ([$$128, $$143, $$199, $$173]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                     -- STREAM_PROJECT  |LOCAL|
+                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                        left outer join (eq($$173, $$174))
                         -- HYBRID_HASH_JOIN [$$173][$$174]  |LOCAL|
+                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |LOCAL|
-                            -- PRE_CLUSTERED_GROUP_BY[$$109]  |LOCAL|
-                                    {
+                            group by ([$$173 := $$109]) decor ([]) {
+                                      aggregate [$$128] <- [listify($$127)]
                                       -- AGGREGATE  |LOCAL|
+                                        aggregate [$$127] <- [listify($$126)]
                                         -- AGGREGATE  |LOCAL|
+                                          select (not(is-missing($$172)))
                                           -- STREAM_SELECT  |LOCAL|
+                                            nested tuple source
                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                    }
+                                   } [cardinality: 0.0, op-cost: 0.0, total-cost: 1000000.0]
+                            -- PRE_CLUSTERED_GROUP_BY[$$109]  |LOCAL|
+                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                                order (ASC, $$109) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- STABLE_SORT [$$109(ASC)]  |LOCAL|
+                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                    project ([$$126, $$172, $$109]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- STREAM_PROJECT  |UNPARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                        left outer join (eq($$109, $$166)) [cardinality: 9.223372036854776E16, op-cost: 1.000001E12, total-cost: 3.000009E12]
                                         -- HYBRID_HASH_JOIN [$$109][$$166]  |UNPARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            assign [$$109] <- [$$175] project: [$$109] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- ASSIGN  |UNPARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- REPLICATE  |UNPARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                    assign [$$175] <- [$$176] project: [$$175] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- ASSIGN  |UNPARTITIONED|
+                                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                        replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- REPLICATE  |UNPARTITIONED|
+                                                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                            aggregate [$$176] <- [listify($$183)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                             -- AGGREGATE  |UNPARTITIONED|
+                                                              aggregate [$$183] <- [agg-sql-sum($$206)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                               -- AGGREGATE  |UNPARTITIONED|
+                                                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                 -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                                  aggregate [$$206] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                   -- AGGREGATE  |PARTITIONED|
+                                                                    select (and(ge($$185, 1), le($$185, 20)))
                                                                     -- STREAM_SELECT  |PARTITIONED|
+                                                                      assign [$$185] <- [$$184.getField(10)] project: [$$185] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                           -- REPLICATE  |PARTITIONED|
+                                                                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              project ([$$184]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                  data-scan []<-[$$186, $$187, $$184] <- tpcds.store_sales [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      empty-tuple-source
                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                            join (true) [cardinality: 1.0E12, op-cost: 1.0E12, total-cost: 1.000006E12]
                                             -- NESTED_LOOP  |UNPARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                assign [$$166, $$172] <- [$$176, $$182] project: [$$166, $$172]
                                                 -- ASSIGN  |UNPARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                    replicate
                                                     -- REPLICATE  |UNPARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                        assign [$$182] <- [true]
                                                         -- ASSIGN  |UNPARTITIONED|
+                                                          select (lt(get-item($$176, 0), 25437)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                           -- STREAM_SELECT  |UNPARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                              replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                               -- REPLICATE  |UNPARTITIONED|
+                                                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                 -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                                  aggregate [$$176] <- [listify($$183)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                   -- AGGREGATE  |UNPARTITIONED|
+                                                                    aggregate [$$183] <- [agg-sql-sum($$206)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                     -- AGGREGATE  |UNPARTITIONED|
+                                                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                                        aggregate [$$206] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                         -- AGGREGATE  |PARTITIONED|
+                                                                          select (and(ge($$185, 1), le($$185, 20)))
                                                                           -- STREAM_SELECT  |PARTITIONED|
+                                                                            assign [$$185] <- [$$184.getField(10)] project: [$$185] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                             -- ASSIGN  |PARTITIONED|
+                                                                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                 -- REPLICATE  |PARTITIONED|
+                                                                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    project ([$$184]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                        -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                        data-scan []<-[$$186, $$187, $$184] <- tpcds.store_sales [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            empty-tuple-source
                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                assign [$$126] <- [{"$1": $$161}] project: [$$126]
                                                 -- ASSIGN  |UNPARTITIONED|
+                                                  aggregate [$$161] <- [agg-global-sql-avg($$204)]
                                                   -- AGGREGATE  |UNPARTITIONED|
+                                                    exchange
                                                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                      aggregate [$$204] <- [agg-local-sql-avg($$124)]
                                                       -- AGGREGATE  |PARTITIONED|
+                                                        select (and(ge($$151, 1), le($$151, 20))) project: [$$124] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- STREAM_SELECT  |PARTITIONED|
+                                                          assign [$$124, $$151] <- [$$store_sales.getField(14), $$store_sales.getField(10)] project: [$$124, $$151]
                                                           -- ASSIGN  |PARTITIONED|
+                                                            assign [$$store_sales] <- [$$184] project: [$$store_sales]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              exchange
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                 -- REPLICATE  |PARTITIONED|
+                                                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    project ([$$184]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                        data-scan []<-[$$186, $$187, $$184] <- tpcds.store_sales [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            empty-tuple-source
                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                            join (true)
                             -- NESTED_LOOP  |LOCAL|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                                assign [$$199] <- [true]
                                 -- ASSIGN  |LOCAL|
+                                  select (not(or(and($$212, not(is-unknown($$212)))))) project: [$$174]
                                   -- STREAM_SELECT  |LOCAL|
+                                    assign [$$212] <- [lt(get-item($$174, 0), 25437)]
                                     -- ASSIGN  |LOCAL|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |LOCAL|
-                                        -- PRE_CLUSTERED_GROUP_BY[$$175]  |LOCAL|
-                                                {
+                                        group by ([$$174 := $$175]) decor ([]) {
+                                                  aggregate [] <- []
                                                   -- AGGREGATE  |LOCAL|
+                                                    aggregate [] <- []
                                                     -- AGGREGATE  |LOCAL|
+                                                      select (not(is-missing($$182)))
                                                       -- STREAM_SELECT  |LOCAL|
+                                                        nested tuple source
                                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                               }
+                                        -- PRE_CLUSTERED_GROUP_BY[$$175]  |LOCAL|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+                                            order (ASC, $$175)
                                             -- STABLE_SORT [$$175(ASC)]  |LOCAL|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                project ([$$182, $$175])
                                                 -- STREAM_PROJECT  |UNPARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                    left outer join (eq($$175, $$176)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                     -- HYBRID_HASH_JOIN [$$175][$$176]  |UNPARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                        replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- REPLICATE  |UNPARTITIONED|
+                                                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                            assign [$$175] <- [$$176] project: [$$175] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                             -- ASSIGN  |UNPARTITIONED|
+                                                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                 -- REPLICATE  |UNPARTITIONED|
+                                                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                                    aggregate [$$176] <- [listify($$183)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                     -- AGGREGATE  |UNPARTITIONED|
+                                                                      aggregate [$$183] <- [agg-sql-sum($$206)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                       -- AGGREGATE  |UNPARTITIONED|
+                                                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                                          aggregate [$$206] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                           -- AGGREGATE  |PARTITIONED|
+                                                                            select (and(ge($$185, 1), le($$185, 20)))
                                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                                              assign [$$185] <- [$$184.getField(10)] project: [$$185] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                               -- ASSIGN  |PARTITIONED|
+                                                                                exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                   -- REPLICATE  |PARTITIONED|
+                                                                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      project ([$$184]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                       -- STREAM_PROJECT  |PARTITIONED|
+                                                                                        exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                          -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                          data-scan []<-[$$186, $$187, $$184] <- tpcds.store_sales [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                            exchange
                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                              empty-tuple-source
                                                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                        replicate
                                                         -- REPLICATE  |UNPARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                            assign [$$182] <- [true]
                                                             -- ASSIGN  |UNPARTITIONED|
+                                                              select (lt(get-item($$176, 0), 25437)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                               -- STREAM_SELECT  |UNPARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                                  replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                   -- REPLICATE  |UNPARTITIONED|
+                                                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                     -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                                                      aggregate [$$176] <- [listify($$183)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                       -- AGGREGATE  |UNPARTITIONED|
+                                                                        aggregate [$$183] <- [agg-sql-sum($$206)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                         -- AGGREGATE  |UNPARTITIONED|
+                                                                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                           -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                                                            aggregate [$$206] <- [agg-sql-count(1)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                             -- AGGREGATE  |PARTITIONED|
+                                                                              select (and(ge($$185, 1), le($$185, 20)))
                                                                               -- STREAM_SELECT  |PARTITIONED|
+                                                                                assign [$$185] <- [$$184.getField(10)] project: [$$185] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                 -- ASSIGN  |PARTITIONED|
+                                                                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                     -- REPLICATE  |PARTITIONED|
+                                                                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        project ([$$184]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                            -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                            data-scan []<-[$$186, $$187, $$184] <- tpcds.store_sales [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                              exchange
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                empty-tuple-source
                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                                assign [$$143] <- [{"$2": $$162}] project: [$$143]
                                 -- ASSIGN  |UNPARTITIONED|
+                                  aggregate [$$162] <- [agg-global-sql-avg($$207)]
                                   -- AGGREGATE  |UNPARTITIONED|
+                                    exchange
                                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                                      aggregate [$$207] <- [agg-local-sql-avg($$141)]
                                       -- AGGREGATE  |PARTITIONED|
+                                        select (and(ge($$152, 1), le($$152, 20))) project: [$$141]
                                         -- STREAM_SELECT  |PARTITIONED|
+                                          assign [$$141, $$152] <- [$$store_sales.getField(22), $$store_sales.getField(10)] project: [$$141, $$152]
                                           -- ASSIGN  |PARTITIONED|
+                                            assign [$$store_sales] <- [$$184] project: [$$store_sales]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                replicate [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- REPLICATE  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    project ([$$184]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                        data-scan []<-[$$186, $$187, $$184] <- tpcds.store_sales [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1591.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1591.plan
index b9d7b95..2323d7c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1591.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1591.plan
@@ -1,146 +1,274 @@
+distribute result [$$148] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    limit 100 [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
     -- STREAM_LIMIT  |UNPARTITIONED|
+      assign [$$148] <- [{"c": $$c, "ca": $$ca}] project: [$$148] [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
       -- ASSIGN  |PARTITIONED|
+        project ([$$c, $$ca]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
         -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
           -- SORT_MERGE_EXCHANGE [$$192(ASC) ]  |PARTITIONED|
+            limit 100 [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
             -- STREAM_LIMIT  |PARTITIONED|
+              select (or(neq($$163, 0), neq($$164, 0))) project: [$$192, $$c, $$ca]
               -- STREAM_SELECT  |PARTITIONED|
+                project ([$$164, $$192, $$c, $$ca, $$163]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$201, $$202]  |PARTITIONED|
-                            {
+                    group by ([$$192 := $$201; $$193 := $$202]) decor ([$$c; $$ca; $$163]) {
+                              aggregate [$$164] <- [agg-sum($$200)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+                    -- SORT_GROUP_BY[$$201, $$202]  |PARTITIONED|
+                      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                       -- HASH_PARTITION_EXCHANGE [$$201, $$202]  |PARTITIONED|
-                        -- PRE_CLUSTERED_GROUP_BY[$$189, $$190]  |PARTITIONED|
-                                {
+                        group by ([$$201 := $$189; $$202 := $$190]) decor ([$$c; $$ca; $$163]) {
+                                  aggregate [$$200] <- [agg-count({"cs1": $$cs1, "dd1": $$dd1})]
                                   -- AGGREGATE  |LOCAL|
+                                    select (not(is-missing($$191)))
                                     -- STREAM_SELECT  |LOCAL|
+                                      nested tuple source
                                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+                        -- PRE_CLUSTERED_GROUP_BY[$$189, $$190]  |PARTITIONED|
+                          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$189) (ASC, $$190) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                             -- STABLE_SORT [$$189(ASC), $$190(ASC)]  |PARTITIONED|
+                              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$c, $$ca, $$163, $$cs1, $$dd1, $$191, $$189, $$190]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    left outer join (eq($$189, $$171))
                                     -- HYBRID_HASH_JOIN [$$189][$$171]  |PARTITIONED|
+                                      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                       -- HASH_PARTITION_EXCHANGE [$$189]  |PARTITIONED|
-                                        -- SORT_GROUP_BY[$$198, $$199]  |PARTITIONED|
-                                                {
+                                        group by ([$$189 := $$198; $$190 := $$199]) decor ([$$c; $$ca]) {
+                                                  aggregate [$$163] <- [agg-sum($$197)]
                                                   -- AGGREGATE  |LOCAL|
+                                                    nested tuple source
                                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                }
+                                               } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+                                        -- SORT_GROUP_BY[$$198, $$199]  |PARTITIONED|
+                                          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                           -- HASH_PARTITION_EXCHANGE [$$198, $$199]  |PARTITIONED|
-                                            -- PRE_CLUSTERED_GROUP_BY[$$186, $$187]  |PARTITIONED|
-                                                    {
+                                            group by ([$$198 := $$186; $$199 := $$187]) decor ([$$c; $$ca]) {
+                                                      aggregate [$$197] <- [agg-count({"ws1": $$ws1, "dd1": $$dd1})]
                                                       -- AGGREGATE  |LOCAL|
+                                                        select (not(is-missing($$188)))
                                                         -- STREAM_SELECT  |LOCAL|
+                                                          nested tuple source
                                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                    }
+                                                   } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+                                            -- PRE_CLUSTERED_GROUP_BY[$$186, $$187]  |PARTITIONED|
+                                              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                order (ASC, $$186) (ASC, $$187) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                 -- STABLE_SORT [$$186(ASC), $$187(ASC)]  |PARTITIONED|
+                                                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    project ([$$c, $$ca, $$ws1, $$dd1, $$188, $$186, $$187]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        left outer join (eq($$186, $$169))
                                                         -- HYBRID_HASH_JOIN [$$186][$$169]  |PARTITIONED|
+                                                          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                           -- HASH_PARTITION_EXCHANGE [$$186]  |PARTITIONED|
+                                                            select (neq($$165, 0)) project: [$$c, $$ca, $$186, $$187]
                                                             -- STREAM_SELECT  |PARTITIONED|
+                                                              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- SORT_GROUP_BY[$$195, $$196]  |PARTITIONED|
-                                                                        {
+                                                                group by ([$$186 := $$195; $$187 := $$196]) decor ([$$c; $$ca]) {
+                                                                          aggregate [$$165] <- [agg-sum($$194)]
                                                                           -- AGGREGATE  |LOCAL|
+                                                                            nested tuple source
                                                                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                        }
+                                                                       } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+                                                                -- SORT_GROUP_BY[$$195, $$196]  |PARTITIONED|
+                                                                  exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                                   -- HASH_PARTITION_EXCHANGE [$$195, $$196]  |PARTITIONED|
-                                                                    -- PRE_CLUSTERED_GROUP_BY[$$150, $$151]  |PARTITIONED|
-                                                                            {
+                                                                    group by ([$$195 := $$150; $$196 := $$151]) decor ([$$c; $$ca]) {
+                                                                              aggregate [$$194] <- [agg-count({"ss1": $$ss1, "dd1": $$dd1})]
                                                                               -- AGGREGATE  |LOCAL|
+                                                                                select (not(is-missing($$185)))
                                                                                 -- STREAM_SELECT  |LOCAL|
+                                                                                  nested tuple source
                                                                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                            }
+                                                                           } [cardinality: 0.0, op-cost: 0.0, total-cost: 9.223372036854776E16]
+                                                                    -- PRE_CLUSTERED_GROUP_BY[$$150, $$151]  |PARTITIONED|
+                                                                      exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        order (ASC, $$150) (ASC, $$151) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                                         -- STABLE_SORT [$$150(ASC), $$151(ASC)]  |PARTITIONED|
+                                                                          exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            project ([$$c, $$ca, $$ss1, $$dd1, $$185, $$150, $$151]) [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                                             -- STREAM_PROJECT  |PARTITIONED|
+                                                                              exchange [cardinality: 9.223372036854776E16, op-cost: 0.0, total-cost: 9.223372036854776E16]
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                join (eq($$161, $$151)) [cardinality: 9.223372036854776E16, op-cost: 9.223372036854776E16, total-cost: 9.223372036854776E16]
                                                                                 -- HYBRID_HASH_JOIN [$$161][$$151]  |PARTITIONED|
+                                                                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    project ([$$c, $$ss1, $$dd1, $$185, $$150, $$161]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        left outer join (eq($$150, $$167)) [cardinality: 9.223372036854776E16, op-cost: 5.00001E11, total-cost: 1.000009E12]
                                                                                         -- HYBRID_HASH_JOIN [$$150][$$167]  |PARTITIONED|
+                                                                                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                           -- HASH_PARTITION_EXCHANGE [$$150]  |PARTITIONED|
+                                                                                            assign [$$161] <- [$$c.getField(4)] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                -- DATASOURCE_SCAN (tpcds.customer)  |PARTITIONED|
+                                                                                                data-scan []<-[$$150, $$c] <- tpcds.customer [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                  exchange
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    empty-tuple-source
                                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                          exchange
                                                                                           -- HASH_PARTITION_EXCHANGE [$$167]  |PARTITIONED|
+                                                                                            assign [$$185] <- [true]
                                                                                             -- ASSIGN  |PARTITIONED|
+                                                                                              project ([$$ss1, $$167, $$dd1])
                                                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                exchange
                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                  join (eq($$172, $$154)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                                                                   -- HYBRID_HASH_JOIN [$$172][$$154]  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- HASH_PARTITION_EXCHANGE [$$172]  |PARTITIONED|
+                                                                                                      assign [$$167, $$172] <- [$$ss1.getField(3), $$ss1.getField(0)]
                                                                                                       -- ASSIGN  |PARTITIONED|
+                                                                                                        project ([$$ss1])
                                                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                          exchange
                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                            -- DATASOURCE_SCAN (tpcds.store_sales)  |PARTITIONED|
+                                                                                                            data-scan []<-[$$152, $$153, $$ss1] <- tpcds.store_sales [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                              exchange
                                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                empty-tuple-source
                                                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                                    exchange
                                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                      replicate
                                                                                                       -- REPLICATE  |PARTITIONED|
+                                                                                                        exchange
                                                                                                         -- HASH_PARTITION_EXCHANGE [$$154]  |PARTITIONED|
+                                                                                                          select (and(lt($$dd1.getField(10), 4), eq($$dd1.getField(6), 1900))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                                                           -- STREAM_SELECT  |PARTITIONED|
+                                                                                                            exchange
                                                                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                              -- DATASOURCE_SCAN (tpcds.date_dim)  |PARTITIONED|
+                                                                                                              data-scan []<-[$$154, $$dd1] <- tpcds.date_dim [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                exchange
                                                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                  empty-tuple-source
                                                                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                  exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                                                    -- DATASOURCE_SCAN (tpcds.customer_address)  |PARTITIONED|
+                                                                                    data-scan []<-[$$151, $$ca] <- tpcds.customer_address [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                      exchange
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        empty-tuple-source
                                                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                          exchange
                                                           -- HASH_PARTITION_EXCHANGE [$$169]  |PARTITIONED|
+                                                            assign [$$188] <- [true]
                                                             -- ASSIGN  |PARTITIONED|
+                                                              project ([$$ws1, $$169, $$dd1])
                                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  join (eq($$174, $$157)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                                   -- HYBRID_HASH_JOIN [$$174][$$157]  |PARTITIONED|
+                                                                    exchange
                                                                     -- HASH_PARTITION_EXCHANGE [$$174]  |PARTITIONED|
+                                                                      assign [$$169, $$174] <- [$$ws1.getField(4), $$ws1.getField(0)]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        project ([$$ws1])
                                                                         -- STREAM_PROJECT  |PARTITIONED|
+                                                                          exchange
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- DATASOURCE_SCAN (tpcds.web_sales)  |PARTITIONED|
+                                                                            data-scan []<-[$$155, $$156, $$ws1] <- tpcds.web_sales [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                              exchange
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                empty-tuple-source
                                                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                    exchange
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      assign [$$157, $$dd1] <- [$$154, $$dd1] project: [$$157, $$dd1]
                                                                       -- ASSIGN  |PARTITIONED|
+                                                                        exchange
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          replicate
                                                                           -- REPLICATE  |PARTITIONED|
+                                                                            exchange
                                                                             -- HASH_PARTITION_EXCHANGE [$$154]  |PARTITIONED|
+                                                                              select (and(lt($$dd1.getField(10), 4), eq($$dd1.getField(6), 1900))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                                               -- STREAM_SELECT  |PARTITIONED|
+                                                                                exchange
                                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- DATASOURCE_SCAN (tpcds.date_dim)  |PARTITIONED|
+                                                                                  data-scan []<-[$$154, $$dd1] <- tpcds.date_dim [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                    exchange
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      empty-tuple-source
                                                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange
                                       -- HASH_PARTITION_EXCHANGE [$$171]  |PARTITIONED|
+                                        assign [$$191] <- [true]
                                         -- ASSIGN  |PARTITIONED|
+                                          project ([$$cs1, $$171, $$dd1])
                                           -- STREAM_PROJECT  |PARTITIONED|
+                                            exchange
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              join (eq($$176, $$160)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                               -- HYBRID_HASH_JOIN [$$176][$$160]  |PARTITIONED|
+                                                exchange
                                                 -- HASH_PARTITION_EXCHANGE [$$176]  |PARTITIONED|
+                                                  assign [$$171, $$176] <- [$$cs1.getField(7), $$cs1.getField(0)]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    project ([$$cs1])
                                                     -- STREAM_PROJECT  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (tpcds.catalog_sales)  |PARTITIONED|
+                                                        data-scan []<-[$$158, $$159, $$cs1] <- tpcds.catalog_sales [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          exchange
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            empty-tuple-source
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                exchange
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  assign [$$160, $$dd1] <- [$$154, $$dd1] project: [$$160, $$dd1]
                                                   -- ASSIGN  |PARTITIONED|
+                                                    exchange
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      replicate
                                                       -- REPLICATE  |PARTITIONED|
+                                                        exchange
                                                         -- HASH_PARTITION_EXCHANGE [$$154]  |PARTITIONED|
+                                                          select (and(lt($$dd1.getField(10), 4), eq($$dd1.getField(6), 1900))) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                           -- STREAM_SELECT  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN (tpcds.date_dim)  |PARTITIONED|
+                                                              data-scan []<-[$$154, $$dd1] <- tpcds.date_dim [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1596.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1596.plan
index 286620f..9ec9038 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1596.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1596.plan
@@ -1,26 +1,52 @@
+distribute result [$$50] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$50] <- [{"cs1": $$cs1, "cr1": $$cr1, "i1": $$i1}] project: [$$50] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
     -- ASSIGN  |PARTITIONED|
+      project ([$$cs1, $$cr1, $$i1]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
         -- SORT_MERGE_EXCHANGE [$$53(ASC), $$54(ASC) ]  |PARTITIONED|
+          order (ASC, $$53) (ASC, $$54) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
           -- STABLE_SORT [$$53(ASC), $$54(ASC)]  |PARTITIONED|
+            exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$cs1, $$cr1, $$i1, $$53, $$54]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
               -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$57, $$53)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 1.1E7]
                   -- HYBRID_HASH_JOIN [$$53][$$57]  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                     -- HASH_PARTITION_EXCHANGE [$$53]  |PARTITIONED|
+                      project ([$$cs1, $$cr1, $$53, $$54]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          left outer join (and(eq($$54, $$56), eq($$53, $$55))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 6000000.0]
                           -- HYBRID_HASH_JOIN [$$54, $$53][$$56, $$55]  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                             -- HASH_PARTITION_EXCHANGE [$$54, $$53]  |PARTITIONED|
-                              -- DATASOURCE_SCAN (tpcds.catalog_sales)  |PARTITIONED|
+                              data-scan []<-[$$53, $$54, $$cs1] <- tpcds.catalog_sales [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange
                             -- HASH_PARTITION_EXCHANGE [$$56, $$55]  |PARTITIONED|
-                              -- DATASOURCE_SCAN (tpcds.catalog_returns)  |PARTITIONED|
+                              data-scan []<-[$$55, $$56, $$cr1] <- tpcds.catalog_returns [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                     -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
-                      -- DATASOURCE_SCAN (tpcds.item)  |PARTITIONED|
+                      data-scan []<-[$$57, $$i1] <- tpcds.item [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                      -- DATASOURCE_SCAN  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1596_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1596_ps.plan
index 4cc1702..4f93a71 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1596_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpcds/query-ASTERIXDB-1596_ps.plan
@@ -1,57 +1,114 @@
+distribute result [$$50] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$50] <- [{"cs1": $$cs1, "cr1": $$cr1, "i1": $$i1}] project: [$$50] [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
     -- ASSIGN  |PARTITIONED|
+      project ([$$cs1, $$cr1, $$i1]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
       -- STREAM_PROJECT  |PARTITIONED|
+        exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          order (ASC, $$53) (ASC, $$54) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
           -- STABLE_SORT [$$53(ASC), $$54(ASC)]  |PARTITIONED|
+            exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
             -- RANGE_PARTITION_EXCHANGE [$$53(ASC), $$54(ASC)]  |PARTITIONED|
+              forward: shared-variable = $$72 [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
               -- FORWARD  |PARTITIONED|
+                exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  replicate [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                   -- REPLICATE  |PARTITIONED|
+                    exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      project ([$$cs1, $$cr1, $$i1, $$53, $$54]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          join (eq($$57, $$53)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 1.1E7]
                           -- HYBRID_HASH_JOIN [$$53][$$57]  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                             -- HASH_PARTITION_EXCHANGE [$$53]  |PARTITIONED|
+                              project ([$$cs1, $$cr1, $$53, $$54]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- STREAM_PROJECT  |PARTITIONED|
+                                exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  left outer join (and(eq($$54, $$56), eq($$53, $$55))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 6000000.0]
                                   -- HYBRID_HASH_JOIN [$$54, $$53][$$56, $$55]  |PARTITIONED|
+                                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                     -- HASH_PARTITION_EXCHANGE [$$54, $$53]  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (tpcds.catalog_sales)  |PARTITIONED|
+                                      data-scan []<-[$$53, $$54, $$cs1] <- tpcds.catalog_sales [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    exchange
                                     -- HASH_PARTITION_EXCHANGE [$$56, $$55]  |PARTITIONED|
-                                      -- DATASOURCE_SCAN (tpcds.catalog_returns)  |PARTITIONED|
+                                      data-scan []<-[$$55, $$56, $$cr1] <- tpcds.catalog_returns [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          empty-tuple-source
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                             -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
-                              -- DATASOURCE_SCAN (tpcds.item)  |PARTITIONED|
+                              data-scan []<-[$$57, $$i1] <- tpcds.item [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                exchange
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  empty-tuple-source
                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                exchange
                 -- BROADCAST_EXCHANGE  |PARTITIONED|
+                  aggregate [$$72] <- [agg-range-map($$69, $$70, $$71)]
                   -- AGGREGATE  |UNPARTITIONED|
+                    exchange
                     -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                      aggregate [$$69, $$70, $$71] <- [agg-local-sampling($$53, $$54), agg-null-writer($$53), agg-null-writer($$54)]
                       -- AGGREGATE  |PARTITIONED|
+                        project ([$$53, $$54])
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            replicate [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                             -- REPLICATE  |PARTITIONED|
+                              exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                project ([$$cs1, $$cr1, $$i1, $$53, $$54]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                                 -- STREAM_PROJECT  |PARTITIONED|
+                                  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    join (eq($$57, $$53)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 1.1E7]
                                     -- HYBRID_HASH_JOIN [$$53][$$57]  |PARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                       -- HASH_PARTITION_EXCHANGE [$$53]  |PARTITIONED|
+                                        project ([$$cs1, $$cr1, $$53, $$54]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                         -- STREAM_PROJECT  |PARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            left outer join (and(eq($$54, $$56), eq($$53, $$55))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 6000000.0]
                                             -- HYBRID_HASH_JOIN [$$54, $$53][$$56, $$55]  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                               -- HASH_PARTITION_EXCHANGE [$$54, $$53]  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpcds.catalog_sales)  |PARTITIONED|
+                                                data-scan []<-[$$53, $$54, $$cs1] <- tpcds.catalog_sales [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              exchange
                                               -- HASH_PARTITION_EXCHANGE [$$56, $$55]  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpcds.catalog_returns)  |PARTITIONED|
+                                                data-scan []<-[$$55, $$56, $$cr1] <- tpcds.catalog_returns [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                       -- HASH_PARTITION_EXCHANGE [$$57]  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (tpcds.item)  |PARTITIONED|
+                                        data-scan []<-[$$57, $$i1] <- tpcds.item [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_broadcast.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_broadcast.plan
deleted file mode 100644
index 4ad65b5..0000000
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_broadcast.plan
+++ /dev/null
@@ -1,43 +0,0 @@
--- DISTRIBUTE_RESULT  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ASSIGN  |PARTITIONED|
-        -- SORT_MERGE_EXCHANGE [$$l_shipmode(ASC) ]  |PARTITIONED|
-          -- SORT_GROUP_BY[$$131]  |PARTITIONED|
-                  {
-                    -- AGGREGATE  |LOCAL|
-                      -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
-            -- HASH_PARTITION_EXCHANGE [$$131]  |PARTITIONED|
-              -- SORT_GROUP_BY[$$114]  |PARTITIONED|
-                      {
-                        -- AGGREGATE  |LOCAL|
-                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                      }
-                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- STREAM_PROJECT  |PARTITIONED|
-                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- HYBRID_HASH_JOIN [$$118][$$121]  |PARTITIONED|
-                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- STREAM_PROJECT  |PARTITIONED|
-                            -- ASSIGN  |PARTITIONED|
-                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
-                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                        -- BROADCAST_EXCHANGE  |PARTITIONED|
-                          -- STREAM_PROJECT  |PARTITIONED|
-                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- HYBRID_HASH_JOIN [$$114][$$120]  |PARTITIONED|
-                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- STREAM_PROJECT  |PARTITIONED|
-                                    -- STREAM_SELECT  |PARTITIONED|
-                                      -- ASSIGN  |PARTITIONED|
-                                        -- STREAM_PROJECT  |PARTITIONED|
-                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                  -- UNNEST  |UNPARTITIONED|
-                                    -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_broadcast_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_broadcast_ps.plan
deleted file mode 100644
index 7bf4afa..0000000
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_broadcast_ps.plan
+++ /dev/null
@@ -1,95 +0,0 @@
--- DISTRIBUTE_RESULT  |PARTITIONED|
-  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- STREAM_PROJECT  |PARTITIONED|
-      -- ASSIGN  |PARTITIONED|
-        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- STABLE_SORT [$$l_shipmode(ASC)]  |PARTITIONED|
-            -- RANGE_PARTITION_EXCHANGE [$$l_shipmode(ASC)]  |PARTITIONED|
-              -- FORWARD  |PARTITIONED|
-                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- REPLICATE  |PARTITIONED|
-                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- SORT_GROUP_BY[$$131]  |PARTITIONED|
-                              {
-                                -- AGGREGATE  |LOCAL|
-                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
-                        -- HASH_PARTITION_EXCHANGE [$$131]  |PARTITIONED|
-                          -- SORT_GROUP_BY[$$114]  |PARTITIONED|
-                                  {
-                                    -- AGGREGATE  |LOCAL|
-                                      -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
-                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
-                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- HYBRID_HASH_JOIN [$$118][$$121]  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        -- ASSIGN  |PARTITIONED|
-                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                    -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- HYBRID_HASH_JOIN [$$114][$$120]  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                -- STREAM_SELECT  |PARTITIONED|
-                                                  -- ASSIGN  |PARTITIONED|
-                                                    -- STREAM_PROJECT  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
-                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                            -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                              -- UNNEST  |UNPARTITIONED|
-                                                -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
-                -- BROADCAST_EXCHANGE  |PARTITIONED|
-                  -- AGGREGATE  |UNPARTITIONED|
-                    -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
-                      -- AGGREGATE  |PARTITIONED|
-                        -- STREAM_PROJECT  |PARTITIONED|
-                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- REPLICATE  |PARTITIONED|
-                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- SORT_GROUP_BY[$$131]  |PARTITIONED|
-                                        {
-                                          -- AGGREGATE  |LOCAL|
-                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                        }
-                                  -- HASH_PARTITION_EXCHANGE [$$131]  |PARTITIONED|
-                                    -- SORT_GROUP_BY[$$114]  |PARTITIONED|
-                                            {
-                                              -- AGGREGATE  |LOCAL|
-                                                -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
-                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- STREAM_PROJECT  |PARTITIONED|
-                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- HYBRID_HASH_JOIN [$$118][$$121]  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- STREAM_PROJECT  |PARTITIONED|
-                                                  -- ASSIGN  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
-                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                              -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                -- STREAM_PROJECT  |PARTITIONED|
-                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- HYBRID_HASH_JOIN [$$114][$$120]  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- STREAM_PROJECT  |PARTITIONED|
-                                                          -- STREAM_SELECT  |PARTITIONED|
-                                                            -- ASSIGN  |PARTITIONED|
-                                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
-                                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                                      -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                        -- UNNEST  |UNPARTITIONED|
-                                                          -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_shipping.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_shipping.plan
index 9308292..a7ad1b3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_shipping.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_shipping.plan
@@ -1,40 +1,74 @@
+distribute result [$$116]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$116] <- [{"l_shipmode": $$l_shipmode, "high_line_count": $$127, "low_line_count": $$128}] project: [$$116]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$l_shipmode(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$135]  |PARTITIONED|
-                {
+        group by ([$$l_shipmode := $$135]) decor ([]) {
+                  aggregate [$$127, $$128] <- [agg-global-sql-sum($$133), agg-global-sql-sum($$134)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$135]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$135]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$118]  |PARTITIONED|
-                    {
+            group by ([$$135 := $$118]) decor ([]) {
+                      aggregate [$$133, $$134] <- [agg-local-sql-sum(switch-case(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH")), numeric-add(1, numeric-multiply($$123, 0)), numeric-add(0, numeric-multiply($$123, 0)))), agg-local-sql-sum(switch-case(true, eq(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH"))), numeric-add(0, numeric-multiply($$123, 0)), numeric-add(1, numeric-multiply($$123, 0))))]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$118]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$123, $$118])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$124, $$118))
                     -- HYBRID_HASH_JOIN [$$118][$$124]  |PARTITIONED|
+                      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$123, $$118]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (eq($$122, $$126)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                             -- HYBRID_HASH_JOIN [$$126][$$122]  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                               -- HASH_PARTITION_EXCHANGE [$$126]  |PARTITIONED|
+                                select (and(lt($$120, $$119), ge($$119, "1994-01-01"), lt($$119, "1995-01-01"), lt($$l.getField("l_shipdate"), $$120))) project: [$$118, $$126] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$120, $$119, $$118, $$126] <- [$$l.getField("l_commitdate"), $$l.getField("l_receiptdate"), $$l.getField("l_shipmode"), $$l.getField("l_orderkey")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$l]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                        data-scan []<-[$$121, $$l] <- tpch.LineItem [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                               -- HASH_PARTITION_EXCHANGE [$$122]  |PARTITIONED|
+                                assign [$$123] <- [$$o.getField("o_orderpriority")] project: [$$123, $$122] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                    data-scan []<-[$$122, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        unnest $$124 <- scan-collection(array: [ "MAIL", "SHIP" ])
                         -- UNNEST  |UNPARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_shipping_broadcast.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_shipping_broadcast.plan
index 3a0c212..bac02d4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_shipping_broadcast.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_shipping_broadcast.plan
@@ -1,40 +1,74 @@
+distribute result [$$116]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$116] <- [{"l_shipmode": $$l_shipmode, "high_line_count": $$127, "low_line_count": $$128}] project: [$$116]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- SORT_MERGE_EXCHANGE [$$l_shipmode(ASC) ]  |PARTITIONED|
-        -- SORT_GROUP_BY[$$135]  |PARTITIONED|
-                {
+        group by ([$$l_shipmode := $$135]) decor ([]) {
+                  aggregate [$$127, $$128] <- [agg-global-sql-sum($$133), agg-global-sql-sum($$134)]
                   -- AGGREGATE  |LOCAL|
+                    nested tuple source
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                }
+               }
+        -- SORT_GROUP_BY[$$135]  |PARTITIONED|
+          exchange
           -- HASH_PARTITION_EXCHANGE [$$135]  |PARTITIONED|
-            -- SORT_GROUP_BY[$$118]  |PARTITIONED|
-                    {
+            group by ([$$135 := $$118]) decor ([]) {
+                      aggregate [$$133, $$134] <- [agg-local-sql-sum(switch-case(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH")), numeric-add(1, numeric-multiply($$123, 0)), numeric-add(0, numeric-multiply($$123, 0)))), agg-local-sql-sum(switch-case(true, eq(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH"))), numeric-add(0, numeric-multiply($$123, 0)), numeric-add(1, numeric-multiply($$123, 0))))]
                       -- AGGREGATE  |LOCAL|
+                        nested tuple source
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
+                   }
+            -- SORT_GROUP_BY[$$118]  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$123, $$118])
                 -- STREAM_PROJECT  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    join (eq($$124, $$118))
                     -- HYBRID_HASH_JOIN [$$118][$$124]  |PARTITIONED|
+                      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        project ([$$123, $$118]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                         -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            join (eq($$125, $$122)) [cardinality: 5.0E11, op-cost: 5000000.0, total-cost: 1.1E7]
                             -- HYBRID_HASH_JOIN [$$125][$$122]  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                select (and(lt($$120, $$119), ge($$119, "1994-01-01"), lt($$119, "1995-01-01"), lt($$l.getField("l_shipdate"), $$120))) project: [$$118, $$125] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- STREAM_SELECT  |PARTITIONED|
+                                  assign [$$120, $$119, $$118, $$125] <- [$$l.getField("l_commitdate"), $$l.getField("l_receiptdate"), $$l.getField("l_shipmode"), $$l.getField("l_orderkey")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                   -- ASSIGN  |PARTITIONED|
+                                    project ([$$l]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                        data-scan []<-[$$121, $$l] <- tpch.LineItem [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          exchange
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            empty-tuple-source
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                assign [$$123] <- [$$o.getField("o_orderpriority")] project: [$$123, $$122] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                 -- ASSIGN  |PARTITIONED|
+                                  exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                    data-scan []<-[$$122, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      exchange
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        empty-tuple-source
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      exchange
                       -- BROADCAST_EXCHANGE  |PARTITIONED|
+                        unnest $$124 <- scan-collection(array: [ "MAIL", "SHIP" ])
                         -- UNNEST  |UNPARTITIONED|
+                          empty-tuple-source
                           -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_shipping_broadcast_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_shipping_broadcast_ps.plan
index cacd6c1..4f8c482 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_shipping_broadcast_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_shipping_broadcast_ps.plan
@@ -1,90 +1,168 @@
+distribute result [$$116]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$116] <- [{"l_shipmode": $$l_shipmode, "high_line_count": $$127, "low_line_count": $$128}] project: [$$116]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$l_shipmode)
         -- STABLE_SORT [$$l_shipmode(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$l_shipmode(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$138
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$135]  |PARTITIONED|
-                            {
+                    group by ([$$l_shipmode := $$135]) decor ([]) {
+                              aggregate [$$127, $$128] <- [agg-global-sql-sum($$133), agg-global-sql-sum($$134)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$135]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$135]  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$118]  |PARTITIONED|
-                                {
+                        group by ([$$135 := $$118]) decor ([]) {
+                                  aggregate [$$133, $$134] <- [agg-local-sql-sum(switch-case(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH")), numeric-add(1, numeric-multiply($$123, 0)), numeric-add(0, numeric-multiply($$123, 0)))), agg-local-sql-sum(switch-case(true, eq(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH"))), numeric-add(0, numeric-multiply($$123, 0)), numeric-add(1, numeric-multiply($$123, 0))))]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$118]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$123, $$118])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$124, $$118))
                                 -- HYBRID_HASH_JOIN [$$118][$$124]  |PARTITIONED|
+                                  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$123, $$118]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        join (eq($$125, $$122)) [cardinality: 5.0E11, op-cost: 5000000.0, total-cost: 1.1E7]
                                         -- HYBRID_HASH_JOIN [$$125][$$122]  |PARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            select (and(lt($$120, $$119), ge($$119, "1994-01-01"), lt($$119, "1995-01-01"), lt($$l.getField("l_shipdate"), $$120))) project: [$$118, $$125] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- STREAM_SELECT  |PARTITIONED|
+                                              assign [$$120, $$119, $$118, $$125] <- [$$l.getField("l_commitdate"), $$l.getField("l_receiptdate"), $$l.getField("l_shipmode"), $$l.getField("l_orderkey")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$l]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                                    data-scan []<-[$$121, $$l] <- tpch.LineItem [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            assign [$$123] <- [$$o.getField("o_orderpriority")] project: [$$123, $$122] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                                data-scan []<-[$$122, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    unnest $$124 <- scan-collection(array: [ "MAIL", "SHIP" ])
                                     -- UNNEST  |UNPARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$138] <- [agg-range-map($$136, $$137)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$136, $$137] <- [agg-local-sampling($$l_shipmode), agg-null-writer($$l_shipmode)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$l_shipmode])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- SORT_GROUP_BY[$$135]  |PARTITIONED|
-                                      {
+                              group by ([$$l_shipmode := $$135]) decor ([]) {
+                                        aggregate [$$127, $$128] <- [agg-global-sql-sum($$133), agg-global-sql-sum($$134)]
                                         -- AGGREGATE  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- SORT_GROUP_BY[$$135]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$135]  |PARTITIONED|
-                                  -- SORT_GROUP_BY[$$118]  |PARTITIONED|
-                                          {
+                                  group by ([$$135 := $$118]) decor ([]) {
+                                            aggregate [$$133, $$134] <- [agg-local-sql-sum(switch-case(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH")), numeric-add(1, numeric-multiply($$123, 0)), numeric-add(0, numeric-multiply($$123, 0)))), agg-local-sql-sum(switch-case(true, eq(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH"))), numeric-add(0, numeric-multiply($$123, 0)), numeric-add(1, numeric-multiply($$123, 0))))]
                                             -- AGGREGATE  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                          }
+                                         }
+                                  -- SORT_GROUP_BY[$$118]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$123, $$118])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          join (eq($$124, $$118))
                                           -- HYBRID_HASH_JOIN [$$118][$$124]  |PARTITIONED|
+                                            exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$123, $$118]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 1.1E7]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  join (eq($$125, $$122)) [cardinality: 5.0E11, op-cost: 5000000.0, total-cost: 1.1E7]
                                                   -- HYBRID_HASH_JOIN [$$125][$$122]  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      select (and(lt($$120, $$119), ge($$119, "1994-01-01"), lt($$119, "1995-01-01"), lt($$l.getField("l_shipdate"), $$120))) project: [$$118, $$125] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        assign [$$120, $$119, $$118, $$125] <- [$$l.getField("l_commitdate"), $$l.getField("l_receiptdate"), $$l.getField("l_shipmode"), $$l.getField("l_orderkey")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          project ([$$l]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                                              data-scan []<-[$$121, $$l] <- tpch.LineItem [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                     -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                      assign [$$123] <- [$$o.getField("o_orderpriority")] project: [$$123, $$122] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange [cardinality: 1000000.0, op-cost: 4000000.0, total-cost: 5000000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                                          data-scan []<-[$$122, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              unnest $$124 <- scan-collection(array: [ "MAIL", "SHIP" ])
                                               -- UNNEST  |UNPARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_shipping_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_shipping_ps.plan
index 1ca832e..7826b98 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_shipping_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results_cbo/tpch/q12_shipping_ps.plan
@@ -1,90 +1,168 @@
+distribute result [$$116]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$116] <- [{"l_shipmode": $$l_shipmode, "high_line_count": $$127, "low_line_count": $$128}] project: [$$116]
     -- ASSIGN  |PARTITIONED|
+      exchange
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+        order (ASC, $$l_shipmode)
         -- STABLE_SORT [$$l_shipmode(ASC)]  |PARTITIONED|
+          exchange
           -- RANGE_PARTITION_EXCHANGE [$$l_shipmode(ASC)]  |PARTITIONED|
+            forward: shared-variable = $$138
             -- FORWARD  |PARTITIONED|
+              exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                replicate
                 -- REPLICATE  |PARTITIONED|
+                  exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- SORT_GROUP_BY[$$135]  |PARTITIONED|
-                            {
+                    group by ([$$l_shipmode := $$135]) decor ([]) {
+                              aggregate [$$127, $$128] <- [agg-global-sql-sum($$133), agg-global-sql-sum($$134)]
                               -- AGGREGATE  |LOCAL|
+                                nested tuple source
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                           }
+                    -- SORT_GROUP_BY[$$135]  |PARTITIONED|
+                      exchange
                       -- HASH_PARTITION_EXCHANGE [$$135]  |PARTITIONED|
-                        -- SORT_GROUP_BY[$$118]  |PARTITIONED|
-                                {
+                        group by ([$$135 := $$118]) decor ([]) {
+                                  aggregate [$$133, $$134] <- [agg-local-sql-sum(switch-case(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH")), numeric-add(1, numeric-multiply($$123, 0)), numeric-add(0, numeric-multiply($$123, 0)))), agg-local-sql-sum(switch-case(true, eq(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH"))), numeric-add(0, numeric-multiply($$123, 0)), numeric-add(1, numeric-multiply($$123, 0))))]
                                   -- AGGREGATE  |LOCAL|
+                                    nested tuple source
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                }
+                               }
+                        -- SORT_GROUP_BY[$$118]  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            project ([$$123, $$118])
                             -- STREAM_PROJECT  |PARTITIONED|
+                              exchange
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                join (eq($$124, $$118))
                                 -- HYBRID_HASH_JOIN [$$118][$$124]  |PARTITIONED|
+                                  exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    project ([$$123, $$118]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                     -- STREAM_PROJECT  |PARTITIONED|
+                                      exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        join (eq($$122, $$126)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                         -- HYBRID_HASH_JOIN [$$126][$$122]  |PARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                           -- HASH_PARTITION_EXCHANGE [$$126]  |PARTITIONED|
+                                            select (and(lt($$120, $$119), ge($$119, "1994-01-01"), lt($$119, "1995-01-01"), lt($$l.getField("l_shipdate"), $$120))) project: [$$118, $$126] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- STREAM_SELECT  |PARTITIONED|
+                                              assign [$$120, $$119, $$118, $$126] <- [$$l.getField("l_commitdate"), $$l.getField("l_receiptdate"), $$l.getField("l_shipmode"), $$l.getField("l_orderkey")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                               -- ASSIGN  |PARTITIONED|
+                                                project ([$$l]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                 -- STREAM_PROJECT  |PARTITIONED|
+                                                  exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                                    data-scan []<-[$$121, $$l] <- tpch.LineItem [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      exchange
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        empty-tuple-source
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                           -- HASH_PARTITION_EXCHANGE [$$122]  |PARTITIONED|
+                                            assign [$$123] <- [$$o.getField("o_orderpriority")] project: [$$123, $$122] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                             -- ASSIGN  |PARTITIONED|
+                                              exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                                data-scan []<-[$$122, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  exchange
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    empty-tuple-source
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  exchange
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                    unnest $$124 <- scan-collection(array: [ "MAIL", "SHIP" ])
                                     -- UNNEST  |UNPARTITIONED|
+                                      empty-tuple-source
                                       -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+              exchange
               -- BROADCAST_EXCHANGE  |PARTITIONED|
+                aggregate [$$138] <- [agg-range-map($$136, $$137)]
                 -- AGGREGATE  |UNPARTITIONED|
+                  exchange
                   -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+                    aggregate [$$136, $$137] <- [agg-local-sampling($$l_shipmode), agg-null-writer($$l_shipmode)]
                     -- AGGREGATE  |PARTITIONED|
+                      project ([$$l_shipmode])
                       -- STREAM_PROJECT  |PARTITIONED|
+                        exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          replicate
                           -- REPLICATE  |PARTITIONED|
+                            exchange
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- SORT_GROUP_BY[$$135]  |PARTITIONED|
-                                      {
+                              group by ([$$l_shipmode := $$135]) decor ([]) {
+                                        aggregate [$$127, $$128] <- [agg-global-sql-sum($$133), agg-global-sql-sum($$134)]
                                         -- AGGREGATE  |LOCAL|
+                                          nested tuple source
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                      }
+                                     }
+                              -- SORT_GROUP_BY[$$135]  |PARTITIONED|
+                                exchange
                                 -- HASH_PARTITION_EXCHANGE [$$135]  |PARTITIONED|
-                                  -- SORT_GROUP_BY[$$118]  |PARTITIONED|
-                                          {
+                                  group by ([$$135 := $$118]) decor ([]) {
+                                            aggregate [$$133, $$134] <- [agg-local-sql-sum(switch-case(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH")), numeric-add(1, numeric-multiply($$123, 0)), numeric-add(0, numeric-multiply($$123, 0)))), agg-local-sql-sum(switch-case(true, eq(true, or(eq($$123, "1-URGENT"), eq($$123, "2-HIGH"))), numeric-add(0, numeric-multiply($$123, 0)), numeric-add(1, numeric-multiply($$123, 0))))]
                                             -- AGGREGATE  |LOCAL|
+                                              nested tuple source
                                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                          }
+                                         }
+                                  -- SORT_GROUP_BY[$$118]  |PARTITIONED|
+                                    exchange
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      project ([$$123, $$118])
                                       -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          join (eq($$124, $$118))
                                           -- HYBRID_HASH_JOIN [$$118][$$124]  |PARTITIONED|
+                                            exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              project ([$$123, $$118]) [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                               -- STREAM_PROJECT  |PARTITIONED|
+                                                exchange [cardinality: 5.0E11, op-cost: 0.0, total-cost: 6000000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  join (eq($$122, $$126)) [cardinality: 5.0E11, op-cost: 2000000.0, total-cost: 6000000.0]
                                                   -- HYBRID_HASH_JOIN [$$126][$$122]  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                     -- HASH_PARTITION_EXCHANGE [$$126]  |PARTITIONED|
+                                                      select (and(lt($$120, $$119), ge($$119, "1994-01-01"), lt($$119, "1995-01-01"), lt($$l.getField("l_shipdate"), $$120))) project: [$$118, $$126] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- STREAM_SELECT  |PARTITIONED|
+                                                        assign [$$120, $$119, $$118, $$126] <- [$$l.getField("l_commitdate"), $$l.getField("l_receiptdate"), $$l.getField("l_shipmode"), $$l.getField("l_orderkey")] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                         -- ASSIGN  |PARTITIONED|
+                                                          project ([$$l]) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                           -- STREAM_PROJECT  |PARTITIONED|
+                                                            exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN (tpch.LineItem)  |PARTITIONED|
+                                                              data-scan []<-[$$121, $$l] <- tpch.LineItem [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                exchange
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  empty-tuple-source
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                     -- HASH_PARTITION_EXCHANGE [$$122]  |PARTITIONED|
+                                                      assign [$$123] <- [$$o.getField("o_orderpriority")] project: [$$123, $$122] [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
                                                       -- ASSIGN  |PARTITIONED|
+                                                        exchange [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 2000000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN (tpch.Orders)  |PARTITIONED|
+                                                          data-scan []<-[$$122, $$o] <- tpch.Orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            exchange
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              empty-tuple-source
                                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            exchange
                                             -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              unnest $$124 <- scan-collection(array: [ "MAIL", "SHIP" ])
                                               -- UNNEST  |UNPARTITIONED|
+                                                empty-tuple-source
                                                 -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|