[NO ISSUE][OTHER] Fix hash join tests

Ext-ref: MB-66611
Change-Id: I8e12388a14e00ef47498baf408eadcf7e6128d41
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19834
Reviewed-by: Michael Blow <mblow@apache.org>
Tested-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.5.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.5.query.plan
index d1c3b5a..c9c3348 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.5.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.5.query.plan
@@ -1,42 +1,40 @@
-distribute result [$$43] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+distribute result [$$43]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$43]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-    -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$43] <- [object-concat-strict({"c_id": $$46}, if-missing-or-null(cast(to-object($$o)), cast({  })))] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-      -- ASSIGN  |PARTITIONED|
-        project ([$$46, $$o]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-        -- STREAM_PROJECT  |PARTITIONED|
-          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            left outer join (and(eq($$46, $$51), eq($$44, $$47), eq($$45, $$48))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-            -- HYBRID_HASH_JOIN [$$46, $$44, $$45][$$51, $$47, $$48]  |PARTITIONED|
-              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                project ([$$46, $$44, $$45]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                -- STREAM_PROJECT  |PARTITIONED|
-                  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    data-scan []<-[$$44, $$45, $$46, $$c] <- test.customer [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                    -- DATASOURCE_SCAN  |PARTITIONED|
-                      exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-              -- HASH_PARTITION_EXCHANGE [$$47, $$48, $$51]  |PARTITIONED|
-                select (gt($$o.getField("o_carrier_id"), 8)) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                -- STREAM_SELECT  |PARTITIONED|
-                  assign [$$51] <- [$$o.getField("o_c_id")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                  -- ASSIGN  |PARTITIONED|
-                    project ([$$47, $$48, $$o]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                    -- STREAM_PROJECT  |PARTITIONED|
-                      exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        data-scan []<-[$$47, $$48, $$49, $$o] <- test.orders [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                        -- DATASOURCE_SCAN  |PARTITIONED|
-                          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+    assign [$$43] <- [object-concat-strict({"c_id": $$46}, to-object-var-str($$o))] project: [$$43]
+    -- ASSIGN  |PARTITIONED|
+      project ([$$46, $$o])
+      -- STREAM_PROJECT  |PARTITIONED|
+        exchange
+        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          left outer join (and(eq($$46, $$51), eq($$44, $$47), eq($$45, $$48)))
+          -- HYBRID_HASH_JOIN [$$46, $$44, $$45][$$51, $$47, $$48]  |PARTITIONED|
+            exchange
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$46, $$44, $$45])
+              -- STREAM_PROJECT  |PARTITIONED|
+                exchange
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  data-scan []<-[$$44, $$45, $$46, $$c] <- test.customer
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
+                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
+            -- HASH_PARTITION_EXCHANGE [$$47, $$48, $$51]  |PARTITIONED|
+              select (gt($$o.getField("o_carrier_id"), 8))
+              -- STREAM_SELECT  |PARTITIONED|
+                assign [$$51] <- [$$o.getField("o_c_id")]
+                -- ASSIGN  |PARTITIONED|
+                  project ([$$47, $$48, $$o])
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      data-scan []<-[$$47, $$48, $$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/joins/hash_join_exchange/hash_join_exchange.7.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.7.query.plan
index cc77d9f..02a3b43 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.7.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.7.query.plan
@@ -1,42 +1,40 @@
-distribute result [$$43] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+distribute result [$$43]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$43]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-    -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$43] <- [object-concat-strict({"c_id": $$46}, if-missing-or-null(cast(to-object($$o)), cast({  })))] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-      -- ASSIGN  |PARTITIONED|
-        project ([$$46, $$o]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-        -- STREAM_PROJECT  |PARTITIONED|
-          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            left outer join (and(eq($$46, $$51), eq($$44, $$47), eq($$45, $$48))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-            -- HYBRID_HASH_JOIN [$$46, $$44, $$45][$$51, $$47, $$48]  |PARTITIONED|
-              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                project ([$$46, $$44, $$45]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                -- STREAM_PROJECT  |PARTITIONED|
-                  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    data-scan []<-[$$44, $$45, $$46, $$c] <- test.customer [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                    -- DATASOURCE_SCAN  |PARTITIONED|
-                      exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-              -- BROADCAST_EXCHANGE  |PARTITIONED|
-                select (gt($$o.getField("o_carrier_id"), 8)) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                -- STREAM_SELECT  |PARTITIONED|
-                  assign [$$51] <- [$$o.getField("o_c_id")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                  -- ASSIGN  |PARTITIONED|
-                    project ([$$47, $$48, $$o]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                    -- STREAM_PROJECT  |PARTITIONED|
-                      exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        data-scan []<-[$$47, $$48, $$49, $$o] <- test.orders [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                        -- DATASOURCE_SCAN  |PARTITIONED|
-                          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+    assign [$$43] <- [object-concat-strict({"c_id": $$46}, to-object-var-str($$o))] project: [$$43]
+    -- ASSIGN  |PARTITIONED|
+      project ([$$46, $$o])
+      -- STREAM_PROJECT  |PARTITIONED|
+        exchange
+        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          left outer join (and(eq($$46, $$51), eq($$44, $$47), eq($$45, $$48)))
+          -- HYBRID_HASH_JOIN [$$46, $$44, $$45][$$51, $$47, $$48]  |PARTITIONED|
+            exchange
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$46, $$44, $$45])
+              -- STREAM_PROJECT  |PARTITIONED|
+                exchange
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  data-scan []<-[$$44, $$45, $$46, $$c] <- test.customer
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source
+                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
+            -- BROADCAST_EXCHANGE  |PARTITIONED|
+              select (gt($$o.getField("o_carrier_id"), 8))
+              -- STREAM_SELECT  |PARTITIONED|
+                assign [$$51] <- [$$o.getField("o_c_id")]
+                -- ASSIGN  |PARTITIONED|
+                  project ([$$47, $$48, $$o])
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    exchange
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      data-scan []<-[$$47, $$48, $$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/joins/hash_join_exchange/hash_join_exchange.9.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.9.query.plan
index 148740d..4a69a97 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.9.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange/hash_join_exchange.9.query.plan
@@ -1,60 +1,54 @@
-distribute result [$$48] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+distribute result [$$48]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$48]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-    -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$48] <- [object-concat-strict({"o_d_id": $$50, "o_w_id": $$49, "o_id": $$51, "c_id": $$65, "o_carrier_id": $$61, "o_ol_cnt": $$67}, if-missing-or-null(cast(to-object($$c)), cast({  })))] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-      -- ASSIGN  |PARTITIONED|
-        project ([$$50, $$49, $$51, $$65, $$61, $$67, $$c]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-        -- STREAM_PROJECT  |PARTITIONED|
-          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            left outer join (and(eq($$49, $$73), eq($$50, $$74), eq($$51, $$75))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-            -- HYBRID_HASH_JOIN [$$49, $$50, $$51][$$73, $$74, $$75]  |PARTITIONED|
-              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                project ([$$50, $$49, $$51, $$65, $$61, $$67]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                -- STREAM_PROJECT  |PARTITIONED|
-                  assign [$$67, $$61, $$65] <- [$$o.getField("o_ol_cnt"), $$o.getField("o_carrier_id"), $$o.getField("c_id")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                  -- ASSIGN  |PARTITIONED|
-                    exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+    assign [$$48] <- [object-concat-strict({"o_d_id": $$50, "o_w_id": $$49, "o_id": $$51, "c_id": $$65, "o_carrier_id": $$61, "o_ol_cnt": $$67}, to-object-var-str($$c))] project: [$$48]
+    -- ASSIGN  |PARTITIONED|
+      project ([$$50, $$49, $$51, $$65, $$61, $$67, $$c])
+      -- STREAM_PROJECT  |PARTITIONED|
+        exchange
+        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          left outer join (and(eq($$49, $$73), eq($$50, $$74), eq($$51, $$75)))
+          -- HYBRID_HASH_JOIN [$$49, $$50, $$51][$$73, $$74, $$75]  |PARTITIONED|
+            exchange
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              assign [$$67, $$61, $$65] <- [$$o.getField("o_ol_cnt"), $$o.getField("o_carrier_id"), $$o.getField("c_id")] project: [$$50, $$49, $$51, $$65, $$61, $$67]
+              -- ASSIGN  |PARTITIONED|
+                exchange
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  data-scan []<-[$$49, $$50, $$51, $$o] <- test.orders
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      data-scan []<-[$$49, $$50, $$51, $$o] <- test.orders [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                      -- DATASOURCE_SCAN  |PARTITIONED|
-                        exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-              -- HASH_PARTITION_EXCHANGE [$$73, $$74, $$75]  |PARTITIONED|
-                project ([$$c, $$73, $$74, $$75]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                -- STREAM_PROJECT  |PARTITIONED|
-                  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    join (and(eq($$54, $$68), eq($$52, $$73), eq($$53, $$74))) [cardinality: 1000000.0, op-cost: 2000000.0, total-cost: 6000000.0]
-                    -- HYBRID_HASH_JOIN [$$68, $$73, $$74][$$54, $$52, $$53]  |PARTITIONED|
-                      exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                      -- HASH_PARTITION_EXCHANGE [$$73, $$74, $$68]  |PARTITIONED|
-                        project ([$$73, $$74, $$75, $$68]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                        -- STREAM_PROJECT  |PARTITIONED|
-                          select (gt($$69.getField("o_carrier_id"), 8)) [cardinality: 1000000.0, op-cost: 0.0, total-cost: 1000000.0]
-                          -- STREAM_SELECT  |PARTITIONED|
-                            assign [$$68] <- [$$69.getField("o_c_id")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                            -- ASSIGN  |PARTITIONED|
-                              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                data-scan []<-[$$73, $$74, $$75, $$69] <- test.orders [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
-                                -- DATASOURCE_SCAN  |PARTITIONED|
-                                  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                      exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        data-scan []<-[$$52, $$53, $$54, $$c] <- test.customer [cardinality: 1000000.0, op-cost: 1000000.0, total-cost: 1000000.0]
-                        -- DATASOURCE_SCAN  |PARTITIONED|
-                          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                      empty-tuple-source
+                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
+            -- HASH_PARTITION_EXCHANGE [$$73, $$74, $$75]  |PARTITIONED|
+              project ([$$c, $$73, $$74, $$75])
+              -- STREAM_PROJECT  |PARTITIONED|
+                exchange
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (and(eq($$54, $$68), eq($$52, $$73), eq($$53, $$74)))
+                  -- HYBRID_HASH_JOIN [$$68, $$73, $$74][$$54, $$52, $$53]  |PARTITIONED|
+                    exchange
+                    -- HASH_PARTITION_EXCHANGE [$$73, $$74, $$68]  |PARTITIONED|
+                      select (gt($$69.getField("o_carrier_id"), 8)) project: [$$73, $$74, $$75, $$68]
+                      -- STREAM_SELECT  |PARTITIONED|
+                        assign [$$68] <- [$$69.getField("o_c_id")]
+                        -- ASSIGN  |PARTITIONED|
+                          exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            data-scan []<-[$$73, $$74, $$75, $$69] <- test.orders
+                            -- DATASOURCE_SCAN  |PARTITIONED|
+                              exchange
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                empty-tuple-source
+                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                    exchange
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      data-scan []<-[$$52, $$53, $$54, $$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/joins/hash_join_exchange_1/hash_join_exchange_1.11.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.11.query.plan
index 094f7cf..20fa187 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.11.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.11.query.plan
@@ -1,44 +1,38 @@
-distribute result [$$44] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+distribute result [$$46]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$44]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-    -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$44] <- [{"a_0": $$47, "a_1": $$48, "a_2": $$49, "a_3": $$60, "b_3": $$61}] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-      -- ASSIGN  |PARTITIONED|
-        project ([$$47, $$48, $$49, $$60, $$61]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-        -- STREAM_PROJECT  |PARTITIONED|
-          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            left outer join (and(eq($$49, $$52), eq($$47, $$50), eq($$51, $$48))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-            -- HYBRID_HASH_JOIN [$$49, $$47, $$48][$$52, $$50, $$51]  |PARTITIONED|
-              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                select (eq($$47, $$49)) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                -- STREAM_SELECT  |PARTITIONED|
-                  project ([$$47, $$48, $$49, $$60]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                  -- STREAM_PROJECT  |PARTITIONED|
-                    assign [$$60] <- [$$A.getField("a_3")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                    -- ASSIGN  |PARTITIONED|
-                      exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+    assign [$$46] <- [{"a_0": $$49, "a_1": $$50, "a_2": $$51, "a_3": $$62, "b_3": $$63}] project: [$$46]
+    -- ASSIGN  |PARTITIONED|
+      project ([$$49, $$50, $$51, $$62, $$63])
+      -- STREAM_PROJECT  |PARTITIONED|
+        exchange
+        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          left outer join (and(eq($$51, $$54), eq($$49, $$52), eq($$53, $$50)))
+          -- HYBRID_HASH_JOIN [$$51, $$49, $$50][$$54, $$52, $$53]  |PARTITIONED|
+            exchange
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              select (eq($$49, $$51))
+              -- STREAM_SELECT  |PARTITIONED|
+                assign [$$62] <- [$$A.getField("a_3")] project: [$$49, $$50, $$51, $$62]
+                -- ASSIGN  |PARTITIONED|
+                  exchange
+                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    data-scan []<-[$$49, $$50, $$51, $$A] <- test.A
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        data-scan []<-[$$47, $$48, $$49, $$A] <- test.A [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                        -- DATASOURCE_SCAN  |PARTITIONED|
-                          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                project ([$$61, $$52, $$50, $$51]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                -- STREAM_PROJECT  |PARTITIONED|
-                  assign [$$61] <- [$$B.getField("b_3")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                  -- ASSIGN  |PARTITIONED|
-                    exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                        empty-tuple-source
+                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              assign [$$63] <- [$$B.getField("b_3")] project: [$$63, $$54, $$52, $$53]
+              -- ASSIGN  |PARTITIONED|
+                exchange
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  data-scan []<-[$$52, $$53, $$54, $$B] <- test.B
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      data-scan []<-[$$50, $$51, $$52, $$B] <- test.B [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                      -- DATASOURCE_SCAN  |PARTITIONED|
-                        exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      empty-tuple-source
+                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.13.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.13.query.plan
index 09f76b6..f4d6562 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.13.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.13.query.plan
@@ -1,42 +1,36 @@
-distribute result [$$44] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+distribute result [$$46]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$44]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-    -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$44] <- [{"a_0": $$45, "a_1": $$46, "a_2": $$47, "a_3": $$53, "b_3": $$54}] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-      -- ASSIGN  |PARTITIONED|
-        project ([$$45, $$46, $$47, $$53, $$54]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-        -- STREAM_PROJECT  |PARTITIONED|
-          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            left outer join (and(eq($$47, $$50), eq($$53, $$54), eq($$45, $$48), eq($$49, $$46))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-            -- HYBRID_HASH_JOIN [$$47, $$53, $$45, $$46][$$50, $$54, $$48, $$49]  |PARTITIONED|
-              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                project ([$$45, $$46, $$47, $$53]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                -- STREAM_PROJECT  |PARTITIONED|
-                  assign [$$53] <- [$$A.getField("a_3")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                  -- ASSIGN  |PARTITIONED|
-                    exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+    assign [$$46] <- [{"a_0": $$47, "a_1": $$48, "a_2": $$49, "a_3": $$55, "b_3": $$56}] project: [$$46]
+    -- ASSIGN  |PARTITIONED|
+      project ([$$47, $$48, $$49, $$55, $$56])
+      -- STREAM_PROJECT  |PARTITIONED|
+        exchange
+        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          left outer join (and(eq($$49, $$52), eq($$55, $$56), eq($$47, $$50), eq($$51, $$48)))
+          -- HYBRID_HASH_JOIN [$$49, $$55, $$47, $$48][$$52, $$56, $$50, $$51]  |PARTITIONED|
+            exchange
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              assign [$$55] <- [$$A.getField("a_3")] project: [$$47, $$48, $$49, $$55]
+              -- ASSIGN  |PARTITIONED|
+                exchange
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  data-scan []<-[$$47, $$48, $$49, $$A] <- test.A
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      data-scan []<-[$$45, $$46, $$47, $$A] <- test.A [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                      -- DATASOURCE_SCAN  |PARTITIONED|
-                        exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                project ([$$54, $$50, $$48, $$49]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                -- STREAM_PROJECT  |PARTITIONED|
-                  assign [$$54] <- [$$B.getField("b_3")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                  -- ASSIGN  |PARTITIONED|
-                    exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                      empty-tuple-source
+                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              assign [$$56] <- [$$B.getField("b_3")] project: [$$56, $$52, $$50, $$51]
+              -- ASSIGN  |PARTITIONED|
+                exchange
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  data-scan []<-[$$50, $$51, $$52, $$B] <- test.B
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      data-scan []<-[$$48, $$49, $$50, $$B] <- test.B [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                      -- DATASOURCE_SCAN  |PARTITIONED|
-                        exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      empty-tuple-source
+                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.5.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.5.query.plan
index b51190e..3bf9f1a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.5.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.5.query.plan
@@ -1,42 +1,36 @@
-distribute result [$$41] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+distribute result [$$43]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$41]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-    -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$41] <- [{"a_0": $$42, "a_1": $$43, "a_2": $$44, "a_3": $$57, "b_3": $$58}] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-      -- ASSIGN  |PARTITIONED|
-        project ([$$42, $$43, $$44, $$57, $$58]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-        -- STREAM_PROJECT  |PARTITIONED|
-          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            left outer join (and(eq($$44, $$47), eq($$42, $$45), eq($$46, $$43))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-            -- HYBRID_HASH_JOIN [$$44, $$42, $$43][$$47, $$45, $$46]  |PARTITIONED|
-              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                project ([$$42, $$43, $$44, $$57]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                -- STREAM_PROJECT  |PARTITIONED|
-                  assign [$$57] <- [$$A.getField("a_3")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                  -- ASSIGN  |PARTITIONED|
-                    exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+    assign [$$43] <- [{"a_0": $$44, "a_1": $$45, "a_2": $$46, "a_3": $$59, "b_3": $$60}] project: [$$43]
+    -- ASSIGN  |PARTITIONED|
+      project ([$$44, $$45, $$46, $$59, $$60])
+      -- STREAM_PROJECT  |PARTITIONED|
+        exchange
+        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          left outer join (and(eq($$46, $$49), eq($$44, $$47), eq($$48, $$45)))
+          -- HYBRID_HASH_JOIN [$$46, $$44, $$45][$$49, $$47, $$48]  |PARTITIONED|
+            exchange
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              assign [$$59] <- [$$A.getField("a_3")] project: [$$44, $$45, $$46, $$59]
+              -- ASSIGN  |PARTITIONED|
+                exchange
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  data-scan []<-[$$44, $$45, $$46, $$A] <- test.A
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      data-scan []<-[$$42, $$43, $$44, $$A] <- test.A [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                      -- DATASOURCE_SCAN  |PARTITIONED|
-                        exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                project ([$$58, $$47, $$45, $$46]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                -- STREAM_PROJECT  |PARTITIONED|
-                  assign [$$58] <- [$$B.getField("b_3")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                  -- ASSIGN  |PARTITIONED|
-                    exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                      empty-tuple-source
+                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              assign [$$60] <- [$$B.getField("b_3")] project: [$$60, $$49, $$47, $$48]
+              -- ASSIGN  |PARTITIONED|
+                exchange
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  data-scan []<-[$$47, $$48, $$49, $$B] <- test.B
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      data-scan []<-[$$45, $$46, $$47, $$B] <- test.B [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                      -- DATASOURCE_SCAN  |PARTITIONED|
-                        exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      empty-tuple-source
+                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.7.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.7.query.plan
index 6fe29dd..2751a74 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.7.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.7.query.plan
@@ -1,44 +1,38 @@
-distribute result [$$41] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+distribute result [$$43]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$41]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-    -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$41] <- [{"a_0": $$42, "a_1": $$43, "a_2": $$44, "a_3": $$48, "b_3": $$49}] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-      -- ASSIGN  |PARTITIONED|
-        project ([$$42, $$43, $$44, $$48, $$49]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-        -- STREAM_PROJECT  |PARTITIONED|
-          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            left outer join (and(eq($$48, $$49), eq($$42, $$45), eq($$46, $$43))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-            -- HYBRID_HASH_JOIN [$$48, $$42, $$43][$$49, $$45, $$46]  |PARTITIONED|
-              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-              -- HASH_PARTITION_EXCHANGE [$$48, $$42, $$43]  |PARTITIONED|
-                project ([$$42, $$43, $$44, $$48]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                -- STREAM_PROJECT  |PARTITIONED|
-                  assign [$$48] <- [$$A.getField("a_3")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                  -- ASSIGN  |PARTITIONED|
-                    exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+    assign [$$43] <- [{"a_0": $$44, "a_1": $$45, "a_2": $$46, "a_3": $$50, "b_3": $$51}] project: [$$43]
+    -- ASSIGN  |PARTITIONED|
+      project ([$$44, $$45, $$46, $$50, $$51])
+      -- STREAM_PROJECT  |PARTITIONED|
+        exchange
+        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          left outer join (and(eq($$50, $$51), eq($$44, $$47), eq($$48, $$45)))
+          -- HYBRID_HASH_JOIN [$$50, $$44, $$45][$$51, $$47, $$48]  |PARTITIONED|
+            exchange
+            -- HASH_PARTITION_EXCHANGE [$$50, $$44, $$45]  |PARTITIONED|
+              assign [$$50] <- [$$A.getField("a_3")] project: [$$44, $$45, $$46, $$50]
+              -- ASSIGN  |PARTITIONED|
+                exchange
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  data-scan []<-[$$44, $$45, $$46, $$A] <- test.A
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      data-scan []<-[$$42, $$43, $$44, $$A] <- test.A [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                      -- DATASOURCE_SCAN  |PARTITIONED|
-                        exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-              -- HASH_PARTITION_EXCHANGE [$$49, $$45, $$46]  |PARTITIONED|
-                project ([$$49, $$45, $$46]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                      empty-tuple-source
+                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
+            -- HASH_PARTITION_EXCHANGE [$$51, $$47, $$48]  |PARTITIONED|
+              assign [$$51] <- [$$B.getField("b_3")] project: [$$51, $$47, $$48]
+              -- ASSIGN  |PARTITIONED|
+                project ([$$47, $$48, $$B])
                 -- STREAM_PROJECT  |PARTITIONED|
-                  assign [$$49] <- [$$B.getField("b_3")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                  -- ASSIGN  |PARTITIONED|
-                    project ([$$45, $$46, $$B]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                    -- STREAM_PROJECT  |PARTITIONED|
-                      exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                  exchange
+                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    data-scan []<-[$$47, $$48, $$49, $$B] <- test.B
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        data-scan []<-[$$45, $$46, $$47, $$B] <- test.B [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                        -- DATASOURCE_SCAN  |PARTITIONED|
-                          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        empty-tuple-source
+                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.9.query.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.9.query.plan
index 37b0111..483fdc2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.9.query.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/joins/hash_join_exchange_1/hash_join_exchange_1.9.query.plan
@@ -1,44 +1,38 @@
-distribute result [$$38] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+distribute result [$$40]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+  exchange
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$38]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-    -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$38] <- [{"a_0": $$39, "a_1": $$40, "a_2": $$41, "a_3": $$52, "b_3": $$53}] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-      -- ASSIGN  |PARTITIONED|
-        project ([$$39, $$40, $$41, $$52, $$53]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-        -- STREAM_PROJECT  |PARTITIONED|
-          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            left outer join (and(eq($$39, $$42), eq($$43, $$40))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-            -- HYBRID_HASH_JOIN [$$39, $$40][$$42, $$43]  |PARTITIONED|
-              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-              -- HASH_PARTITION_EXCHANGE [$$39, $$40]  |PARTITIONED|
-                project ([$$39, $$40, $$41, $$52]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                -- STREAM_PROJECT  |PARTITIONED|
-                  assign [$$52] <- [$$A.getField("a_3")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                  -- ASSIGN  |PARTITIONED|
-                    exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+    assign [$$40] <- [{"a_0": $$41, "a_1": $$42, "a_2": $$43, "a_3": $$54, "b_3": $$55}] project: [$$40]
+    -- ASSIGN  |PARTITIONED|
+      project ([$$41, $$42, $$43, $$54, $$55])
+      -- STREAM_PROJECT  |PARTITIONED|
+        exchange
+        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          left outer join (and(eq($$41, $$44), eq($$45, $$42)))
+          -- HYBRID_HASH_JOIN [$$41, $$42][$$44, $$45]  |PARTITIONED|
+            exchange
+            -- HASH_PARTITION_EXCHANGE [$$41, $$42]  |PARTITIONED|
+              assign [$$54] <- [$$A.getField("a_3")] project: [$$41, $$42, $$43, $$54]
+              -- ASSIGN  |PARTITIONED|
+                exchange
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  data-scan []<-[$$41, $$42, $$43, $$A] <- test.A
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      data-scan []<-[$$39, $$40, $$41, $$A] <- test.A [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                      -- DATASOURCE_SCAN  |PARTITIONED|
-                        exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-              -- HASH_PARTITION_EXCHANGE [$$42, $$43]  |PARTITIONED|
-                project ([$$53, $$42, $$43]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                      empty-tuple-source
+                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+            exchange
+            -- HASH_PARTITION_EXCHANGE [$$44, $$45]  |PARTITIONED|
+              assign [$$55] <- [$$B.getField("b_3")] project: [$$55, $$44, $$45]
+              -- ASSIGN  |PARTITIONED|
+                project ([$$44, $$45, $$B])
                 -- STREAM_PROJECT  |PARTITIONED|
-                  assign [$$53] <- [$$B.getField("b_3")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                  -- ASSIGN  |PARTITIONED|
-                    project ([$$42, $$43, $$B]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                    -- STREAM_PROJECT  |PARTITIONED|
-                      exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                  exchange
+                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    data-scan []<-[$$44, $$45, $$46, $$B] <- test.B
+                    -- DATASOURCE_SCAN  |PARTITIONED|
+                      exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        data-scan []<-[$$42, $$43, $$44, $$B] <- test.B [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                        -- DATASOURCE_SCAN  |PARTITIONED|
-                          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        empty-tuple-source
+                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|