== Physical Plan ==
* Sort (23)
+- Exchange (22)
   +- * HashAggregate (21)
      +- Exchange (20)
         +- * HashAggregate (19)
            +- * HashAggregate (18)
               +- Exchange (17)
                  +- * HashAggregate (16)
                     +- * Project (15)
                        +- * BroadcastHashJoin Inner BuildRight (14)
                           :- * BroadcastHashJoin LeftAnti BuildRight (9)
                           :  :- * Filter (3)
                           :  :  +- * ColumnarToRow (2)
                           :  :     +- Scan parquet spark_catalog.default.partsupp (1)
                           :  +- BroadcastExchange (8)
                           :     +- * Project (7)
                           :        +- * Filter (6)
                           :           +- * ColumnarToRow (5)
                           :              +- Scan parquet spark_catalog.default.supplier (4)
                           +- BroadcastExchange (13)
                              +- * Filter (12)
                                 +- * ColumnarToRow (11)
                                    +- Scan parquet spark_catalog.default.part (10)


(1) Scan parquet spark_catalog.default.partsupp
Output [2]: [ps_partkey#1, ps_suppkey#2]
Batched: true
Location [not included in comparison]/{warehouse_dir}/partsupp]
PushedFilters: [IsNotNull(ps_partkey)]
ReadSchema: struct<ps_partkey:bigint,ps_suppkey:bigint>

(2) ColumnarToRow [codegen id : 3]
Input [2]: [ps_partkey#1, ps_suppkey#2]

(3) Filter [codegen id : 3]
Input [2]: [ps_partkey#1, ps_suppkey#2]
Condition : isnotnull(ps_partkey#1)

(4) Scan parquet spark_catalog.default.supplier
Output [2]: [s_suppkey#3, s_comment#4]
Batched: true
Location [not included in comparison]/{warehouse_dir}/supplier]
PushedFilters: [IsNotNull(s_comment)]
ReadSchema: struct<s_suppkey:bigint,s_comment:string>

(5) ColumnarToRow [codegen id : 1]
Input [2]: [s_suppkey#3, s_comment#4]

(6) Filter [codegen id : 1]
Input [2]: [s_suppkey#3, s_comment#4]
Condition : (isnotnull(s_comment#4) AND s_comment#4 LIKE %Customer%Complaints%)

(7) Project [codegen id : 1]
Output [1]: [s_suppkey#3]
Input [2]: [s_suppkey#3, s_comment#4]

(8) BroadcastExchange
Input [1]: [s_suppkey#3]
Arguments: HashedRelationBroadcastMode(List(input[0, bigint, true]),true), [plan_id=1]

(9) BroadcastHashJoin [codegen id : 3]
Left keys [1]: [ps_suppkey#2]
Right keys [1]: [s_suppkey#3]
Join type: LeftAnti
Join condition: None

(10) Scan parquet spark_catalog.default.part
Output [4]: [p_partkey#5, p_brand#6, p_type#7, p_size#8]
Batched: true
Location [not included in comparison]/{warehouse_dir}/part]
PushedFilters: [IsNotNull(p_brand), IsNotNull(p_type), Not(EqualTo(p_brand,Brand#9)), Not(StringStartsWith(p_type,MEDIUM POLISHED)), In(p_size, [14,19,23,3,36,45,49,9]), IsNotNull(p_partkey)]
ReadSchema: struct<p_partkey:bigint,p_brand:string,p_type:string,p_size:int>

(11) ColumnarToRow [codegen id : 2]
Input [4]: [p_partkey#5, p_brand#6, p_type#7, p_size#8]

(12) Filter [codegen id : 2]
Input [4]: [p_partkey#5, p_brand#6, p_type#7, p_size#8]
Condition : (((((isnotnull(p_brand#6) AND isnotnull(p_type#7)) AND NOT (p_brand#6 = Brand#9)) AND NOT StartsWith(p_type#7, MEDIUM POLISHED)) AND p_size#8 IN (49,14,23,45,19,3,36,9)) AND isnotnull(p_partkey#5))

(13) BroadcastExchange
Input [4]: [p_partkey#5, p_brand#6, p_type#7, p_size#8]
Arguments: HashedRelationBroadcastMode(List(input[0, bigint, false]),false), [plan_id=2]

(14) BroadcastHashJoin [codegen id : 3]
Left keys [1]: [ps_partkey#1]
Right keys [1]: [p_partkey#5]
Join type: Inner
Join condition: None

(15) Project [codegen id : 3]
Output [4]: [ps_suppkey#2, p_brand#6, p_type#7, p_size#8]
Input [6]: [ps_partkey#1, ps_suppkey#2, p_partkey#5, p_brand#6, p_type#7, p_size#8]

(16) HashAggregate [codegen id : 3]
Input [4]: [ps_suppkey#2, p_brand#6, p_type#7, p_size#8]
Keys [4]: [p_brand#6, p_type#7, p_size#8, ps_suppkey#2]
Functions: []
Aggregate Attributes: []
Results [4]: [p_brand#6, p_type#7, p_size#8, ps_suppkey#2]

(17) Exchange
Input [4]: [p_brand#6, p_type#7, p_size#8, ps_suppkey#2]
Arguments: hashpartitioning(p_brand#6, p_type#7, p_size#8, ps_suppkey#2, 5), ENSURE_REQUIREMENTS, [plan_id=3]

(18) HashAggregate [codegen id : 4]
Input [4]: [p_brand#6, p_type#7, p_size#8, ps_suppkey#2]
Keys [4]: [p_brand#6, p_type#7, p_size#8, ps_suppkey#2]
Functions: []
Aggregate Attributes: []
Results [4]: [p_brand#6, p_type#7, p_size#8, ps_suppkey#2]

(19) HashAggregate [codegen id : 4]
Input [4]: [p_brand#6, p_type#7, p_size#8, ps_suppkey#2]
Keys [3]: [p_brand#6, p_type#7, p_size#8]
Functions [1]: [partial_count(distinct ps_suppkey#2)]
Aggregate Attributes [1]: [count(ps_suppkey#2)#10]
Results [4]: [p_brand#6, p_type#7, p_size#8, count#11]

(20) Exchange
Input [4]: [p_brand#6, p_type#7, p_size#8, count#11]
Arguments: hashpartitioning(p_brand#6, p_type#7, p_size#8, 5), ENSURE_REQUIREMENTS, [plan_id=4]

(21) HashAggregate [codegen id : 5]
Input [4]: [p_brand#6, p_type#7, p_size#8, count#11]
Keys [3]: [p_brand#6, p_type#7, p_size#8]
Functions [1]: [count(distinct ps_suppkey#2)]
Aggregate Attributes [1]: [count(ps_suppkey#2)#10]
Results [4]: [p_brand#6, p_type#7, p_size#8, count(ps_suppkey#2)#10 AS supplier_cnt#12]

(22) Exchange
Input [4]: [p_brand#6, p_type#7, p_size#8, supplier_cnt#12]
Arguments: rangepartitioning(supplier_cnt#12 DESC NULLS LAST, p_brand#6 ASC NULLS FIRST, p_type#7 ASC NULLS FIRST, p_size#8 ASC NULLS FIRST, 5), ENSURE_REQUIREMENTS, [plan_id=5]

(23) Sort [codegen id : 6]
Input [4]: [p_brand#6, p_type#7, p_size#8, supplier_cnt#12]
Arguments: [supplier_cnt#12 DESC NULLS LAST, p_brand#6 ASC NULLS FIRST, p_type#7 ASC NULLS FIRST, p_size#8 ASC NULLS FIRST], true, 0

