From 7ab8b4798f7290c87240545e4dd23f8fcd73ddbd Mon Sep 17 00:00:00 2001 From: Gabor Gevay Date: Wed, 22 Jan 2025 15:55:33 +0100 Subject: [PATCH 1/7] Eliminate HirScalarExpr's deprecated visit_pre_post --- src/sql/src/plan/hir.rs | 22 ---------------------- src/sql/src/plan/lowering.rs | 4 ++-- 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/src/sql/src/plan/hir.rs b/src/sql/src/plan/hir.rs index 687b028f418ee..a17e9bb4303a8 100644 --- a/src/sql/src/plan/hir.rs +++ b/src/sql/src/plan/hir.rs @@ -3190,28 +3190,6 @@ impl HirScalarExpr { } } - #[deprecated = "Use `Visit::visit_pre_post` instead."] - /// A generalization of `visit`. The function `pre` runs on a - /// `HirScalarExpr` before it runs on any of the child `HirScalarExpr`s. - /// The function `post` runs on child `HirScalarExpr`s first before the - /// parent. Optionally, `pre` can return which child `HirScalarExpr`s, if - /// any, should be visited (default is to visit all children). - pub fn visit_pre_post(&self, pre: &mut F1, post: &mut F2) - where - F1: FnMut(&Self) -> Option>, - F2: FnMut(&Self), - { - let to_visit = pre(self); - if let Some(to_visit) = to_visit { - for e in to_visit { - e.visit_pre_post(pre, post); - } - } else { - self.visit1(|e| e.visit_pre_post(pre, post)); - } - post(self); - } - #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."] /// Visits the column references in this scalar expression. /// diff --git a/src/sql/src/plan/lowering.rs b/src/sql/src/plan/lowering.rs index 8ca869a598805..ce92846933228 100644 --- a/src/sql/src/plan/lowering.rs +++ b/src/sql/src/plan/lowering.rs @@ -47,6 +47,7 @@ use crate::plan::{transform_hir, PlanError}; use crate::session::vars::SystemVars; use itertools::Itertools; use mz_expr::{AccessStrategy, AggregateFunc, MirRelationExpr, MirScalarExpr}; +use mz_expr::visit::Visit; use mz_ore::collections::CollectionExt; use mz_ore::stack::maybe_grow; use mz_repr::*; @@ -1525,7 +1526,6 @@ impl HirScalarExpr { let mut subqueries = Vec::new(); let distinct_inner = get_inner.clone().distinct(); for expr in exprs.iter() { - #[allow(deprecated)] expr.visit_pre_post( &mut |e| match e { // For simplicity, subqueries within a conditional statement will be @@ -1565,7 +1565,7 @@ impl HirScalarExpr { } _ => {} }, - ); + )?; } if subqueries.is_empty() { From b999569ffd934a5602501ae1ebc32a0470a14135 Mon Sep 17 00:00:00 2001 From: Gabor Gevay Date: Wed, 22 Jan 2025 15:58:39 +0100 Subject: [PATCH 2/7] Eliminate HirScalarExpr's visit and visit1 Note that this changes a visit call to visit_pre_nolimit, which is also deprecated. The next commit will change this visit_pre_nolimit to a proper visit_pre. --- src/sql/src/plan/hir.rs | 40 ------------------------------- src/sql/src/plan/transform_hir.rs | 2 +- 2 files changed, 1 insertion(+), 41 deletions(-) diff --git a/src/sql/src/plan/hir.rs b/src/sql/src/plan/hir.rs index a17e9bb4303a8..4f3369ae262f7 100644 --- a/src/sql/src/plan/hir.rs +++ b/src/sql/src/plan/hir.rs @@ -3097,46 +3097,6 @@ impl HirScalarExpr { mem::replace(self, HirScalarExpr::literal_null(ScalarType::String)) } - pub fn visit<'a, F>(&'a self, f: &mut F) - where - F: FnMut(&'a Self), - { - self.visit1(|e: &HirScalarExpr| e.visit(f)); - f(self); - } - - pub fn visit1<'a, F>(&'a self, mut f: F) - where - F: FnMut(&'a Self), - { - use HirScalarExpr::*; - match self { - Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => (), - CallUnary { expr, .. } => f(expr), - CallBinary { expr1, expr2, .. } => { - f(expr1); - f(expr2); - } - CallVariadic { exprs, .. } => { - for expr in exprs { - f(expr); - } - } - If { cond, then, els } => { - f(cond); - f(then); - f(els); - } - Exists(..) | Select(..) => (), - Windowing(expr) => { - let _ = expr.visit_expressions(&mut |e| -> Result<(), ()> { - f(e); - Ok(()) - }); - } - } - } - #[deprecated = "Use `Visit::visit_post` instead."] pub fn visit_mut(&mut self, f: &mut F) where diff --git a/src/sql/src/plan/transform_hir.rs b/src/sql/src/plan/transform_hir.rs index 6545475f18c16..245fd5bd98b0f 100644 --- a/src/sql/src/plan/transform_hir.rs +++ b/src/sql/src/plan/transform_hir.rs @@ -99,7 +99,7 @@ pub fn split_subquery_predicates(expr: &mut HirRelationExpr) { fn contains_subquery(expr: &HirScalarExpr) -> bool { let mut found = false; - expr.visit(&mut |expr| match expr { + expr.visit_pre_nolimit(&mut |expr| match expr { HirScalarExpr::Exists(_) | HirScalarExpr::Select(_) => found = true, _ => (), }); From 8b07336533db5d5cd8071010fd7117cd01570857 Mon Sep 17 00:00:00 2001 From: Gabor Gevay Date: Wed, 22 Jan 2025 16:14:25 +0100 Subject: [PATCH 3/7] Eliminate the visit_pre_nolimit call introduced in the previous commit --- src/sql/src/plan/lowering.rs | 15 +++--- src/sql/src/plan/transform_hir.rs | 87 +++++++++++++++++-------------- 2 files changed, 57 insertions(+), 45 deletions(-) diff --git a/src/sql/src/plan/lowering.rs b/src/sql/src/plan/lowering.rs index ce92846933228..4d1ceecdf4bb4 100644 --- a/src/sql/src/plan/lowering.rs +++ b/src/sql/src/plan/lowering.rs @@ -39,18 +39,19 @@ use std::collections::{BTreeMap, BTreeSet}; use std::iter::repeat; +use itertools::Itertools; +use mz_expr::visit::Visit; +use mz_expr::{AccessStrategy, AggregateFunc, MirRelationExpr, MirScalarExpr}; +use mz_ore::collections::CollectionExt; +use mz_ore::stack::maybe_grow; +use mz_repr::*; + use crate::optimizer_metrics::OptimizerMetrics; use crate::plan::hir::{ AggregateExpr, ColumnOrder, ColumnRef, HirRelationExpr, HirScalarExpr, JoinKind, WindowExprType, }; use crate::plan::{transform_hir, PlanError}; use crate::session::vars::SystemVars; -use itertools::Itertools; -use mz_expr::{AccessStrategy, AggregateFunc, MirRelationExpr, MirScalarExpr}; -use mz_expr::visit::Visit; -use mz_ore::collections::CollectionExt; -use mz_ore::stack::maybe_grow; -use mz_repr::*; mod variadic_left; @@ -185,7 +186,7 @@ impl HirRelationExpr { } mut other => { let mut id_gen = mz_ore::id_gen::IdGen::default(); - transform_hir::split_subquery_predicates(&mut other); + transform_hir::split_subquery_predicates(&mut other)?; transform_hir::try_simplify_quantified_comparisons(&mut other); transform_hir::fuse_window_functions(&mut other, &context)?; MirRelationExpr::constant(vec![vec![]], RelationType::new(vec![])).let_in( diff --git a/src/sql/src/plan/transform_hir.rs b/src/sql/src/plan/transform_hir.rs index 245fd5bd98b0f..94e41288178bd 100644 --- a/src/sql/src/plan/transform_hir.rs +++ b/src/sql/src/plan/transform_hir.rs @@ -56,54 +56,61 @@ use crate::plan::{AggregateExpr, WindowExprType}; /// = e`, will be further restricted to outer rows that match `A = b AND c = /// d AND EXISTS()`. This can vastly reduce the cost of the /// subquery, especially when the original conjunction contains join keys. -pub fn split_subquery_predicates(expr: &mut HirRelationExpr) { - fn walk_relation(expr: &mut HirRelationExpr) { +pub fn split_subquery_predicates(expr: &mut HirRelationExpr) -> Result<(), RecursionLimitError> { + fn walk_relation(expr: &mut HirRelationExpr) -> Result<(), RecursionLimitError> { #[allow(deprecated)] - expr.visit_mut(0, &mut |expr, _| match expr { - HirRelationExpr::Map { scalars, .. } => { - for scalar in scalars { - walk_scalar(scalar); - } - } - HirRelationExpr::CallTable { exprs, .. } => { - for expr in exprs { - walk_scalar(expr); + expr.visit_mut_fallible(0, &mut |expr, _| { + match expr { + HirRelationExpr::Map { scalars, .. } => { + for scalar in scalars { + walk_scalar(scalar)?; + } } - } - HirRelationExpr::Filter { predicates, .. } => { - let mut subqueries = vec![]; - for predicate in &mut *predicates { - walk_scalar(predicate); - extract_conjuncted_subqueries(predicate, &mut subqueries); + HirRelationExpr::CallTable { exprs, .. } => { + for expr in exprs { + walk_scalar(expr)?; + } } - // TODO(benesch): we could be smarter about the order in which - // we emit subqueries. At the moment we just emit in the order - // we discovered them, but ideally we'd emit them in an order - // that accounted for their cost/selectivity. E.g., low-cost, - // high-selectivity subqueries should go first. - for subquery in subqueries { - predicates.push(subquery); + HirRelationExpr::Filter { predicates, .. } => { + let mut subqueries = vec![]; + for predicate in &mut *predicates { + walk_scalar(predicate)?; + extract_conjuncted_subqueries(predicate, &mut subqueries)?; + } + // TODO(benesch): we could be smarter about the order in which + // we emit subqueries. At the moment we just emit in the order + // we discovered them, but ideally we'd emit them in an order + // that accounted for their cost/selectivity. E.g., low-cost, + // high-selectivity subqueries should go first. + for subquery in subqueries { + predicates.push(subquery); + } } + _ => (), } - _ => (), - }); + Ok(()) + }) } - fn walk_scalar(expr: &mut HirScalarExpr) { - #[allow(deprecated)] - expr.visit_mut(&mut |expr| match expr { - HirScalarExpr::Exists(input) | HirScalarExpr::Select(input) => walk_relation(input), - _ => (), + fn walk_scalar(expr: &mut HirScalarExpr) -> Result<(), RecursionLimitError> { + expr.try_visit_mut_post(&mut |expr| { + match expr { + HirScalarExpr::Exists(input) | HirScalarExpr::Select(input) => { + walk_relation(input)? + } + _ => (), + } + Ok(()) }) } - fn contains_subquery(expr: &HirScalarExpr) -> bool { + fn contains_subquery(expr: &HirScalarExpr) -> Result { let mut found = false; - expr.visit_pre_nolimit(&mut |expr| match expr { + expr.visit_pre(&mut |expr| match expr { HirScalarExpr::Exists(_) | HirScalarExpr::Select(_) => found = true, _ => (), - }); - found + })?; + Ok(found) } /// Extracts subqueries from a conjunction into `out`. @@ -122,7 +129,10 @@ pub fn split_subquery_predicates(expr: &mut HirRelationExpr) { /// /// and returns the expression fragments `EXISTS ()` and /// `() = e` in the `out` vector. - fn extract_conjuncted_subqueries(expr: &mut HirScalarExpr, out: &mut Vec) { + fn extract_conjuncted_subqueries( + expr: &mut HirScalarExpr, + out: &mut Vec, + ) -> Result<(), RecursionLimitError> { match expr { HirScalarExpr::CallVariadic { func: VariadicFunc::And, @@ -130,13 +140,14 @@ pub fn split_subquery_predicates(expr: &mut HirRelationExpr) { } => { exprs .into_iter() - .for_each(|e| extract_conjuncted_subqueries(e, out)); + .try_for_each(|e| extract_conjuncted_subqueries(e, out))?; } - expr if contains_subquery(expr) => { + expr if contains_subquery(expr)? => { out.push(mem::replace(expr, HirScalarExpr::literal_true())) } _ => (), } + Ok(()) } walk_relation(expr) From 125df380e4ea087e5fe962703bbb991874aa1930 Mon Sep 17 00:00:00 2001 From: Gabor Gevay Date: Wed, 22 Jan 2025 16:23:32 +0100 Subject: [PATCH 4/7] Fix HirScalarExpr::visit_mut_pre --- src/sql/src/plan/hir.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sql/src/plan/hir.rs b/src/sql/src/plan/hir.rs index 4f3369ae262f7..1d4b58b0494df 100644 --- a/src/sql/src/plan/hir.rs +++ b/src/sql/src/plan/hir.rs @@ -3114,7 +3114,7 @@ impl HirScalarExpr { { f(self); #[allow(deprecated)] - self.visit1_mut(|e: &mut HirScalarExpr| e.visit_mut(f)); + self.visit1_mut(|e: &mut HirScalarExpr| e.visit_mut_pre(f)); } #[deprecated = "Use `VisitChildren::visit_children` instead."] From 45da845d71d77b10aadf2ced57d83abe18910e1a Mon Sep 17 00:00:00 2001 From: Gabor Gevay Date: Wed, 22 Jan 2025 16:24:56 +0100 Subject: [PATCH 5/7] Eliminate deprecated HirScalarExpr::visit_mut --- src/sql/src/plan/hir.rs | 10 ---------- src/sql/src/plan/query.rs | 7 ++++--- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/sql/src/plan/hir.rs b/src/sql/src/plan/hir.rs index 1d4b58b0494df..6924ba638dd46 100644 --- a/src/sql/src/plan/hir.rs +++ b/src/sql/src/plan/hir.rs @@ -3097,16 +3097,6 @@ impl HirScalarExpr { mem::replace(self, HirScalarExpr::literal_null(ScalarType::String)) } - #[deprecated = "Use `Visit::visit_post` instead."] - pub fn visit_mut(&mut self, f: &mut F) - where - F: FnMut(&mut Self), - { - #[allow(deprecated)] - self.visit1_mut(|e: &mut HirScalarExpr| e.visit_mut(f)); - f(self); - } - #[deprecated = "Use `Visit::visit_mut_pre` instead."] pub fn visit_mut_pre(&mut self, f: &mut F) where diff --git a/src/sql/src/plan/query.rs b/src/sql/src/plan/query.rs index 2778774acf4cb..fe114aaf878b1 100644 --- a/src/sql/src/plan/query.rs +++ b/src/sql/src/plan/query.rs @@ -855,15 +855,16 @@ fn handle_mutation_using_clause( // those to the right of `using_rel_expr`) to instead be correlated to // the outer relation, i.e. `get`. let using_rel_arity = qcx.relation_type(&using_rel_expr).arity(); - #[allow(deprecated)] - expr.visit_mut(&mut |e| { + // local import to not get confused with `mz_sql_parser::ast::visit::Visit` + use mz_expr::visit::Visit; + expr.visit_mut_post(&mut |e| { if let HirScalarExpr::Column(c) = e { if c.column >= using_rel_arity { c.level += 1; c.column -= using_rel_arity; }; } - }); + })?; // Filter `USING` tables like ` WHERE `. Note that // this filters the `USING` tables, _not_ the joined `USING..., FROM` From 1c8b23400906f5de9af326d5235c900f0912b025 Mon Sep 17 00:00:00 2001 From: Gabor Gevay Date: Wed, 22 Jan 2025 16:37:08 +0100 Subject: [PATCH 6/7] Eliminate deprecated HirScalarExpr::visit_mut_pre --- src/sql/src/plan/hir.rs | 10 --- src/sql/src/plan/lowering.rs | 2 +- src/sql/src/plan/transform_hir.rs | 143 ++++++++++++++++-------------- 3 files changed, 78 insertions(+), 77 deletions(-) diff --git a/src/sql/src/plan/hir.rs b/src/sql/src/plan/hir.rs index 6924ba638dd46..b18017668615e 100644 --- a/src/sql/src/plan/hir.rs +++ b/src/sql/src/plan/hir.rs @@ -3097,16 +3097,6 @@ impl HirScalarExpr { mem::replace(self, HirScalarExpr::literal_null(ScalarType::String)) } - #[deprecated = "Use `Visit::visit_mut_pre` instead."] - pub fn visit_mut_pre(&mut self, f: &mut F) - where - F: FnMut(&mut Self), - { - f(self); - #[allow(deprecated)] - self.visit1_mut(|e: &mut HirScalarExpr| e.visit_mut_pre(f)); - } - #[deprecated = "Use `VisitChildren::visit_children` instead."] pub fn visit1_mut(&mut self, mut f: F) where diff --git a/src/sql/src/plan/lowering.rs b/src/sql/src/plan/lowering.rs index 4d1ceecdf4bb4..10ec1d13bd0a8 100644 --- a/src/sql/src/plan/lowering.rs +++ b/src/sql/src/plan/lowering.rs @@ -187,7 +187,7 @@ impl HirRelationExpr { mut other => { let mut id_gen = mz_ore::id_gen::IdGen::default(); transform_hir::split_subquery_predicates(&mut other)?; - transform_hir::try_simplify_quantified_comparisons(&mut other); + transform_hir::try_simplify_quantified_comparisons(&mut other)?; transform_hir::fuse_window_functions(&mut other, &context)?; MirRelationExpr::constant(vec![vec![]], RelationType::new(vec![])).let_in( &mut id_gen, diff --git a/src/sql/src/plan/transform_hir.rs b/src/sql/src/plan/transform_hir.rs index 94e41288178bd..32298f981321a 100644 --- a/src/sql/src/plan/transform_hir.rs +++ b/src/sql/src/plan/transform_hir.rs @@ -173,15 +173,20 @@ pub fn split_subquery_predicates(expr: &mut HirRelationExpr) -> Result<(), Recur /// /// See Section 3.5 of "Execution Strategies for SQL Subqueries" by /// M. Elhemali, et al. -pub fn try_simplify_quantified_comparisons(expr: &mut HirRelationExpr) { - fn walk_relation(expr: &mut HirRelationExpr, outers: &[RelationType]) { +pub fn try_simplify_quantified_comparisons( + expr: &mut HirRelationExpr, +) -> Result<(), RecursionLimitError> { + fn walk_relation( + expr: &mut HirRelationExpr, + outers: &[RelationType], + ) -> Result<(), RecursionLimitError> { match expr { HirRelationExpr::Map { scalars, input } => { - walk_relation(input, outers); + walk_relation(input, outers)?; let mut outers = outers.to_vec(); outers.insert(0, input.typ(&outers, &NO_PARAMS)); for scalar in scalars { - walk_scalar(scalar, &outers, false); + walk_scalar(scalar, &outers, false)?; let (inner, outers) = outers .split_first_mut() .expect("outers known to have at least one element"); @@ -190,95 +195,101 @@ pub fn try_simplify_quantified_comparisons(expr: &mut HirRelationExpr) { } } HirRelationExpr::Filter { predicates, input } => { - walk_relation(input, outers); + walk_relation(input, outers)?; let mut outers = outers.to_vec(); outers.insert(0, input.typ(&outers, &NO_PARAMS)); for pred in predicates { - walk_scalar(pred, &outers, true); + walk_scalar(pred, &outers, true)?; } } HirRelationExpr::CallTable { exprs, .. } => { let mut outers = outers.to_vec(); outers.insert(0, RelationType::empty()); for scalar in exprs { - walk_scalar(scalar, &outers, false); + walk_scalar(scalar, &outers, false)?; } } HirRelationExpr::Join { left, right, .. } => { - walk_relation(left, outers); + walk_relation(left, outers)?; let mut outers = outers.to_vec(); outers.insert(0, left.typ(&outers, &NO_PARAMS)); - walk_relation(right, &outers); + walk_relation(right, &outers)?; } expr => { #[allow(deprecated)] - let _ = expr.visit1_mut(0, &mut |expr, _| -> Result<(), ()> { - walk_relation(expr, outers); - Ok(()) + let _ = expr.visit1_mut(0, &mut |expr, _| -> Result<(), RecursionLimitError> { + walk_relation(expr, outers) }); } } + Ok(()) } - fn walk_scalar(expr: &mut HirScalarExpr, outers: &[RelationType], mut in_filter: bool) { - #[allow(deprecated)] - expr.visit_mut_pre(&mut |e| match e { - HirScalarExpr::Exists(input) => walk_relation(input, outers), - HirScalarExpr::Select(input) => { - walk_relation(input, outers); - - // We're inside of a `(SELECT ...)` subquery. Now let's see if - // it has the form `(SELECT (...) FROM )`. - // Ideally we could do this with one pattern, but Rust's pattern - // matching engine is not powerful enough, so we have to do this - // in stages; the early returns avoid brutal nesting. - - let (func, expr, input) = match &mut **input { - HirRelationExpr::Reduce { - group_key, - aggregates, - input, - expected_group_size: _, - } if group_key.is_empty() && aggregates.len() == 1 => { - let agg = &mut aggregates[0]; - (&agg.func, &mut agg.expr, input) - } - _ => return, - }; - - if !in_filter && column_type(outers, input, expr).nullable { - // Unless we're directly inside of a WHERE, this - // transformation is only valid if the expression involved - // is non-nullable. - return; - } + fn walk_scalar( + expr: &mut HirScalarExpr, + outers: &[RelationType], + mut in_filter: bool, + ) -> Result<(), RecursionLimitError> { + expr.try_visit_mut_pre(&mut |e| { + match e { + HirScalarExpr::Exists(input) => walk_relation(input, outers)?, + HirScalarExpr::Select(input) => { + walk_relation(input, outers)?; + + // We're inside a `(SELECT ...)` subquery. Now let's see if + // it has the form `(SELECT (...) FROM )`. + // Ideally we could do this with one pattern, but Rust's pattern + // matching engine is not powerful enough, so we have to do this + // in stages; the early returns avoid brutal nesting. + + let (func, expr, input) = match &mut **input { + HirRelationExpr::Reduce { + group_key, + aggregates, + input, + expected_group_size: _, + } if group_key.is_empty() && aggregates.len() == 1 => { + let agg = &mut aggregates[0]; + (&agg.func, &mut agg.expr, input) + } + _ => return Ok(()), + }; - match func { - AggregateFunc::Any => { - // Found `(SELECT any() FROM )`. Rewrite to - // `EXISTS(SELECT 1 FROM WHERE )`. - *e = input.take().filter(vec![expr.take()]).exists(); + if !in_filter && column_type(outers, input, expr).nullable { + // Unless we're directly inside a WHERE, this + // transformation is only valid if the expression involved + // is non-nullable. + return Ok(()); } - AggregateFunc::All => { - // Found `(SELECT all() FROM )`. Rewrite to - // `NOT EXISTS(SELECT 1 FROM WHERE NOT OR IS NULL)`. - // - // Note that negation of alone is insufficient. - // Consider that `WHERE ` filters out rows if - // `` is false *or* null. To invert the test, we - // need `NOT OR IS NULL`. - let expr = expr.take(); - let filter = expr.clone().not().or(expr.call_is_null()); - *e = input.take().filter(vec![filter]).exists().not(); + + match func { + AggregateFunc::Any => { + // Found `(SELECT any() FROM )`. Rewrite to + // `EXISTS(SELECT 1 FROM WHERE )`. + *e = input.take().filter(vec![expr.take()]).exists(); + } + AggregateFunc::All => { + // Found `(SELECT all() FROM )`. Rewrite to + // `NOT EXISTS(SELECT 1 FROM WHERE NOT OR IS NULL)`. + // + // Note that negation of alone is insufficient. + // Consider that `WHERE ` filters out rows if + // `` is false *or* null. To invert the test, we + // need `NOT OR IS NULL`. + let expr = expr.take(); + let filter = expr.clone().not().or(expr.call_is_null()); + *e = input.take().filter(vec![filter]).exists().not(); + } + _ => (), } - _ => (), + } + _ => { + // As soon as we see *any* scalar expression, we are no longer + // directly inside a filter. + in_filter = false; } } - _ => { - // As soon as we see *any* scalar expression, we are no longer - // directly inside of a filter. - in_filter = false; - } + Ok(()) }) } From 7e1e1c540fff5c5e23709947f84559bc979ce8da Mon Sep 17 00:00:00 2001 From: Gabor Gevay Date: Wed, 22 Jan 2025 16:39:42 +0100 Subject: [PATCH 7/7] Delete unused HirScalarExpr::visit1_mut --- src/sql/src/plan/hir.rs | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/src/sql/src/plan/hir.rs b/src/sql/src/plan/hir.rs index b18017668615e..48535e26e5ad5 100644 --- a/src/sql/src/plan/hir.rs +++ b/src/sql/src/plan/hir.rs @@ -3097,39 +3097,6 @@ impl HirScalarExpr { mem::replace(self, HirScalarExpr::literal_null(ScalarType::String)) } - #[deprecated = "Use `VisitChildren::visit_children` instead."] - pub fn visit1_mut(&mut self, mut f: F) - where - F: FnMut(&mut Self), - { - use HirScalarExpr::*; - match self { - Column(..) | Parameter(..) | Literal(..) | CallUnmaterializable(..) => (), - CallUnary { expr, .. } => f(expr), - CallBinary { expr1, expr2, .. } => { - f(expr1); - f(expr2); - } - CallVariadic { exprs, .. } => { - for expr in exprs { - f(expr); - } - } - If { cond, then, els } => { - f(cond); - f(then); - f(els); - } - Exists(..) | Select(..) => (), - Windowing(expr) => { - let _ = expr.visit_expressions_mut(&mut |e| -> Result<(), ()> { - f(e); - Ok(()) - }); - } - } - } - #[deprecated = "Redefine this based on the `Visit` and `VisitChildren` methods."] /// Visits the column references in this scalar expression. ///