Skip to content

Commit db18683

Browse files
committed
chore: codefmt
1 parent 5f2efb2 commit db18683

File tree

4 files changed

+72
-50
lines changed

4 files changed

+72
-50
lines changed

src/query/service/src/physical_plans/physical_join.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use databend_common_exception::{ErrorCode, Result};
15+
use databend_common_exception::ErrorCode;
16+
use databend_common_exception::Result;
1617
use databend_common_sql::binder::JoinPredicate;
1718
use databend_common_sql::optimizer::ir::RelExpr;
1819
use databend_common_sql::optimizer::ir::RelationalProperty;
@@ -40,10 +41,12 @@ pub fn physical_join(join: &Join, s_expr: &SExpr) -> Result<PhysicalJoinType> {
4041
JoinType::Asof | JoinType::LeftAsof | JoinType::RightAsof
4142
);
4243

43-
if join.equi_conditions.is_empty() && (join.join_type.is_any_join() || join.join_type == JoinType::Cross(true)) {
44+
if join.equi_conditions.is_empty()
45+
&& (join.join_type.is_any_join() || join.join_type == JoinType::Cross(true))
46+
{
4447
return Err(ErrorCode::SemanticError(
4548
"ANY JOIN only supports equality-based hash joins",
46-
))
49+
));
4750
}
4851
if !join.equi_conditions.is_empty() && !check_asof {
4952
// Contain equi condition, use hash join

src/query/service/tests/it/sql/planner/optimizer/ir/expr/visitor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ fn create_complex_expr() -> SExpr {
7676
let join_condition = builder.join_condition(t1_id, t2_id, false);
7777

7878
// Create JOIN node
79-
let joined = builder.join(scan1, scan2, vec![join_condition], JoinType::Inner);
79+
let joined = builder.join(scan1, scan2, vec![join_condition], JoinType::Inner(false));
8080

8181
// Add WHERE filter condition (simplified as boolean constant)
8282
let where_condition = builder.bool(true);

src/query/service/tests/it/sql/planner/optimizer/optimizers/operator/filter/deduplicate_join_condition_test.rs

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -244,12 +244,12 @@ fn test_basic_deduplication() -> Result<()> {
244244
let cond_t2_t3 = builder.join_condition(t2_id.clone(), t3_id.clone(), false);
245245

246246
// Create the join tree: (t3 JOIN (t1 JOIN t2))
247-
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Inner);
247+
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Inner(false));
248248
let join_tree = builder.join(
249249
t3,
250250
join_t1_t2,
251251
vec![cond_t1_t3.clone(), cond_t2_t3.clone()],
252-
JoinType::Inner,
252+
JoinType::Inner(false),
253253
);
254254

255255
// Define expected before optimization patterns
@@ -336,12 +336,12 @@ fn test_different_data_types() -> Result<()> {
336336
let cond_t1_t3 = builder.join_condition(t1_id.clone(), t3_id.clone(), false);
337337

338338
// Create the join tree: ((t1 JOIN t2) JOIN t3)
339-
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Inner);
339+
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Inner(false));
340340
let join_tree = builder.join(
341341
join_t1_t2,
342342
t3,
343343
vec![cond_t2_t3.clone(), cond_t1_t3.clone()],
344-
JoinType::Inner,
344+
JoinType::Inner(false),
345345
);
346346

347347
// Define expected before optimization patterns
@@ -430,7 +430,7 @@ fn test_no_redundant_conditions() -> Result<()> {
430430
let cond_name = builder.join_condition(t1_name.clone(), t2_name.clone(), false);
431431

432432
// Create the join
433-
let join = builder.join(t1, t2, vec![cond_id, cond_name], JoinType::Inner);
433+
let join = builder.join(t1, t2, vec![cond_id, cond_name], JoinType::Inner(false));
434434

435435
// Define expected before optimization patterns
436436
let before_patterns = [
@@ -545,18 +545,18 @@ fn test_complex_transitive_conditions() -> Result<()> {
545545
let cond_t1_t4 = builder.join_condition(t1_id.clone(), t4_id.clone(), false); // Redundant: t1-t2-t3-t4
546546

547547
// Create a complex join tree: (((t1 JOIN t2) JOIN t3) JOIN t4)
548-
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Inner);
548+
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Inner(false));
549549
let join_t1_t2_t3 = builder.join(
550550
join_t1_t2,
551551
t3,
552552
vec![cond_t2_t3, cond_t1_t3],
553-
JoinType::Inner,
553+
JoinType::Inner(false),
554554
);
555555
let join_tree = builder.join(
556556
join_t1_t2_t3,
557557
t4,
558558
vec![cond_t3_t4, cond_t2_t4, cond_t1_t4],
559-
JoinType::Inner,
559+
JoinType::Inner(false),
560560
);
561561

562562
// Define expected before optimization patterns
@@ -660,12 +660,12 @@ fn test_null_equal_conditions() -> Result<()> {
660660
let cond_t1_t3 = builder.join_condition(t1_id.clone(), t3_id.clone(), true); // Redundant
661661

662662
// Create the join tree: (t1 JOIN t2) JOIN t3
663-
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Inner);
663+
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Inner(false));
664664
let join_tree = builder.join(
665665
join_t1_t2,
666666
t3,
667667
vec![cond_t2_t3, cond_t1_t3],
668-
JoinType::Inner,
668+
JoinType::Inner(false),
669669
);
670670

671671
// Define expected before optimization patterns
@@ -764,12 +764,12 @@ fn test_mixed_null_equal_conditions() -> Result<()> {
764764
let cond_t1_t3 = builder.join_condition(t1_id.clone(), t3_id.clone(), true); // Redundant but with different is_null_equal
765765

766766
// Create the join tree: (t1 JOIN t2) JOIN t3
767-
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Inner);
767+
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Inner(false));
768768
let join_tree = builder.join(
769769
join_t1_t2,
770770
t3,
771771
vec![cond_t2_t3, cond_t1_t3],
772-
JoinType::Inner,
772+
JoinType::Inner(false),
773773
);
774774

775775
// Define expected before optimization patterns
@@ -868,8 +868,13 @@ fn test_non_inner_join_types() -> Result<()> {
868868
let cond_t1_t3 = builder.join_condition(t1_id.clone(), t3_id.clone(), false); // Redundant
869869

870870
// Create a join tree with non-inner joins
871-
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Left);
872-
let join_tree = builder.join(join_t1_t2, t3, vec![cond_t2_t3, cond_t1_t3], JoinType::Left);
871+
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Left(false));
872+
let join_tree = builder.join(
873+
join_t1_t2,
874+
t3,
875+
vec![cond_t2_t3, cond_t1_t3],
876+
JoinType::Left(false),
877+
);
873878

874879
// Define expected before optimization patterns
875880
let before_patterns = [
@@ -970,7 +975,7 @@ fn test_multiple_conditions_same_tables() -> Result<()> {
970975
t1,
971976
t2,
972977
vec![cond_t1_t2_id, cond_t1_t2_name, cond_t1_t2_id_duplicate],
973-
JoinType::Inner,
978+
JoinType::Inner(false),
974979
);
975980

976981
// Define expected before optimization patterns
@@ -1020,7 +1025,7 @@ fn test_empty_conditions() -> Result<()> {
10201025
let t2 = builder.table_scan(1, "t2");
10211026

10221027
// Create a join with no conditions
1023-
let join = builder.join(t1, t2, vec![], JoinType::Inner);
1028+
let join = builder.join(t1, t2, vec![], JoinType::Inner(false));
10241029

10251030
// Define expected before optimization patterns
10261031
let before_patterns = [
@@ -1097,7 +1102,7 @@ fn test_duplicate_identical_conditions() -> Result<()> {
10971102
let cond2 = builder.join_condition(t1_id.clone(), t2_id.clone(), false); // Duplicate
10981103

10991104
// Create a join with duplicate conditions
1100-
let join = builder.join(t1, t2, vec![cond1, cond2], JoinType::Inner);
1105+
let join = builder.join(t1, t2, vec![cond1, cond2], JoinType::Inner(false));
11011106

11021107
// Define expected before optimization patterns
11031108
let before_patterns = [
@@ -1192,12 +1197,12 @@ fn test_commutative_and_circular_conditions() -> Result<()> {
11921197
let cond_t3_t1 = builder.join_condition(t3_id.clone(), t1_id.clone(), false); // Same as t1.id = t3.id but reversed
11931198

11941199
// Create a join tree
1195-
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Inner);
1200+
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Inner(false));
11961201
let join_tree = builder.join(
11971202
join_t1_t2,
11981203
t3,
11991204
vec![cond_t2_t3, cond_t3_t1],
1200-
JoinType::Inner,
1205+
JoinType::Inner(false),
12011206
);
12021207

12031208
// Define expected before optimization patterns
@@ -1327,14 +1332,15 @@ fn test_deep_nested_join_tree() -> Result<()> {
13271332
let cond_t1_t5 = builder.join_condition(t1_id.clone(), t5_id.clone(), false); // Redundant due to transitivity
13281333

13291334
// Create a deeply nested join tree: ((((t1 JOIN t2) JOIN t3) JOIN t4) JOIN t5)
1330-
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Inner);
1331-
let join_t1_t2_t3 = builder.join(join_t1_t2, t3, vec![cond_t2_t3], JoinType::Inner);
1332-
let join_t1_t2_t3_t4 = builder.join(join_t1_t2_t3, t4, vec![cond_t3_t4], JoinType::Inner);
1335+
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Inner(false));
1336+
let join_t1_t2_t3 = builder.join(join_t1_t2, t3, vec![cond_t2_t3], JoinType::Inner(false));
1337+
let join_t1_t2_t3_t4 =
1338+
builder.join(join_t1_t2_t3, t4, vec![cond_t3_t4], JoinType::Inner(false));
13331339
let join_tree = builder.join(
13341340
join_t1_t2_t3_t4,
13351341
t5,
13361342
vec![cond_t4_t5, cond_t1_t5],
1337-
JoinType::Inner,
1343+
JoinType::Inner(false),
13381344
);
13391345

13401346
// Define expected before optimization patterns
@@ -1436,8 +1442,13 @@ fn test_mixed_join_types() -> Result<()> {
14361442
let cond_t1_t3 = builder.join_condition(t1_id.clone(), t3_id.clone(), false); // Redundant
14371443

14381444
// Create a mixed join tree: (t1 INNER JOIN t2) LEFT JOIN t3
1439-
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Inner);
1440-
let join_tree = builder.join(join_t1_t2, t3, vec![cond_t2_t3, cond_t1_t3], JoinType::Left);
1445+
let join_t1_t2 = builder.join(t1, t2, vec![cond_t1_t2], JoinType::Inner(false));
1446+
let join_tree = builder.join(
1447+
join_t1_t2,
1448+
t3,
1449+
vec![cond_t2_t3, cond_t1_t3],
1450+
JoinType::Left(false),
1451+
);
14411452

14421453
// Define expected before optimization patterns
14431454
let before_patterns = [

src/query/service/tests/it/sql/planner/optimizer/optimizers/rule/filter_rules/push_down_filter_join_test.rs

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,14 @@ fn sexpr_to_string(s_expr: &SExpr) -> String {
139139
}
140140
RelOperator::Join(join) => {
141141
let join_type = match join.join_type {
142-
JoinType::Inner => "Inner",
143-
JoinType::Left => "Left",
144-
JoinType::Right => "Right",
142+
JoinType::Inner(false) => "Inner",
143+
JoinType::Inner(true) => "InnerAny",
144+
JoinType::Left(false) => "Left",
145+
JoinType::Left(true) => "LeftAny",
146+
JoinType::Right(false) => "Right",
147+
JoinType::Right(true) => "RightAny",
145148
JoinType::Full => "Full",
146-
JoinType::Cross => "Cross",
149+
JoinType::Cross(_) => "Cross",
147150
JoinType::LeftSemi => "LeftSemi",
148151
JoinType::RightSemi => "RightSemi",
149152
JoinType::LeftAnti => "LeftAnti",
@@ -288,7 +291,7 @@ fn run_join_filter_test(test_case: &JoinFilterTestCase, metadata: &MetadataRef)
288291
println!("Actual after pattern:\n{}", normalized_after);
289292

290293
// Special handling for RIGHT JOIN which might be converted to INNER JOIN
291-
if test_case.join_type == JoinType::Right {
294+
if matches!(test_case.join_type, JoinType::Right(_)) {
292295
// Check if filter was pushed down correctly even if join type changed
293296
let expected_filter_pushed =
294297
normalized_after_expected.contains("Filter") && normalized_after.contains("Filter");
@@ -420,7 +423,7 @@ fn test_push_down_filter_left_join() -> Result<()> {
420423
description: "Tests that a filter on the right table join key converts LEFT JOIN to INNER JOIN",
421424
sql_example: "SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id WHERE t2.id > 10",
422425
filter_expr: right_id_filter.clone(),
423-
join_type: JoinType::Left,
426+
join_type: JoinType::Left(false),
424427
before_pattern: r#"
425428
Filter [t2.id > 10]
426429
Left Join [t1.id = t2.id]
@@ -441,7 +444,7 @@ fn test_push_down_filter_left_join() -> Result<()> {
441444
description: "Tests that a complex filter with multiple conditions is handled correctly",
442445
sql_example: "SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id WHERE t2.id > 10 AND t2.value < 100",
443446
filter_expr: right_combined_filter.clone(),
444-
join_type: JoinType::Left,
447+
join_type: JoinType::Left(false),
445448
before_pattern: r#"
446449
Filter [and(t2.id > 10, t2.value < 100)]
447450
Left Join [t1.id = t2.id]
@@ -461,7 +464,7 @@ fn test_push_down_filter_left_join() -> Result<()> {
461464
description: "Tests that a filter on a non-join column of the right table converts LEFT JOIN to INNER JOIN",
462465
sql_example: "SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id WHERE t2.value < 100",
463466
filter_expr: right_value_filter.clone(),
464-
join_type: JoinType::Left,
467+
join_type: JoinType::Left(false),
465468
before_pattern: r#"
466469
Filter [t2.value < 100]
467470
Left Join [t1.id = t2.id]
@@ -481,7 +484,7 @@ fn test_push_down_filter_left_join() -> Result<()> {
481484
description: "Tests that an IS NULL filter on the right table is handled correctly in LEFT JOIN",
482485
sql_example: "SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id WHERE t2.id IS NULL",
483486
filter_expr: is_null_filter.clone(),
484-
join_type: JoinType::Left,
487+
join_type: JoinType::Left(false),
485488
before_pattern: r#"
486489
Filter [t2.id = Null]
487490
Left Join [t1.id = t2.id]
@@ -502,7 +505,7 @@ fn test_push_down_filter_left_join() -> Result<()> {
502505
description: "Tests that an IS NOT NULL filter on the right table converts LEFT JOIN to INNER JOIN",
503506
sql_example: "SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id WHERE t2.id IS NOT NULL",
504507
filter_expr: is_not_null_filter.clone(),
505-
join_type: JoinType::Left,
508+
join_type: JoinType::Left(false),
506509
before_pattern: r#"
507510
Filter [noteq(t2.id, Null)]
508511
Left Join [t1.id = t2.id]
@@ -523,7 +526,7 @@ fn test_push_down_filter_left_join() -> Result<()> {
523526
description: "Tests a complex OR filter with multiple conditions on the right table (TPC-DS query 13 pattern)",
524527
sql_example: "SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id WHERE (t2.id > 10 AND t2.value < 50) OR (t2.id > 20 AND t2.qty < 100)",
525528
filter_expr: complex_or_filter.clone(),
526-
join_type: JoinType::Left,
529+
join_type: JoinType::Left(false),
527530
before_pattern: r#"
528531
Filter [or(and(t2.id > 10, t2.value < 50), and(t2.id > 20, t2.qty < 100))]
529532
Left Join [t1.id = t2.id]
@@ -544,7 +547,7 @@ fn test_push_down_filter_left_join() -> Result<()> {
544547
description: "Tests a complex filter with AND-OR conditions including a date filter (TPC-DS query 72 pattern)",
545548
sql_example: "SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id WHERE ((t2.id > 10 AND t2.value < 50) OR (t2.id > 20 AND t2.qty < 100)) AND t2.date > 200",
546549
filter_expr: complex_and_or_filter.clone(),
547-
join_type: JoinType::Left,
550+
join_type: JoinType::Left(false),
548551
before_pattern: r#"
549552
Filter [and(or(and(t2.id > 10, t2.value < 50), and(t2.id > 20, t2.qty < 100)), t2.date > 200)]
550553
Left Join [t1.id = t2.id]
@@ -564,7 +567,7 @@ fn test_push_down_filter_left_join() -> Result<()> {
564567
description: "Tests a filter with an IF function (similar to CASE expression in TPC-DS query 72 pattern)",
565568
sql_example: "SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id WHERE IF(t2.id = 10, 1, 0) > 0",
566569
filter_expr: case_filter.clone(),
567-
join_type: JoinType::Left,
570+
join_type: JoinType::Left(false),
568571
before_pattern: r#"
569572
Filter [if(t2.id = 10, 1, 0) > 0]
570573
Left Join [t1.id = t2.id]
@@ -689,7 +692,7 @@ fn test_push_down_filter_right_join() -> Result<()> {
689692
description: "Tests that a filter on the left table is pushed down in RIGHT JOIN",
690693
sql_example: "SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id WHERE t1.a > 10",
691694
filter_expr: left_a_filter.clone(),
692-
join_type: JoinType::Right,
695+
join_type: JoinType::Right(false),
693696
before_pattern: r#"
694697
Filter [t1.a > 10]
695698
Right Join [t1.id = t2.id]
@@ -709,7 +712,7 @@ fn test_push_down_filter_right_join() -> Result<()> {
709712
description: "Tests that a complex filter with multiple conditions on left table is handled correctly",
710713
sql_example: "SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id WHERE t1.a > 10 AND t1.value < 100",
711714
filter_expr: left_combined_filter.clone(),
712-
join_type: JoinType::Right,
715+
join_type: JoinType::Right(false),
713716
before_pattern: r#"
714717
Filter [and(t1.a > 10, t1.value < 100)]
715718
Right Join [t1.id = t2.id]
@@ -729,7 +732,7 @@ fn test_push_down_filter_right_join() -> Result<()> {
729732
description: "Tests that an IS NULL filter on the left table is handled correctly in RIGHT JOIN",
730733
sql_example: "SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id WHERE t1.a IS NULL",
731734
filter_expr: is_null_filter.clone(),
732-
join_type: JoinType::Right,
735+
join_type: JoinType::Right(false),
733736
before_pattern: r#"
734737
Filter [t1.a = Null]
735738
Right Join [t1.id = t2.id]
@@ -749,7 +752,7 @@ fn test_push_down_filter_right_join() -> Result<()> {
749752
description: "Tests that an IS NOT NULL filter on the left table is handled correctly in RIGHT JOIN",
750753
sql_example: "SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id WHERE t1.a IS NOT NULL",
751754
filter_expr: is_not_null_filter.clone(),
752-
join_type: JoinType::Right,
755+
join_type: JoinType::Right(false),
753756
before_pattern: r#"
754757
Filter [noteq(t1.a, Null)]
755758
Right Join [t1.id = t2.id]
@@ -769,7 +772,7 @@ fn test_push_down_filter_right_join() -> Result<()> {
769772
description: "Tests a complex OR filter with multiple conditions on the left table",
770773
sql_example: "SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id WHERE (t1.a > 10 AND t1.value < 50) OR (t1.a > 20 AND t1.qty < 100)",
771774
filter_expr: complex_or_filter.clone(),
772-
join_type: JoinType::Right,
775+
join_type: JoinType::Right(false),
773776
before_pattern: r#"
774777
Filter [or(and(t1.a > 10, t1.value < 50), and(t1.a > 20, t1.qty < 100))]
775778
Right Join [t1.id = t2.id]
@@ -790,7 +793,7 @@ fn test_push_down_filter_right_join() -> Result<()> {
790793
description: "Tests a complex filter with AND-OR conditions including a date filter on left table",
791794
sql_example: "SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id WHERE ((t1.a > 10 AND t1.value < 50) OR (t1.a > 20 AND t1.qty < 100)) AND t1.date > 200",
792795
filter_expr: complex_and_or_filter.clone(),
793-
join_type: JoinType::Right,
796+
join_type: JoinType::Right(false),
794797
before_pattern: r#"
795798
Filter [and(or(and(t1.a > 10, t1.value < 50), and(t1.a > 20, t1.qty < 100)), t1.date > 200)]
796799
Right Join [t1.id = t2.id]
@@ -810,7 +813,7 @@ fn test_push_down_filter_right_join() -> Result<()> {
810813
description: "Tests a filter with an IF function on left table",
811814
sql_example: "SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id WHERE IF(t1.a = 10, 1, 0) > 0",
812815
filter_expr: case_filter.clone(),
813-
join_type: JoinType::Right,
816+
join_type: JoinType::Right(false),
814817
before_pattern: r#"
815818
Filter [if(t1.a = 10, 1, 0) > 0]
816819
Right Join [t1.id = t2.id]
@@ -1158,7 +1161,12 @@ fn test_push_down_complex_or_expressions() -> Result<()> {
11581161

11591162
// Create join
11601163
// SQL: FROM t1 INNER JOIN t2 ON t1.id = t2.id
1161-
let join = builder.join(left_scan, right_scan, vec![join_condition], JoinType::Inner);
1164+
let join = builder.join(
1165+
left_scan,
1166+
right_scan,
1167+
vec![join_condition],
1168+
JoinType::Inner(false),
1169+
);
11621170

11631171
// Create filter
11641172
// SQL: SELECT * FROM t1 INNER JOIN t2 ON t1.id = t2.id

0 commit comments

Comments
 (0)