Skip to content
This repository was archived by the owner on Jan 7, 2025. It is now read-only.

Commit cddb6e2

Browse files
committed
fix(core): handle winners when merging groups
Signed-off-by: Alex Chi Z <[email protected]>
1 parent edd5d2f commit cddb6e2

File tree

3 files changed

+71
-57
lines changed

3 files changed

+71
-57
lines changed

optd-core/src/cascades/memo.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -407,14 +407,29 @@ impl<T: NodeType> NaiveMemo<T> {
407407
trace!(event = "merge_group", merge_into = %merge_into, merge_from = %merge_from);
408408
let group_merge_from = self.groups.remove(&merge_from).unwrap();
409409
let group_merge_into = self.groups.get_mut(&merge_into).unwrap();
410-
// TODO: update winner, cost and properties
410+
411+
// Merge expressions
411412
for from_expr in group_merge_from.group_exprs {
412413
let ret = self.expr_id_to_group_id.insert(from_expr, merge_into);
413414
assert!(ret.is_some());
414415
group_merge_into.group_exprs.insert(from_expr);
415416
}
416417
self.merged_group_mapping.insert(merge_from, merge_into);
417418

419+
// Merge winner
420+
if let Some(winner) = group_merge_from.info.winner.as_full_winner() {
421+
match &group_merge_into.info.winner {
422+
Winner::Impossible | Winner::Unknown => {
423+
group_merge_into.info.winner = Winner::Full(winner.clone());
424+
}
425+
Winner::Full(winner_into) => {
426+
if winner.total_weighted_cost < winner_into.total_weighted_cost {
427+
group_merge_into.info.winner = Winner::Full(winner.clone());
428+
}
429+
}
430+
}
431+
}
432+
418433
// Update all indexes and other data structures
419434
// 1. update merged group mapping -- could be optimized with union find
420435
for (_, mapped_to) in self.merged_group_mapping.iter_mut() {

optd-sqlplannertest/tests/joins/join_enumerate.planner.sql

+6-5
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,12 @@ PhysicalHashJoin { join_type: Inner, left_keys: [ #1 ], right_keys: [ #0 ] }
132132
(Join (Join t3 t1) t2)
133133
(Join (Join t3 t2) t1)
134134
135-
PhysicalHashJoin { join_type: Inner, left_keys: [ #1 ], right_keys: [ #0 ] }
136-
├── PhysicalHashJoin { join_type: Inner, left_keys: [ #0 ], right_keys: [ #0 ] }
137-
│ ├── PhysicalScan { table: t1 }
138-
│ └── PhysicalScan { table: t2 }
139-
└── PhysicalScan { table: t3 }
135+
PhysicalProjection { exprs: [ #4, #5, #0, #1, #2, #3 ] }
136+
└── PhysicalHashJoin { join_type: Inner, left_keys: [ #0 ], right_keys: [ #2 ] }
137+
├── PhysicalScan { table: t2 }
138+
└── PhysicalHashJoin { join_type: Inner, left_keys: [ #0 ], right_keys: [ #1 ] }
139+
├── PhysicalScan { table: t3 }
140+
└── PhysicalScan { table: t1 }
140141
0 0 0 200 0 300
141142
1 1 1 201 1 301
142143
2 2 2 202 2 302

optd-sqlplannertest/tests/tpch/q17.planner.sql

+49-51
Original file line numberDiff line numberDiff line change
@@ -75,57 +75,55 @@ PhysicalProjection
7575
│ └── [ #5 ]
7676
├── groups: []
7777
└── 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 ] }
78-
└── 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 ] }
79-
└── PhysicalNestedLoopJoin
80-
├── join_type: Inner
81-
├── cond:And
82-
│ ├── Eq
83-
│ │ ├── #2
84-
│ │ └── #12
85-
│ └── Lt
86-
│ ├── Cast { cast_to: Decimal128(30, 15), child: #15 }
87-
│ └── #1
88-
├── PhysicalProjection { exprs: [ #9, #10, #0, #1, #2, #3, #4, #5, #6, #7, #8 ] }
89-
│ └── PhysicalHashJoin { join_type: Inner, left_keys: [ #0 ], right_keys: [ #0 ] }
90-
│ ├── PhysicalFilter
91-
│ │ ├── cond:And
92-
│ │ │ ├── Eq
93-
│ │ │ │ ├── #3
94-
│ │ │ │ └── "Brand#13"
95-
│ │ │ └── Eq
96-
│ │ │ ├── #6
97-
│ │ │ └── "JUMBO PKG"
98-
│ │ └── PhysicalScan { table: part }
99-
│ └── PhysicalProjection
100-
│ ├── exprs:
101-
│ │ ┌── #0
102-
│ │ └── Cast
103-
│ │ ├── cast_to: Decimal128(30, 15)
104-
│ │ ├── child:Mul
105-
│ │ │ ├── 0.2(float)
106-
│ │ │ └── Cast { cast_to: Float64, child: #1 }
78+
└── PhysicalNestedLoopJoin
79+
├── join_type: Inner
80+
├── cond:And
81+
│ ├── Eq
82+
│ │ ├── #16
83+
│ │ └── #1
84+
│ └── Lt
85+
│ ├── Cast { cast_to: Decimal128(30, 15), child: #4 }
86+
│ └── #26
87+
├── PhysicalScan { table: lineitem }
88+
└── PhysicalHashJoin { join_type: Inner, left_keys: [ #0 ], right_keys: [ #0 ] }
89+
├── PhysicalFilter
90+
│ ├── cond:And
91+
│ │ ├── Eq
92+
│ │ │ ├── #3
93+
│ │ │ └── "Brand#13"
94+
│ │ └── Eq
95+
│ │ ├── #6
96+
│ │ └── "JUMBO PKG"
97+
│ └── PhysicalScan { table: part }
98+
└── PhysicalProjection
99+
├── exprs:
100+
│ ┌── #0
101+
│ └── Cast
102+
│ ├── cast_to: Decimal128(30, 15)
103+
│ ├── child:Mul
104+
│ │ ├── 0.2(float)
105+
│ │ └── Cast { cast_to: Float64, child: #1 }
107106
108-
│ └── PhysicalProjection { exprs: [ #0, #2 ] }
109-
│ └── PhysicalNestedLoopJoin
110-
│ ├── join_type: LeftOuter
111-
│ ├── cond:And
112-
│ │ └── Eq
113-
│ │ ├── #0
114-
│ │ └── #1
115-
│ ├── PhysicalAgg { aggrs: [], groups: [ #16 ] }
116-
│ │ └── PhysicalNestedLoopJoin { join_type: Inner, cond: true }
117-
│ │ ├── PhysicalScan { table: lineitem }
118-
│ │ └── PhysicalScan { table: part }
119-
│ └── PhysicalAgg
120-
│ ├── aggrs:Agg(Avg)
121-
│ │ └── [ #5 ]
122-
│ ├── groups: [ #0 ]
123-
│ └── PhysicalHashJoin { join_type: Inner, left_keys: [ #0 ], right_keys: [ #1 ] }
124-
│ ├── PhysicalAgg { aggrs: [], groups: [ #16 ] }
125-
│ │ └── PhysicalNestedLoopJoin { join_type: Inner, cond: true }
126-
│ │ ├── PhysicalScan { table: lineitem }
127-
│ │ └── PhysicalScan { table: part }
128-
│ └── PhysicalScan { table: lineitem }
129-
└── PhysicalScan { table: lineitem }
107+
└── PhysicalProjection { exprs: [ #0, #2 ] }
108+
└── PhysicalNestedLoopJoin
109+
├── join_type: LeftOuter
110+
├── cond:And
111+
│ └── Eq
112+
│ ├── #0
113+
│ └── #1
114+
├── PhysicalAgg { aggrs: [], groups: [ #16 ] }
115+
│ └── PhysicalNestedLoopJoin { join_type: Inner, cond: true }
116+
│ ├── PhysicalScan { table: lineitem }
117+
│ └── PhysicalScan { table: part }
118+
└── PhysicalAgg
119+
├── aggrs:Agg(Avg)
120+
│ └── [ #5 ]
121+
├── groups: [ #0 ]
122+
└── PhysicalHashJoin { join_type: Inner, left_keys: [ #0 ], right_keys: [ #1 ] }
123+
├── PhysicalAgg { aggrs: [], groups: [ #16 ] }
124+
│ └── PhysicalNestedLoopJoin { join_type: Inner, cond: true }
125+
│ ├── PhysicalScan { table: lineitem }
126+
│ └── PhysicalScan { table: part }
127+
└── PhysicalScan { table: lineitem }
130128
*/
131129

0 commit comments

Comments
 (0)