Skip to content

Commit

Permalink
fix(core): handle winners when merging groups
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Chi Z <[email protected]>
  • Loading branch information
skyzh committed Dec 19, 2024
1 parent edd5d2f commit cddb6e2
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 57 deletions.
17 changes: 16 additions & 1 deletion optd-core/src/cascades/memo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,14 +407,29 @@ impl<T: NodeType> NaiveMemo<T> {
trace!(event = "merge_group", merge_into = %merge_into, merge_from = %merge_from);
let group_merge_from = self.groups.remove(&merge_from).unwrap();
let group_merge_into = self.groups.get_mut(&merge_into).unwrap();
// TODO: update winner, cost and properties

// Merge expressions
for from_expr in group_merge_from.group_exprs {
let ret = self.expr_id_to_group_id.insert(from_expr, merge_into);
assert!(ret.is_some());
group_merge_into.group_exprs.insert(from_expr);
}
self.merged_group_mapping.insert(merge_from, merge_into);

// Merge winner
if let Some(winner) = group_merge_from.info.winner.as_full_winner() {
match &group_merge_into.info.winner {
Winner::Impossible | Winner::Unknown => {
group_merge_into.info.winner = Winner::Full(winner.clone());
}
Winner::Full(winner_into) => {
if winner.total_weighted_cost < winner_into.total_weighted_cost {
group_merge_into.info.winner = Winner::Full(winner.clone());
}
}
}
}

// Update all indexes and other data structures
// 1. update merged group mapping -- could be optimized with union find
for (_, mapped_to) in self.merged_group_mapping.iter_mut() {
Expand Down
11 changes: 6 additions & 5 deletions optd-sqlplannertest/tests/joins/join_enumerate.planner.sql
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,12 @@ PhysicalHashJoin { join_type: Inner, left_keys: [ #1 ], right_keys: [ #0 ] }
(Join (Join t3 t1) t2)
(Join (Join t3 t2) t1)
PhysicalHashJoin { join_type: Inner, left_keys: [ #1 ], right_keys: [ #0 ] }
├── PhysicalHashJoin { join_type: Inner, left_keys: [ #0 ], right_keys: [ #0 ] }
│ ├── PhysicalScan { table: t1 }
│ └── PhysicalScan { table: t2 }
└── PhysicalScan { table: t3 }
PhysicalProjection { exprs: [ #4, #5, #0, #1, #2, #3 ] }
└── PhysicalHashJoin { join_type: Inner, left_keys: [ #0 ], right_keys: [ #2 ] }
├── PhysicalScan { table: t2 }
└── PhysicalHashJoin { join_type: Inner, left_keys: [ #0 ], right_keys: [ #1 ] }
├── PhysicalScan { table: t3 }
└── PhysicalScan { table: t1 }
0 0 0 200 0 300
1 1 1 201 1 301
2 2 2 202 2 302
Expand Down
100 changes: 49 additions & 51 deletions optd-sqlplannertest/tests/tpch/q17.planner.sql
Original file line number Diff line number Diff line change
Expand Up @@ -75,57 +75,55 @@ PhysicalProjection
│ └── [ #5 ]
├── groups: []
└── PhysicalProjection { exprs: [ #0, #1, #2, #3, #4, #5, #6, #7, #8, #9, #10, #11, #12, #13, #14, #15, #16, #17, #18, #19, #20, #21, #22, #23, #24, #26 ] }
└── PhysicalProjection { exprs: [ #11, #12, #13, #14, #15, #16, #17, #18, #19, #20, #21, #22, #23, #24, #25, #26, #2, #3, #4, #5, #6, #7, #8, #9, #10, #0, #1 ] }
└── PhysicalNestedLoopJoin
├── join_type: Inner
├── cond:And
│ ├── Eq
│ │ ├── #2
│ │ └── #12
│ └── Lt
│ ├── Cast { cast_to: Decimal128(30, 15), child: #15 }
│ └── #1
├── PhysicalProjection { exprs: [ #9, #10, #0, #1, #2, #3, #4, #5, #6, #7, #8 ] }
│ └── PhysicalHashJoin { join_type: Inner, left_keys: [ #0 ], right_keys: [ #0 ] }
│ ├── PhysicalFilter
│ │ ├── cond:And
│ │ │ ├── Eq
│ │ │ │ ├── #3
│ │ │ │ └── "Brand#13"
│ │ │ └── Eq
│ │ │ ├── #6
│ │ │ └── "JUMBO PKG"
│ │ └── PhysicalScan { table: part }
│ └── PhysicalProjection
│ ├── exprs:
│ │ ┌── #0
│ │ └── Cast
│ │ ├── cast_to: Decimal128(30, 15)
│ │ ├── child:Mul
│ │ │ ├── 0.2(float)
│ │ │ └── Cast { cast_to: Float64, child: #1 }
└── PhysicalNestedLoopJoin
├── join_type: Inner
├── cond:And
│ ├── Eq
│ │ ├── #16
│ │ └── #1
│ └── Lt
│ ├── Cast { cast_to: Decimal128(30, 15), child: #4 }
│ └── #26
├── PhysicalScan { table: lineitem }
└── PhysicalHashJoin { join_type: Inner, left_keys: [ #0 ], right_keys: [ #0 ] }
├── PhysicalFilter
│ ├── cond:And
│ │ ├── Eq
│ │ │ ├── #3
│ │ │ └── "Brand#13"
│ │ └── Eq
│ │ ├── #6
│ │ └── "JUMBO PKG"
│ └── PhysicalScan { table: part }
└── PhysicalProjection
├── exprs:
│ ┌── #0
│ └── Cast
│ ├── cast_to: Decimal128(30, 15)
│ ├── child:Mul
│ │ ├── 0.2(float)
│ │ └── Cast { cast_to: Float64, child: #1 }
│ └── PhysicalProjection { exprs: [ #0, #2 ] }
│ └── PhysicalNestedLoopJoin
│ ├── join_type: LeftOuter
│ ├── cond:And
│ │ └── Eq
│ │ ├── #0
│ │ └── #1
│ ├── PhysicalAgg { aggrs: [], groups: [ #16 ] }
│ │ └── PhysicalNestedLoopJoin { join_type: Inner, cond: true }
│ │ ├── PhysicalScan { table: lineitem }
│ │ └── PhysicalScan { table: part }
│ └── PhysicalAgg
│ ├── aggrs:Agg(Avg)
│ │ └── [ #5 ]
│ ├── groups: [ #0 ]
│ └── PhysicalHashJoin { join_type: Inner, left_keys: [ #0 ], right_keys: [ #1 ] }
│ ├── PhysicalAgg { aggrs: [], groups: [ #16 ] }
│ │ └── PhysicalNestedLoopJoin { join_type: Inner, cond: true }
│ │ ├── PhysicalScan { table: lineitem }
│ │ └── PhysicalScan { table: part }
│ └── PhysicalScan { table: lineitem }
└── PhysicalScan { table: lineitem }
└── PhysicalProjection { exprs: [ #0, #2 ] }
└── PhysicalNestedLoopJoin
├── join_type: LeftOuter
├── cond:And
│ └── Eq
│ ├── #0
│ └── #1
├── PhysicalAgg { aggrs: [], groups: [ #16 ] }
│ └── PhysicalNestedLoopJoin { join_type: Inner, cond: true }
│ ├── PhysicalScan { table: lineitem }
│ └── PhysicalScan { table: part }
└── PhysicalAgg
├── aggrs:Agg(Avg)
│ └── [ #5 ]
├── groups: [ #0 ]
└── PhysicalHashJoin { join_type: Inner, left_keys: [ #0 ], right_keys: [ #1 ] }
├── PhysicalAgg { aggrs: [], groups: [ #16 ] }
│ └── PhysicalNestedLoopJoin { join_type: Inner, cond: true }
│ ├── PhysicalScan { table: lineitem }
│ └── PhysicalScan { table: part }
└── PhysicalScan { table: lineitem }
*/

0 comments on commit cddb6e2

Please sign in to comment.