mirror of
https://github.com/aljazceru/turso.git
synced 2026-01-27 11:54:30 +01:00
Merge 'optimizer: convert outer join to inner join if possible' from Jussi Saurio
Convert `LEFT JOIN` to `INNER JOIN` when the result of `LEFT JOIN` can never be different from the result of an `INNER JOIN` This is useful because 1. it uses less instructions and 2. it allows for join reordering due to inner join commutativity Reviewed-by: Preston Thorpe <preston@turso.tech> Closes #2972
This commit is contained in:
@@ -190,6 +190,34 @@ fn optimize_table_access(
|
||||
let maybe_order_target = compute_order_target(order_by, group_by.as_mut());
|
||||
let constraints_per_table =
|
||||
constraints_from_where_clause(where_clause, table_references, available_indexes)?;
|
||||
|
||||
// Currently the expressions we evaluate as constraints are binary expressions that will never be true for a NULL operand.
|
||||
// If there are any constraints on the right hand side table of an outer join that are not part of the outer join condition,
|
||||
// the outer join can be converted into an inner join.
|
||||
// for example:
|
||||
// - SELECT * FROM t1 LEFT JOIN t2 ON false WHERE t2.id = 5
|
||||
// there can never be a situation where null columns are emitted for t2 because t2.id = 5 will never be true in that case.
|
||||
// hence: we can convert the outer join into an inner join.
|
||||
for (i, t) in table_references
|
||||
.joined_tables_mut()
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.filter(|(_, t)| {
|
||||
t.join_info
|
||||
.as_ref()
|
||||
.is_some_and(|join_info| join_info.outer)
|
||||
})
|
||||
{
|
||||
if constraints_per_table[i]
|
||||
.constraints
|
||||
.iter()
|
||||
.any(|c| where_clause[c.where_clause_pos.0].from_outer_join.is_none())
|
||||
{
|
||||
t.join_info.as_mut().unwrap().outer = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let Some(best_join_order_result) = compute_best_join_order(
|
||||
table_references.joined_tables_mut(),
|
||||
maybe_order_target.as_ref(),
|
||||
|
||||
Reference in New Issue
Block a user