risingwave_frontend/expr/
expr_visitor.rs1use risingwave_common::util::recursive::{Recurse, tracker};
16
17use super::{
18 AggCall, CorrelatedInputRef, EXPR_DEPTH_THRESHOLD, EXPR_TOO_DEEP_NOTICE, ExprImpl,
19 FunctionCall, FunctionCallWithLambda, InputRef, Literal, Now, Parameter, Subquery,
20 TableFunction, UserDefinedFunction, WindowFunction,
21};
22use crate::session::current::notice_to_user;
23
24pub fn default_visit_expr<V: ExprVisitor + ?Sized>(visitor: &mut V, expr: &ExprImpl) {
31 tracker!().recurse(|t| {
35 if t.depth_reaches(EXPR_DEPTH_THRESHOLD) {
36 notice_to_user(EXPR_TOO_DEEP_NOTICE);
37 }
38
39 match expr {
40 ExprImpl::InputRef(inner) => visitor.visit_input_ref(inner),
41 ExprImpl::Literal(inner) => visitor.visit_literal(inner),
42 ExprImpl::FunctionCall(inner) => visitor.visit_function_call(inner),
43 ExprImpl::FunctionCallWithLambda(inner) => {
44 visitor.visit_function_call_with_lambda(inner)
45 }
46 ExprImpl::AggCall(inner) => visitor.visit_agg_call(inner),
47 ExprImpl::Subquery(inner) => visitor.visit_subquery(inner),
48 ExprImpl::CorrelatedInputRef(inner) => visitor.visit_correlated_input_ref(inner),
49 ExprImpl::TableFunction(inner) => visitor.visit_table_function(inner),
50 ExprImpl::WindowFunction(inner) => visitor.visit_window_function(inner),
51 ExprImpl::UserDefinedFunction(inner) => visitor.visit_user_defined_function(inner),
52 ExprImpl::Parameter(inner) => visitor.visit_parameter(inner),
53 ExprImpl::Now(inner) => visitor.visit_now(inner),
54 }
55 })
56}
57
58pub trait ExprVisitor {
67 fn visit_expr(&mut self, expr: &ExprImpl) {
68 default_visit_expr(self, expr)
69 }
70 fn visit_function_call(&mut self, func_call: &FunctionCall) {
71 func_call
72 .inputs()
73 .iter()
74 .for_each(|expr| self.visit_expr(expr));
75 }
76 fn visit_function_call_with_lambda(&mut self, func_call: &FunctionCallWithLambda) {
77 self.visit_function_call(func_call.base())
78 }
79 fn visit_agg_call(&mut self, agg_call: &AggCall) {
80 agg_call
81 .args()
82 .iter()
83 .for_each(|expr| self.visit_expr(expr));
84 agg_call.order_by().visit_expr(self);
85 agg_call.filter().visit_expr(self);
86 }
87 fn visit_parameter(&mut self, _: &Parameter) {}
88 fn visit_literal(&mut self, _: &Literal) {}
89 fn visit_input_ref(&mut self, _: &InputRef) {}
90 fn visit_subquery(&mut self, _: &Subquery) {}
91 fn visit_correlated_input_ref(&mut self, _: &CorrelatedInputRef) {}
92
93 fn visit_table_function(&mut self, func_call: &TableFunction) {
94 func_call.args.iter().for_each(|expr| self.visit_expr(expr));
95 }
96 fn visit_window_function(&mut self, func_call: &WindowFunction) {
97 func_call.args.iter().for_each(|expr| self.visit_expr(expr));
98 }
99 fn visit_user_defined_function(&mut self, func_call: &UserDefinedFunction) {
100 func_call.args.iter().for_each(|expr| self.visit_expr(expr));
101 }
102 fn visit_now(&mut self, _: &Now) {}
103}