diff --git a/core/translate/planner.rs b/core/translate/planner.rs index 226768d05..b5a696b36 100644 --- a/core/translate/planner.rs +++ b/core/translate/planner.rs @@ -597,133 +597,17 @@ impl TableMask { /// Returns a [TableMask] representing the tables referenced in the given expression. /// Used in the optimizer for constraint analysis. -pub fn table_mask_from_expr(expr: &Expr) -> Result { +pub fn table_mask_from_expr(top_level_expr: &Expr) -> Result { let mut mask = TableMask::new(); - match expr { - Expr::Binary(e1, _, e2) => { - mask |= table_mask_from_expr(e1)?; - mask |= table_mask_from_expr(e2)?; - } - Expr::Column { table, .. } | Expr::RowId { table, .. } => { - mask.add_table(*table); - } - Expr::Between { - lhs, - not: _, - start, - end, - } => { - mask |= table_mask_from_expr(lhs)?; - mask |= table_mask_from_expr(start)?; - mask |= table_mask_from_expr(end)?; - } - Expr::Case { - base, - when_then_pairs, - else_expr, - } => { - if let Some(base) = base { - mask |= table_mask_from_expr(base)?; - } - for (when, then) in when_then_pairs { - mask |= table_mask_from_expr(when)?; - mask |= table_mask_from_expr(then)?; - } - if let Some(else_expr) = else_expr { - mask |= table_mask_from_expr(else_expr)?; + walk_expr(top_level_expr, &mut |expr: &Expr| -> Result<()> { + match expr { + Expr::Column { table, .. } | Expr::RowId { table, .. } => { + mask.add_table(*table); } + _ => {} } - Expr::Cast { expr, .. } => { - mask |= table_mask_from_expr(expr)?; - } - Expr::Collate(expr, _) => { - mask |= table_mask_from_expr(expr)?; - } - Expr::DoublyQualified(_, _, _) => { - crate::bail_parse_error!( - "DoublyQualified should be resolved to a Column before resolving table mask" - ); - } - Expr::Exists(_) => { - todo!(); - } - Expr::FunctionCall { - args, - order_by, - filter_over: _, - .. - } => { - if let Some(args) = args { - for arg in args.iter() { - mask |= table_mask_from_expr(arg)?; - } - } - if let Some(order_by) = order_by { - for term in order_by.iter() { - mask |= table_mask_from_expr(&term.expr)?; - } - } - } - Expr::FunctionCallStar { .. } => {} - Expr::Id(_) => panic!("Id should be resolved to a Column before resolving table mask"), - Expr::InList { lhs, not: _, rhs } => { - mask |= table_mask_from_expr(lhs)?; - if let Some(rhs) = rhs { - for rhs_expr in rhs.iter() { - mask |= table_mask_from_expr(rhs_expr)?; - } - } - } - Expr::InSelect { .. } => todo!(), - Expr::InTable { - lhs, - not: _, - rhs: _, - args, - } => { - mask |= table_mask_from_expr(lhs)?; - if let Some(args) = args { - for arg in args.iter() { - mask |= table_mask_from_expr(arg)?; - } - } - } - Expr::IsNull(expr) => { - mask |= table_mask_from_expr(expr)?; - } - Expr::Like { - lhs, - not: _, - op: _, - rhs, - escape, - } => { - mask |= table_mask_from_expr(lhs)?; - mask |= table_mask_from_expr(rhs)?; - if let Some(escape) = escape { - mask |= table_mask_from_expr(escape)?; - } - } - Expr::Literal(_) => {} - Expr::Name(_) => {} - Expr::NotNull(expr) => { - mask |= table_mask_from_expr(expr)?; - } - Expr::Parenthesized(exprs) => { - for expr in exprs.iter() { - mask |= table_mask_from_expr(expr)?; - } - } - Expr::Qualified(_, _) => { - panic!("Qualified should be resolved to a Column before resolving table mask"); - } - Expr::Raise(_, _) => todo!(), - Expr::Subquery(_) => todo!(), - Expr::Unary(_, expr) => { - mask |= table_mask_from_expr(expr)?; - } - Expr::Variable(_) => {} - } + Ok(()) + })?; Ok(mask) }