== Physical Plan ==
TakeOrderedAndProject (91)
+- * HashAggregate (90)
   +- Exchange (89)
      +- * HashAggregate (88)
         +- Union (87)
            :- * HashAggregate (76)
            :  +- Exchange (75)
            :     +- * HashAggregate (74)
            :        +- Union (73)
            :           :- * HashAggregate (25)
            :           :  +- Exchange (24)
            :           :     +- * HashAggregate (23)
            :           :        +- * Project (22)
            :           :           +- * BroadcastHashJoin Inner BuildRight (21)
            :           :              :- * Project (16)
            :           :              :  +- * BroadcastHashJoin Inner BuildRight (15)
            :           :              :     :- Union (9)
            :           :              :     :  :- * Project (4)
            :           :              :     :  :  +- * Filter (3)
            :           :              :     :  :     +- * ColumnarToRow (2)
            :           :              :     :  :        +- Scan parquet spark_catalog.default.store_sales (1)
            :           :              :     :  +- * Project (8)
            :           :              :     :     +- * Filter (7)
            :           :              :     :        +- * ColumnarToRow (6)
            :           :              :     :           +- Scan parquet spark_catalog.default.store_returns (5)
            :           :              :     +- BroadcastExchange (14)
            :           :              :        +- * Project (13)
            :           :              :           +- * Filter (12)
            :           :              :              +- * ColumnarToRow (11)
            :           :              :                 +- Scan parquet spark_catalog.default.date_dim (10)
            :           :              +- BroadcastExchange (20)
            :           :                 +- * Filter (19)
            :           :                    +- * ColumnarToRow (18)
            :           :                       +- Scan parquet spark_catalog.default.store (17)
            :           :- * HashAggregate (46)
            :           :  +- Exchange (45)
            :           :     +- * HashAggregate (44)
            :           :        +- * Project (43)
            :           :           +- * BroadcastHashJoin Inner BuildRight (42)
            :           :              :- * Project (37)
            :           :              :  +- * BroadcastHashJoin Inner BuildRight (36)
            :           :              :     :- Union (34)
            :           :              :     :  :- * Project (29)
            :           :              :     :  :  +- * Filter (28)
            :           :              :     :  :     +- * ColumnarToRow (27)
            :           :              :     :  :        +- Scan parquet spark_catalog.default.catalog_sales (26)
            :           :              :     :  +- * Project (33)
            :           :              :     :     +- * Filter (32)
            :           :              :     :        +- * ColumnarToRow (31)
            :           :              :     :           +- Scan parquet spark_catalog.default.catalog_returns (30)
            :           :              :     +- ReusedExchange (35)
            :           :              +- BroadcastExchange (41)
            :           :                 +- * Filter (40)
            :           :                    +- * ColumnarToRow (39)
            :           :                       +- Scan parquet spark_catalog.default.catalog_page (38)
            :           +- * HashAggregate (72)
            :              +- Exchange (71)
            :                 +- * HashAggregate (70)
            :                    +- * Project (69)
            :                       +- * BroadcastHashJoin Inner BuildRight (68)
            :                          :- * Project (63)
            :                          :  +- * BroadcastHashJoin Inner BuildRight (62)
            :                          :     :- Union (60)
            :                          :     :  :- * Project (50)
            :                          :     :  :  +- * Filter (49)
            :                          :     :  :     +- * ColumnarToRow (48)
            :                          :     :  :        +- Scan parquet spark_catalog.default.web_sales (47)
            :                          :     :  +- * Project (59)
            :                          :     :     +- * BroadcastHashJoin Inner BuildLeft (58)
            :                          :     :        :- BroadcastExchange (53)
            :                          :     :        :  +- * ColumnarToRow (52)
            :                          :     :        :     +- Scan parquet spark_catalog.default.web_returns (51)
            :                          :     :        +- * Project (57)
            :                          :     :           +- * Filter (56)
            :                          :     :              +- * ColumnarToRow (55)
            :                          :     :                 +- Scan parquet spark_catalog.default.web_sales (54)
            :                          :     +- ReusedExchange (61)
            :                          +- BroadcastExchange (67)
            :                             +- * Filter (66)
            :                                +- * ColumnarToRow (65)
            :                                   +- Scan parquet spark_catalog.default.web_site (64)
            :- * HashAggregate (81)
            :  +- Exchange (80)
            :     +- * HashAggregate (79)
            :        +- * HashAggregate (78)
            :           +- ReusedExchange (77)
            +- * HashAggregate (86)
               +- Exchange (85)
                  +- * HashAggregate (84)
                     +- * HashAggregate (83)
                        +- ReusedExchange (82)


(1) Scan parquet spark_catalog.default.store_sales
Output [4]: [ss_store_sk#1, ss_ext_sales_price#2, ss_net_profit#3, ss_sold_date_sk#4]
Batched: true
Location: InMemoryFileIndex []
PartitionFilters: [isnotnull(ss_sold_date_sk#4)]
PushedFilters: [IsNotNull(ss_store_sk)]
ReadSchema: struct<ss_store_sk:int,ss_ext_sales_price:decimal(7,2),ss_net_profit:decimal(7,2)>

(2) ColumnarToRow [codegen id : 1]
Input [4]: [ss_store_sk#1, ss_ext_sales_price#2, ss_net_profit#3, ss_sold_date_sk#4]

(3) Filter [codegen id : 1]
Input [4]: [ss_store_sk#1, ss_ext_sales_price#2, ss_net_profit#3, ss_sold_date_sk#4]
Condition : isnotnull(ss_store_sk#1)

(4) Project [codegen id : 1]
Output [6]: [ss_store_sk#1 AS store_sk#5, ss_sold_date_sk#4 AS date_sk#6, ss_ext_sales_price#2 AS sales_price#7, ss_net_profit#3 AS profit#8, 0.00 AS return_amt#9, 0.00 AS net_loss#10]
Input [4]: [ss_store_sk#1, ss_ext_sales_price#2, ss_net_profit#3, ss_sold_date_sk#4]

(5) Scan parquet spark_catalog.default.store_returns
Output [4]: [sr_store_sk#11, sr_return_amt#12, sr_net_loss#13, sr_returned_date_sk#14]
Batched: true
Location: InMemoryFileIndex []
PartitionFilters: [isnotnull(sr_returned_date_sk#14)]
PushedFilters: [IsNotNull(sr_store_sk)]
ReadSchema: struct<sr_store_sk:int,sr_return_amt:decimal(7,2),sr_net_loss:decimal(7,2)>

(6) ColumnarToRow [codegen id : 2]
Input [4]: [sr_store_sk#11, sr_return_amt#12, sr_net_loss#13, sr_returned_date_sk#14]

(7) Filter [codegen id : 2]
Input [4]: [sr_store_sk#11, sr_return_amt#12, sr_net_loss#13, sr_returned_date_sk#14]
Condition : isnotnull(sr_store_sk#11)

(8) Project [codegen id : 2]
Output [6]: [sr_store_sk#11 AS store_sk#15, sr_returned_date_sk#14 AS date_sk#16, 0.00 AS sales_price#17, 0.00 AS profit#18, sr_return_amt#12 AS return_amt#19, sr_net_loss#13 AS net_loss#20]
Input [4]: [sr_store_sk#11, sr_return_amt#12, sr_net_loss#13, sr_returned_date_sk#14]

(9) Union

(10) Scan parquet spark_catalog.default.date_dim
Output [2]: [d_date_sk#21, d_date#22]
Batched: true
Location [not included in comparison]/{warehouse_dir}/date_dim]
PushedFilters: [IsNotNull(d_date), GreaterThanOrEqual(d_date,1998-08-04), LessThanOrEqual(d_date,1998-08-18), IsNotNull(d_date_sk)]
ReadSchema: struct<d_date_sk:int,d_date:date>

(11) ColumnarToRow [codegen id : 3]
Input [2]: [d_date_sk#21, d_date#22]

(12) Filter [codegen id : 3]
Input [2]: [d_date_sk#21, d_date#22]
Condition : (((isnotnull(d_date#22) AND (d_date#22 >= 1998-08-04)) AND (d_date#22 <= 1998-08-18)) AND isnotnull(d_date_sk#21))

(13) Project [codegen id : 3]
Output [1]: [d_date_sk#21]
Input [2]: [d_date_sk#21, d_date#22]

(14) BroadcastExchange
Input [1]: [d_date_sk#21]
Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, true] as bigint)),false), [plan_id=1]

(15) BroadcastHashJoin [codegen id : 5]
Left keys [1]: [date_sk#6]
Right keys [1]: [d_date_sk#21]
Join type: Inner
Join condition: None

(16) Project [codegen id : 5]
Output [5]: [store_sk#5, sales_price#7, profit#8, return_amt#9, net_loss#10]
Input [7]: [store_sk#5, date_sk#6, sales_price#7, profit#8, return_amt#9, net_loss#10, d_date_sk#21]

(17) Scan parquet spark_catalog.default.store
Output [2]: [s_store_sk#23, s_store_id#24]
Batched: true
Location [not included in comparison]/{warehouse_dir}/store]
PushedFilters: [IsNotNull(s_store_sk)]
ReadSchema: struct<s_store_sk:int,s_store_id:string>

(18) ColumnarToRow [codegen id : 4]
Input [2]: [s_store_sk#23, s_store_id#24]

(19) Filter [codegen id : 4]
Input [2]: [s_store_sk#23, s_store_id#24]
Condition : isnotnull(s_store_sk#23)

(20) BroadcastExchange
Input [2]: [s_store_sk#23, s_store_id#24]
Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=2]

(21) BroadcastHashJoin [codegen id : 5]
Left keys [1]: [store_sk#5]
Right keys [1]: [s_store_sk#23]
Join type: Inner
Join condition: None

(22) Project [codegen id : 5]
Output [5]: [sales_price#7, profit#8, return_amt#9, net_loss#10, s_store_id#24]
Input [7]: [store_sk#5, sales_price#7, profit#8, return_amt#9, net_loss#10, s_store_sk#23, s_store_id#24]

(23) HashAggregate [codegen id : 5]
Input [5]: [sales_price#7, profit#8, return_amt#9, net_loss#10, s_store_id#24]
Keys [1]: [s_store_id#24]
Functions [4]: [partial_sum(UnscaledValue(sales_price#7)), partial_sum(UnscaledValue(return_amt#9)), partial_sum(UnscaledValue(profit#8)), partial_sum(UnscaledValue(net_loss#10))]
Aggregate Attributes [4]: [sum#25, sum#26, sum#27, sum#28]
Results [5]: [s_store_id#24, sum#29, sum#30, sum#31, sum#32]

(24) Exchange
Input [5]: [s_store_id#24, sum#29, sum#30, sum#31, sum#32]
Arguments: hashpartitioning(s_store_id#24, 5), ENSURE_REQUIREMENTS, [plan_id=3]

(25) HashAggregate [codegen id : 6]
Input [5]: [s_store_id#24, sum#29, sum#30, sum#31, sum#32]
Keys [1]: [s_store_id#24]
Functions [4]: [sum(UnscaledValue(sales_price#7)), sum(UnscaledValue(return_amt#9)), sum(UnscaledValue(profit#8)), sum(UnscaledValue(net_loss#10))]
Aggregate Attributes [4]: [sum(UnscaledValue(sales_price#7))#33, sum(UnscaledValue(return_amt#9))#34, sum(UnscaledValue(profit#8))#35, sum(UnscaledValue(net_loss#10))#36]
Results [5]: [store channel AS channel#37, concat(store, s_store_id#24) AS id#38, MakeDecimal(sum(UnscaledValue(sales_price#7))#33,17,2) AS sales#39, MakeDecimal(sum(UnscaledValue(return_amt#9))#34,17,2) AS returns#40, (MakeDecimal(sum(UnscaledValue(profit#8))#35,17,2) - MakeDecimal(sum(UnscaledValue(net_loss#10))#36,17,2)) AS profit#41]

(26) Scan parquet spark_catalog.default.catalog_sales
Output [4]: [cs_catalog_page_sk#42, cs_ext_sales_price#43, cs_net_profit#44, cs_sold_date_sk#45]
Batched: true
Location: InMemoryFileIndex []
PartitionFilters: [isnotnull(cs_sold_date_sk#45)]
PushedFilters: [IsNotNull(cs_catalog_page_sk)]
ReadSchema: struct<cs_catalog_page_sk:int,cs_ext_sales_price:decimal(7,2),cs_net_profit:decimal(7,2)>

(27) ColumnarToRow [codegen id : 7]
Input [4]: [cs_catalog_page_sk#42, cs_ext_sales_price#43, cs_net_profit#44, cs_sold_date_sk#45]

(28) Filter [codegen id : 7]
Input [4]: [cs_catalog_page_sk#42, cs_ext_sales_price#43, cs_net_profit#44, cs_sold_date_sk#45]
Condition : isnotnull(cs_catalog_page_sk#42)

(29) Project [codegen id : 7]
Output [6]: [cs_catalog_page_sk#42 AS page_sk#46, cs_sold_date_sk#45 AS date_sk#47, cs_ext_sales_price#43 AS sales_price#48, cs_net_profit#44 AS profit#49, 0.00 AS return_amt#50, 0.00 AS net_loss#51]
Input [4]: [cs_catalog_page_sk#42, cs_ext_sales_price#43, cs_net_profit#44, cs_sold_date_sk#45]

(30) Scan parquet spark_catalog.default.catalog_returns
Output [4]: [cr_catalog_page_sk#52, cr_return_amount#53, cr_net_loss#54, cr_returned_date_sk#55]
Batched: true
Location: InMemoryFileIndex []
PartitionFilters: [isnotnull(cr_returned_date_sk#55)]
PushedFilters: [IsNotNull(cr_catalog_page_sk)]
ReadSchema: struct<cr_catalog_page_sk:int,cr_return_amount:decimal(7,2),cr_net_loss:decimal(7,2)>

(31) ColumnarToRow [codegen id : 8]
Input [4]: [cr_catalog_page_sk#52, cr_return_amount#53, cr_net_loss#54, cr_returned_date_sk#55]

(32) Filter [codegen id : 8]
Input [4]: [cr_catalog_page_sk#52, cr_return_amount#53, cr_net_loss#54, cr_returned_date_sk#55]
Condition : isnotnull(cr_catalog_page_sk#52)

(33) Project [codegen id : 8]
Output [6]: [cr_catalog_page_sk#52 AS page_sk#56, cr_returned_date_sk#55 AS date_sk#57, 0.00 AS sales_price#58, 0.00 AS profit#59, cr_return_amount#53 AS return_amt#60, cr_net_loss#54 AS net_loss#61]
Input [4]: [cr_catalog_page_sk#52, cr_return_amount#53, cr_net_loss#54, cr_returned_date_sk#55]

(34) Union

(35) ReusedExchange [Reuses operator id: 14]
Output [1]: [d_date_sk#62]

(36) BroadcastHashJoin [codegen id : 11]
Left keys [1]: [date_sk#47]
Right keys [1]: [d_date_sk#62]
Join type: Inner
Join condition: None

(37) Project [codegen id : 11]
Output [5]: [page_sk#46, sales_price#48, profit#49, return_amt#50, net_loss#51]
Input [7]: [page_sk#46, date_sk#47, sales_price#48, profit#49, return_amt#50, net_loss#51, d_date_sk#62]

(38) Scan parquet spark_catalog.default.catalog_page
Output [2]: [cp_catalog_page_sk#63, cp_catalog_page_id#64]
Batched: true
Location [not included in comparison]/{warehouse_dir}/catalog_page]
PushedFilters: [IsNotNull(cp_catalog_page_sk)]
ReadSchema: struct<cp_catalog_page_sk:int,cp_catalog_page_id:string>

(39) ColumnarToRow [codegen id : 10]
Input [2]: [cp_catalog_page_sk#63, cp_catalog_page_id#64]

(40) Filter [codegen id : 10]
Input [2]: [cp_catalog_page_sk#63, cp_catalog_page_id#64]
Condition : isnotnull(cp_catalog_page_sk#63)

(41) BroadcastExchange
Input [2]: [cp_catalog_page_sk#63, cp_catalog_page_id#64]
Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=4]

(42) BroadcastHashJoin [codegen id : 11]
Left keys [1]: [page_sk#46]
Right keys [1]: [cp_catalog_page_sk#63]
Join type: Inner
Join condition: None

(43) Project [codegen id : 11]
Output [5]: [sales_price#48, profit#49, return_amt#50, net_loss#51, cp_catalog_page_id#64]
Input [7]: [page_sk#46, sales_price#48, profit#49, return_amt#50, net_loss#51, cp_catalog_page_sk#63, cp_catalog_page_id#64]

(44) HashAggregate [codegen id : 11]
Input [5]: [sales_price#48, profit#49, return_amt#50, net_loss#51, cp_catalog_page_id#64]
Keys [1]: [cp_catalog_page_id#64]
Functions [4]: [partial_sum(UnscaledValue(sales_price#48)), partial_sum(UnscaledValue(return_amt#50)), partial_sum(UnscaledValue(profit#49)), partial_sum(UnscaledValue(net_loss#51))]
Aggregate Attributes [4]: [sum#65, sum#66, sum#67, sum#68]
Results [5]: [cp_catalog_page_id#64, sum#69, sum#70, sum#71, sum#72]

(45) Exchange
Input [5]: [cp_catalog_page_id#64, sum#69, sum#70, sum#71, sum#72]
Arguments: hashpartitioning(cp_catalog_page_id#64, 5), ENSURE_REQUIREMENTS, [plan_id=5]

(46) HashAggregate [codegen id : 12]
Input [5]: [cp_catalog_page_id#64, sum#69, sum#70, sum#71, sum#72]
Keys [1]: [cp_catalog_page_id#64]
Functions [4]: [sum(UnscaledValue(sales_price#48)), sum(UnscaledValue(return_amt#50)), sum(UnscaledValue(profit#49)), sum(UnscaledValue(net_loss#51))]
Aggregate Attributes [4]: [sum(UnscaledValue(sales_price#48))#73, sum(UnscaledValue(return_amt#50))#74, sum(UnscaledValue(profit#49))#75, sum(UnscaledValue(net_loss#51))#76]
Results [5]: [catalog channel AS channel#77, concat(catalog_page, cp_catalog_page_id#64) AS id#78, MakeDecimal(sum(UnscaledValue(sales_price#48))#73,17,2) AS sales#79, MakeDecimal(sum(UnscaledValue(return_amt#50))#74,17,2) AS returns#80, (MakeDecimal(sum(UnscaledValue(profit#49))#75,17,2) - MakeDecimal(sum(UnscaledValue(net_loss#51))#76,17,2)) AS profit#81]

(47) Scan parquet spark_catalog.default.web_sales
Output [4]: [ws_web_site_sk#82, ws_ext_sales_price#83, ws_net_profit#84, ws_sold_date_sk#85]
Batched: true
Location: InMemoryFileIndex []
PartitionFilters: [isnotnull(ws_sold_date_sk#85)]
PushedFilters: [IsNotNull(ws_web_site_sk)]
ReadSchema: struct<ws_web_site_sk:int,ws_ext_sales_price:decimal(7,2),ws_net_profit:decimal(7,2)>

(48) ColumnarToRow [codegen id : 13]
Input [4]: [ws_web_site_sk#82, ws_ext_sales_price#83, ws_net_profit#84, ws_sold_date_sk#85]

(49) Filter [codegen id : 13]
Input [4]: [ws_web_site_sk#82, ws_ext_sales_price#83, ws_net_profit#84, ws_sold_date_sk#85]
Condition : isnotnull(ws_web_site_sk#82)

(50) Project [codegen id : 13]
Output [6]: [ws_web_site_sk#82 AS wsr_web_site_sk#86, ws_sold_date_sk#85 AS date_sk#87, ws_ext_sales_price#83 AS sales_price#88, ws_net_profit#84 AS profit#89, 0.00 AS return_amt#90, 0.00 AS net_loss#91]
Input [4]: [ws_web_site_sk#82, ws_ext_sales_price#83, ws_net_profit#84, ws_sold_date_sk#85]

(51) Scan parquet spark_catalog.default.web_returns
Output [5]: [wr_item_sk#92, wr_order_number#93, wr_return_amt#94, wr_net_loss#95, wr_returned_date_sk#96]
Batched: true
Location: InMemoryFileIndex []
PartitionFilters: [isnotnull(wr_returned_date_sk#96)]
ReadSchema: struct<wr_item_sk:int,wr_order_number:int,wr_return_amt:decimal(7,2),wr_net_loss:decimal(7,2)>

(52) ColumnarToRow [codegen id : 14]
Input [5]: [wr_item_sk#92, wr_order_number#93, wr_return_amt#94, wr_net_loss#95, wr_returned_date_sk#96]

(53) BroadcastExchange
Input [5]: [wr_item_sk#92, wr_order_number#93, wr_return_amt#94, wr_net_loss#95, wr_returned_date_sk#96]
Arguments: HashedRelationBroadcastMode(List((shiftleft(cast(input[0, int, true] as bigint), 32) | (cast(input[1, int, true] as bigint) & 4294967295))),false), [plan_id=6]

(54) Scan parquet spark_catalog.default.web_sales
Output [4]: [ws_item_sk#97, ws_web_site_sk#98, ws_order_number#99, ws_sold_date_sk#100]
Batched: true
Location [not included in comparison]/{warehouse_dir}/web_sales]
PushedFilters: [IsNotNull(ws_item_sk), IsNotNull(ws_order_number), IsNotNull(ws_web_site_sk)]
ReadSchema: struct<ws_item_sk:int,ws_web_site_sk:int,ws_order_number:int>

(55) ColumnarToRow
Input [4]: [ws_item_sk#97, ws_web_site_sk#98, ws_order_number#99, ws_sold_date_sk#100]

(56) Filter
Input [4]: [ws_item_sk#97, ws_web_site_sk#98, ws_order_number#99, ws_sold_date_sk#100]
Condition : ((isnotnull(ws_item_sk#97) AND isnotnull(ws_order_number#99)) AND isnotnull(ws_web_site_sk#98))

(57) Project
Output [3]: [ws_item_sk#97, ws_web_site_sk#98, ws_order_number#99]
Input [4]: [ws_item_sk#97, ws_web_site_sk#98, ws_order_number#99, ws_sold_date_sk#100]

(58) BroadcastHashJoin [codegen id : 15]
Left keys [2]: [wr_item_sk#92, wr_order_number#93]
Right keys [2]: [ws_item_sk#97, ws_order_number#99]
Join type: Inner
Join condition: None

(59) Project [codegen id : 15]
Output [6]: [ws_web_site_sk#98 AS wsr_web_site_sk#101, wr_returned_date_sk#96 AS date_sk#102, 0.00 AS sales_price#103, 0.00 AS profit#104, wr_return_amt#94 AS return_amt#105, wr_net_loss#95 AS net_loss#106]
Input [8]: [wr_item_sk#92, wr_order_number#93, wr_return_amt#94, wr_net_loss#95, wr_returned_date_sk#96, ws_item_sk#97, ws_web_site_sk#98, ws_order_number#99]

(60) Union

(61) ReusedExchange [Reuses operator id: 14]
Output [1]: [d_date_sk#107]

(62) BroadcastHashJoin [codegen id : 18]
Left keys [1]: [date_sk#87]
Right keys [1]: [d_date_sk#107]
Join type: Inner
Join condition: None

(63) Project [codegen id : 18]
Output [5]: [wsr_web_site_sk#86, sales_price#88, profit#89, return_amt#90, net_loss#91]
Input [7]: [wsr_web_site_sk#86, date_sk#87, sales_price#88, profit#89, return_amt#90, net_loss#91, d_date_sk#107]

(64) Scan parquet spark_catalog.default.web_site
Output [2]: [web_site_sk#108, web_site_id#109]
Batched: true
Location [not included in comparison]/{warehouse_dir}/web_site]
PushedFilters: [IsNotNull(web_site_sk)]
ReadSchema: struct<web_site_sk:int,web_site_id:string>

(65) ColumnarToRow [codegen id : 17]
Input [2]: [web_site_sk#108, web_site_id#109]

(66) Filter [codegen id : 17]
Input [2]: [web_site_sk#108, web_site_id#109]
Condition : isnotnull(web_site_sk#108)

(67) BroadcastExchange
Input [2]: [web_site_sk#108, web_site_id#109]
Arguments: HashedRelationBroadcastMode(List(cast(input[0, int, false] as bigint)),false), [plan_id=7]

(68) BroadcastHashJoin [codegen id : 18]
Left keys [1]: [wsr_web_site_sk#86]
Right keys [1]: [web_site_sk#108]
Join type: Inner
Join condition: None

(69) Project [codegen id : 18]
Output [5]: [sales_price#88, profit#89, return_amt#90, net_loss#91, web_site_id#109]
Input [7]: [wsr_web_site_sk#86, sales_price#88, profit#89, return_amt#90, net_loss#91, web_site_sk#108, web_site_id#109]

(70) HashAggregate [codegen id : 18]
Input [5]: [sales_price#88, profit#89, return_amt#90, net_loss#91, web_site_id#109]
Keys [1]: [web_site_id#109]
Functions [4]: [partial_sum(UnscaledValue(sales_price#88)), partial_sum(UnscaledValue(return_amt#90)), partial_sum(UnscaledValue(profit#89)), partial_sum(UnscaledValue(net_loss#91))]
Aggregate Attributes [4]: [sum#110, sum#111, sum#112, sum#113]
Results [5]: [web_site_id#109, sum#114, sum#115, sum#116, sum#117]

(71) Exchange
Input [5]: [web_site_id#109, sum#114, sum#115, sum#116, sum#117]
Arguments: hashpartitioning(web_site_id#109, 5), ENSURE_REQUIREMENTS, [plan_id=8]

(72) HashAggregate [codegen id : 19]
Input [5]: [web_site_id#109, sum#114, sum#115, sum#116, sum#117]
Keys [1]: [web_site_id#109]
Functions [4]: [sum(UnscaledValue(sales_price#88)), sum(UnscaledValue(return_amt#90)), sum(UnscaledValue(profit#89)), sum(UnscaledValue(net_loss#91))]
Aggregate Attributes [4]: [sum(UnscaledValue(sales_price#88))#118, sum(UnscaledValue(return_amt#90))#119, sum(UnscaledValue(profit#89))#120, sum(UnscaledValue(net_loss#91))#121]
Results [5]: [web channel AS channel#122, concat(web_site, web_site_id#109) AS id#123, MakeDecimal(sum(UnscaledValue(sales_price#88))#118,17,2) AS sales#124, MakeDecimal(sum(UnscaledValue(return_amt#90))#119,17,2) AS returns#125, (MakeDecimal(sum(UnscaledValue(profit#89))#120,17,2) - MakeDecimal(sum(UnscaledValue(net_loss#91))#121,17,2)) AS profit#126]

(73) Union

(74) HashAggregate [codegen id : 20]
Input [5]: [channel#37, id#38, sales#39, returns#40, profit#41]
Keys [2]: [channel#37, id#38]
Functions [3]: [partial_sum(sales#39), partial_sum(returns#40), partial_sum(profit#41)]
Aggregate Attributes [6]: [sum#127, isEmpty#128, sum#129, isEmpty#130, sum#131, isEmpty#132]
Results [8]: [channel#37, id#38, sum#133, isEmpty#134, sum#135, isEmpty#136, sum#137, isEmpty#138]

(75) Exchange
Input [8]: [channel#37, id#38, sum#133, isEmpty#134, sum#135, isEmpty#136, sum#137, isEmpty#138]
Arguments: hashpartitioning(channel#37, id#38, 5), ENSURE_REQUIREMENTS, [plan_id=9]

(76) HashAggregate [codegen id : 21]
Input [8]: [channel#37, id#38, sum#133, isEmpty#134, sum#135, isEmpty#136, sum#137, isEmpty#138]
Keys [2]: [channel#37, id#38]
Functions [3]: [sum(sales#39), sum(returns#40), sum(profit#41)]
Aggregate Attributes [3]: [sum(sales#39)#139, sum(returns#40)#140, sum(profit#41)#141]
Results [5]: [channel#37, id#38, cast(sum(sales#39)#139 as decimal(37,2)) AS sales#142, cast(sum(returns#40)#140 as decimal(37,2)) AS returns#143, cast(sum(profit#41)#141 as decimal(38,2)) AS profit#144]

(77) ReusedExchange [Reuses operator id: 75]
Output [8]: [channel#37, id#38, sum#133, isEmpty#134, sum#135, isEmpty#136, sum#137, isEmpty#138]

(78) HashAggregate [codegen id : 42]
Input [8]: [channel#37, id#38, sum#133, isEmpty#134, sum#135, isEmpty#136, sum#137, isEmpty#138]
Keys [2]: [channel#37, id#38]
Functions [3]: [sum(sales#39), sum(returns#40), sum(profit#41)]
Aggregate Attributes [3]: [sum(sales#39)#139, sum(returns#40)#140, sum(profit#41)#141]
Results [4]: [channel#37, sum(sales#39)#139 AS sales#145, sum(returns#40)#140 AS returns#146, sum(profit#41)#141 AS profit#147]

(79) HashAggregate [codegen id : 42]
Input [4]: [channel#37, sales#145, returns#146, profit#147]
Keys [1]: [channel#37]
Functions [3]: [partial_sum(sales#145), partial_sum(returns#146), partial_sum(profit#147)]
Aggregate Attributes [6]: [sum#148, isEmpty#149, sum#150, isEmpty#151, sum#152, isEmpty#153]
Results [7]: [channel#37, sum#154, isEmpty#155, sum#156, isEmpty#157, sum#158, isEmpty#159]

(80) Exchange
Input [7]: [channel#37, sum#154, isEmpty#155, sum#156, isEmpty#157, sum#158, isEmpty#159]
Arguments: hashpartitioning(channel#37, 5), ENSURE_REQUIREMENTS, [plan_id=10]

(81) HashAggregate [codegen id : 43]
Input [7]: [channel#37, sum#154, isEmpty#155, sum#156, isEmpty#157, sum#158, isEmpty#159]
Keys [1]: [channel#37]
Functions [3]: [sum(sales#145), sum(returns#146), sum(profit#147)]
Aggregate Attributes [3]: [sum(sales#145)#160, sum(returns#146)#161, sum(profit#147)#162]
Results [5]: [channel#37, null AS id#163, sum(sales#145)#160 AS sum(sales)#164, sum(returns#146)#161 AS sum(returns)#165, sum(profit#147)#162 AS sum(profit)#166]

(82) ReusedExchange [Reuses operator id: 75]
Output [8]: [channel#37, id#38, sum#133, isEmpty#134, sum#135, isEmpty#136, sum#137, isEmpty#138]

(83) HashAggregate [codegen id : 64]
Input [8]: [channel#37, id#38, sum#133, isEmpty#134, sum#135, isEmpty#136, sum#137, isEmpty#138]
Keys [2]: [channel#37, id#38]
Functions [3]: [sum(sales#39), sum(returns#40), sum(profit#41)]
Aggregate Attributes [3]: [sum(sales#39)#139, sum(returns#40)#140, sum(profit#41)#141]
Results [3]: [sum(sales#39)#139 AS sales#145, sum(returns#40)#140 AS returns#146, sum(profit#41)#141 AS profit#147]

(84) HashAggregate [codegen id : 64]
Input [3]: [sales#145, returns#146, profit#147]
Keys: []
Functions [3]: [partial_sum(sales#145), partial_sum(returns#146), partial_sum(profit#147)]
Aggregate Attributes [6]: [sum#167, isEmpty#168, sum#169, isEmpty#170, sum#171, isEmpty#172]
Results [6]: [sum#173, isEmpty#174, sum#175, isEmpty#176, sum#177, isEmpty#178]

(85) Exchange
Input [6]: [sum#173, isEmpty#174, sum#175, isEmpty#176, sum#177, isEmpty#178]
Arguments: SinglePartition, ENSURE_REQUIREMENTS, [plan_id=11]

(86) HashAggregate [codegen id : 65]
Input [6]: [sum#173, isEmpty#174, sum#175, isEmpty#176, sum#177, isEmpty#178]
Keys: []
Functions [3]: [sum(sales#145), sum(returns#146), sum(profit#147)]
Aggregate Attributes [3]: [sum(sales#145)#179, sum(returns#146)#180, sum(profit#147)#181]
Results [5]: [null AS channel#182, null AS id#183, sum(sales#145)#179 AS sum(sales)#184, sum(returns#146)#180 AS sum(returns)#185, sum(profit#147)#181 AS sum(profit)#186]

(87) Union

(88) HashAggregate [codegen id : 66]
Input [5]: [channel#37, id#38, sales#142, returns#143, profit#144]
Keys [5]: [channel#37, id#38, sales#142, returns#143, profit#144]
Functions: []
Aggregate Attributes: []
Results [5]: [channel#37, id#38, sales#142, returns#143, profit#144]

(89) Exchange
Input [5]: [channel#37, id#38, sales#142, returns#143, profit#144]
Arguments: hashpartitioning(channel#37, id#38, sales#142, returns#143, profit#144, 5), ENSURE_REQUIREMENTS, [plan_id=12]

(90) HashAggregate [codegen id : 67]
Input [5]: [channel#37, id#38, sales#142, returns#143, profit#144]
Keys [5]: [channel#37, id#38, sales#142, returns#143, profit#144]
Functions: []
Aggregate Attributes: []
Results [5]: [channel#37, id#38, sales#142, returns#143, profit#144]

(91) TakeOrderedAndProject
Input [5]: [channel#37, id#38, sales#142, returns#143, profit#144]
Arguments: 100, [channel#37 ASC NULLS FIRST, id#38 ASC NULLS FIRST], [channel#37, id#38, sales#142, returns#143, profit#144]

