diff --git a/datafusion/physical-plan/src/joins/hash_join.rs b/datafusion/physical-plan/src/joins/hash_join.rs index f949c408cadc..39a15037260d 100644 --- a/datafusion/physical-plan/src/joins/hash_join.rs +++ b/datafusion/physical-plan/src/joins/hash_join.rs @@ -669,8 +669,17 @@ impl DisplayAs for HashJoinExec { ) } DisplayFormatType::TreeRender => { - // TODO: collect info - write!(f, "") + let on = self + .on + .iter() + .map(|(c1, c2)| format!("({} = {})", c1, c2)) + .collect::>() + .join(", "); + + if *self.join_type() != JoinType::Inner { + writeln!(f, "join_type={:?}", self.join_type)?; + } + writeln!(f, "on={}", on) } } } diff --git a/datafusion/sqllogictest/test_files/explain_tree.slt b/datafusion/sqllogictest/test_files/explain_tree.slt index 9659bdae195d..fb34d3ec1cc3 100644 --- a/datafusion/sqllogictest/test_files/explain_tree.slt +++ b/datafusion/sqllogictest/test_files/explain_tree.slt @@ -158,23 +158,26 @@ physical_plan 02)│ CoalesceBatchesExec │ 03)└─────────────┬─────────────┘ 04)┌─────────────┴─────────────┐ -05)│ HashJoinExec ├──────────────┐ -06)└─────────────┬─────────────┘ │ -07)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ -08)│ CoalesceBatchesExec ││ CoalesceBatchesExec │ -09)└─────────────┬─────────────┘└─────────────┬─────────────┘ +05)│ HashJoinExec │ +06)│ -------------------- │ +07)│ on: ├──────────────┐ +08)│ (int_col@0 = int_col@0) │ │ +09)└─────────────┬─────────────┘ │ 10)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ -11)│ RepartitionExec ││ RepartitionExec │ +11)│ CoalesceBatchesExec ││ CoalesceBatchesExec │ 12)└─────────────┬─────────────┘└─────────────┬─────────────┘ 13)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ 14)│ RepartitionExec ││ RepartitionExec │ 15)└─────────────┬─────────────┘└─────────────┬─────────────┘ 16)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ -17)│ DataSourceExec ││ DataSourceExec │ -18)│ -------------------- ││ -------------------- │ -19)│ files: 1 ││ files: 1 │ -20)│ format: csv ││ format: parquet │ -21)└───────────────────────────┘└───────────────────────────┘ +17)│ RepartitionExec ││ RepartitionExec │ +18)└─────────────┬─────────────┘└─────────────┬─────────────┘ +19)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ +20)│ DataSourceExec ││ DataSourceExec │ +21)│ -------------------- ││ -------------------- │ +22)│ files: 1 ││ files: 1 │ +23)│ format: csv ││ format: parquet │ +24)└───────────────────────────┘└───────────────────────────┘ # 3 Joins query TT @@ -199,33 +202,39 @@ physical_plan 02)│ CoalesceBatchesExec │ 03)└─────────────┬─────────────┘ 04)┌─────────────┴─────────────┐ -05)│ HashJoinExec ├───────────────────────────────────────────┐ -06)└─────────────┬─────────────┘ │ -07)┌─────────────┴─────────────┐ ┌─────────────┴─────────────┐ -08)│ CoalesceBatchesExec │ │ CoalesceBatchesExec │ -09)└─────────────┬─────────────┘ └─────────────┬─────────────┘ +05)│ HashJoinExec │ +06)│ -------------------- │ +07)│ on: ├───────────────────────────────────────────┐ +08)│ (int_col@1 = int_col@0) │ │ +09)└─────────────┬─────────────┘ │ 10)┌─────────────┴─────────────┐ ┌─────────────┴─────────────┐ -11)│ HashJoinExec ├──────────────┐ │ RepartitionExec │ -12)└─────────────┬─────────────┘ │ └─────────────┬─────────────┘ -13)┌─────────────┴─────────────┐┌─────────────┴─────────────┐┌─────────────┴─────────────┐ -14)│ CoalesceBatchesExec ││ CoalesceBatchesExec ││ DataSourceExec │ -15)│ ││ ││ -------------------- │ -16)│ ││ ││ bytes: 1560 │ -17)│ ││ ││ format: memory │ -18)│ ││ ││ rows: 1 │ -19)└─────────────┬─────────────┘└─────────────┬─────────────┘└───────────────────────────┘ -20)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ -21)│ RepartitionExec ││ RepartitionExec │ -22)└─────────────┬─────────────┘└─────────────┬─────────────┘ -23)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ -24)│ RepartitionExec ││ RepartitionExec │ -25)└─────────────┬─────────────┘└─────────────┬─────────────┘ +11)│ CoalesceBatchesExec │ │ CoalesceBatchesExec │ +12)└─────────────┬─────────────┘ └─────────────┬─────────────┘ +13)┌─────────────┴─────────────┐ ┌─────────────┴─────────────┐ +14)│ HashJoinExec │ │ RepartitionExec │ +15)│ -------------------- │ │ │ +16)│ on: ├──────────────┐ │ │ +17)│ (int_col@0 = int_col@0) │ │ │ │ +18)└─────────────┬─────────────┘ │ └─────────────┬─────────────┘ +19)┌─────────────┴─────────────┐┌─────────────┴─────────────┐┌─────────────┴─────────────┐ +20)│ CoalesceBatchesExec ││ CoalesceBatchesExec ││ DataSourceExec │ +21)│ ││ ││ -------------------- │ +22)│ ││ ││ bytes: 1560 │ +23)│ ││ ││ format: memory │ +24)│ ││ ││ rows: 1 │ +25)└─────────────┬─────────────┘└─────────────┬─────────────┘└───────────────────────────┘ 26)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ -27)│ DataSourceExec ││ DataSourceExec │ -28)│ -------------------- ││ -------------------- │ -29)│ files: 1 ││ files: 1 │ -30)│ format: csv ││ format: parquet │ -31)└───────────────────────────┘└───────────────────────────┘ +27)│ RepartitionExec ││ RepartitionExec │ +28)└─────────────┬─────────────┘└─────────────┬─────────────┘ +29)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ +30)│ RepartitionExec ││ RepartitionExec │ +31)└─────────────┬─────────────┘└─────────────┬─────────────┘ +32)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ +33)│ DataSourceExec ││ DataSourceExec │ +34)│ -------------------- ││ -------------------- │ +35)│ files: 1 ││ files: 1 │ +36)│ format: csv ││ format: parquet │ +37)└───────────────────────────┘└───────────────────────────┘ # Long Filter (demonstrate what happens with wrapping) query TT @@ -519,6 +528,95 @@ physical_plan 17)│ format: arrow │ 18)└───────────────────────────┘ +# Query with hash join. +query TT +explain select * from table1 inner join table2 on table1.int_col = table2.int_col and table1.string_col = table2.string_col; +---- +logical_plan +01)Inner Join: table1.int_col = table2.int_col, CAST(table1.string_col AS Utf8View) = table2.string_col +02)--TableScan: table1 projection=[int_col, string_col, bigint_col, date_col] +03)--TableScan: table2 projection=[int_col, string_col, bigint_col, date_col] +physical_plan +01)┌───────────────────────────┐ +02)│ CoalesceBatchesExec │ +03)└─────────────┬─────────────┘ +04)┌─────────────┴─────────────┐ +05)│ HashJoinExec │ +06)│ -------------------- │ +07)│ on: │ +08)│ (int_col@0 = int_col@0), ├──────────────┐ +09)│ (CAST(table1.string_col │ │ +10)│ AS Utf8View)@4 = │ │ +11)│ string_col@1) │ │ +12)└─────────────┬─────────────┘ │ +13)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ +14)│ CoalesceBatchesExec ││ CoalesceBatchesExec │ +15)└─────────────┬─────────────┘└─────────────┬─────────────┘ +16)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ +17)│ RepartitionExec ││ RepartitionExec │ +18)└─────────────┬─────────────┘└─────────────┬─────────────┘ +19)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ +20)│ ProjectionExec ││ RepartitionExec │ +21)└─────────────┬─────────────┘└─────────────┬─────────────┘ +22)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ +23)│ RepartitionExec ││ DataSourceExec │ +24)│ ││ -------------------- │ +25)│ ││ files: 1 │ +26)│ ││ format: parquet │ +27)└─────────────┬─────────────┘└───────────────────────────┘ +28)┌─────────────┴─────────────┐ +29)│ DataSourceExec │ +30)│ -------------------- │ +31)│ files: 1 │ +32)│ format: csv │ +33)└───────────────────────────┘ + +# Query with outer hash join. +query TT +explain select * from table1 left outer join table2 on table1.int_col = table2.int_col and table1.string_col = table2.string_col; +---- +logical_plan +01)Left Join: table1.int_col = table2.int_col, CAST(table1.string_col AS Utf8View) = table2.string_col +02)--TableScan: table1 projection=[int_col, string_col, bigint_col, date_col] +03)--TableScan: table2 projection=[int_col, string_col, bigint_col, date_col] +physical_plan +01)┌───────────────────────────┐ +02)│ CoalesceBatchesExec │ +03)└─────────────┬─────────────┘ +04)┌─────────────┴─────────────┐ +05)│ HashJoinExec │ +06)│ -------------------- │ +07)│ join_type: Left │ +08)│ │ +09)│ on: ├──────────────┐ +10)│ (int_col@0 = int_col@0), │ │ +11)│ (CAST(table1.string_col │ │ +12)│ AS Utf8View)@4 = │ │ +13)│ string_col@1) │ │ +14)└─────────────┬─────────────┘ │ +15)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ +16)│ CoalesceBatchesExec ││ CoalesceBatchesExec │ +17)└─────────────┬─────────────┘└─────────────┬─────────────┘ +18)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ +19)│ RepartitionExec ││ RepartitionExec │ +20)└─────────────┬─────────────┘└─────────────┬─────────────┘ +21)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ +22)│ ProjectionExec ││ RepartitionExec │ +23)└─────────────┬─────────────┘└─────────────┬─────────────┘ +24)┌─────────────┴─────────────┐┌─────────────┴─────────────┐ +25)│ RepartitionExec ││ DataSourceExec │ +26)│ ││ -------------------- │ +27)│ ││ files: 1 │ +28)│ ││ format: parquet │ +29)└─────────────┬─────────────┘└───────────────────────────┘ +30)┌─────────────┴─────────────┐ +31)│ DataSourceExec │ +32)│ -------------------- │ +33)│ files: 1 │ +34)│ format: csv │ +35)└───────────────────────────┘ + + # cleanup statement ok drop table table1;