You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by al...@apache.org on 2025/03/08 13:04:03 UTC

(datafusion) branch main updated: Implement `tree` explain for `HashJoinExec` (#15079)

This is an automated email from the ASF dual-hosted git repository.

alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git


The following commit(s) were added to refs/heads/main by this push:
     new b0d37369d5 Implement `tree` explain for `HashJoinExec` (#15079)
b0d37369d5 is described below

commit b0d37369d5a1f530d4ada2eae8def8e817749537
Author: irenjj <re...@gmail.com>
AuthorDate: Sat Mar 8 21:03:59 2025 +0800

    Implement `tree` explain for `HashJoinExec` (#15079)
    
    * Implement `tree` explain for `HashJoinExec`
    
    * fix issues
    
    * fix join type
---
 datafusion/physical-plan/src/joins/hash_join.rs    |  13 +-
 .../sqllogictest/test_files/explain_tree.slt       | 170 ++++++++++++++++-----
 2 files changed, 145 insertions(+), 38 deletions(-)

diff --git a/datafusion/physical-plan/src/joins/hash_join.rs b/datafusion/physical-plan/src/joins/hash_join.rs
index f949c408ca..39a1503726 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::<Vec<String>>()
+                    .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 9659bdae19..fb34d3ec1c 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;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org