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, SecretRef, 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 ExprImpl::SecretRef(inner) => visitor.visit_secret_ref(inner),
55 }
56 })
57}
58
59pub trait ExprVisitor {
68 fn visit_expr(&mut self, expr: &ExprImpl) {
69 default_visit_expr(self, expr)
70 }
71 fn visit_function_call(&mut self, func_call: &FunctionCall) {
72 func_call
73 .inputs()
74 .iter()
75 .for_each(|expr| self.visit_expr(expr));
76 }
77 fn visit_function_call_with_lambda(&mut self, func_call: &FunctionCallWithLambda) {
78 self.visit_function_call(func_call.base())
79 }
80 fn visit_agg_call(&mut self, agg_call: &AggCall) {
81 agg_call
82 .args()
83 .iter()
84 .for_each(|expr| self.visit_expr(expr));
85 agg_call.order_by().visit_expr(self);
86 agg_call.filter().visit_expr(self);
87 }
88 fn visit_parameter(&mut self, _: &Parameter) {}
89 fn visit_literal(&mut self, _: &Literal) {}
90 fn visit_input_ref(&mut self, _: &InputRef) {}
91 fn visit_subquery(&mut self, _: &Subquery) {}
92 fn visit_correlated_input_ref(&mut self, _: &CorrelatedInputRef) {}
93
94 fn visit_table_function(&mut self, func_call: &TableFunction) {
95 func_call.args.iter().for_each(|expr| self.visit_expr(expr));
96 }
97 fn visit_window_function(&mut self, func_call: &WindowFunction) {
98 func_call.args.iter().for_each(|expr| self.visit_expr(expr));
99 }
100 fn visit_user_defined_function(&mut self, func_call: &UserDefinedFunction) {
101 func_call.args.iter().for_each(|expr| self.visit_expr(expr));
102 }
103 fn visit_now(&mut self, _: &Now) {}
104 fn visit_secret_ref(&mut self, _: &SecretRef) {}
105}