1use std::iter::Peekable;
16
17use itertools::Itertools;
18use risingwave_common::types::{DataType, ScalarImpl};
19use risingwave_expr::expr::LogReport;
20use risingwave_pb::expr::ExprNode;
21use risingwave_pb::expr::expr_node::{PbType, RexNode};
22
23use super::NonStrictExpression;
24use super::expr_some_all::SomeAllExpression;
25use super::expr_udf::UserDefinedFunction;
26use super::strict::Strict;
27use super::wrapper::EvalErrorReport;
28use super::wrapper::checked::Checked;
29use super::wrapper::non_strict::NonStrict;
30use crate::expr::{
31 AsyncExpressionBoxExt, BoxedExpression, InputRefExpression, LiteralExpression, SyncExpression,
32 SyncExpressionBoxExt,
33};
34use crate::expr_context::strict_mode;
35use crate::sig::FUNCTION_REGISTRY;
36use crate::{Result, bail};
37
38pub fn build_from_prost(prost: &ExprNode) -> Result<BoxedExpression> {
40 let expr = ExprBuilder::new_strict().build(prost)?;
41 Ok(match expr {
42 BoxedExpression::Sync(expr) => Strict::new(expr).boxed(),
43 BoxedExpression::Async(expr) => Strict::new(expr).boxed(),
44 })
45}
46
47pub fn build_non_strict_from_prost(
49 prost: &ExprNode,
50 error_report: impl EvalErrorReport + 'static,
51) -> Result<NonStrictExpression> {
52 let expr = ExprBuilder::new_non_strict(error_report).build(prost)?;
53 Ok(match expr {
54 BoxedExpression::Sync(expr) => NonStrictExpression::Sync(expr),
55 BoxedExpression::Async(expr) => NonStrictExpression::Async(expr),
56 })
57}
58
59pub fn build_batch_expr_from_prost(prost: &ExprNode) -> Result<BoxedExpression> {
66 if strict_mode()? {
67 build_from_prost(prost)
68 } else {
69 Ok(ExprBuilder::new_non_strict(LogReport).build(prost)?)
71 }
72}
73
74struct ExprBuilder<R> {
76 error_report: Option<R>,
81}
82
83impl ExprBuilder<!> {
84 fn new_strict() -> Self {
86 Self { error_report: None }
87 }
88}
89
90impl<R> ExprBuilder<R>
91where
92 R: EvalErrorReport + 'static,
93{
94 fn new_non_strict(error_report: R) -> Self {
96 Self {
97 error_report: Some(error_report),
98 }
99 }
100
101 fn wrap(&self, expr: BoxedExpression) -> BoxedExpression {
103 match expr {
104 BoxedExpression::Sync(expr) => {
105 let checked = Checked(expr);
106 if let Some(error_report) = &self.error_report {
107 NonStrict::new(checked, error_report.clone()).boxed()
108 } else {
109 checked.boxed()
110 }
111 }
112 BoxedExpression::Async(expr) => {
113 let checked = Checked(expr);
114 if let Some(error_report) = &self.error_report {
115 NonStrict::new(checked, error_report.clone()).boxed()
116 } else {
117 checked.boxed()
118 }
119 }
120 }
121 }
122
123 fn build(&self, prost: &ExprNode) -> Result<BoxedExpression> {
125 let expr = self.build_inner(prost)?;
126 Ok(self.wrap(expr))
127 }
128
129 fn build_inner(&self, prost: &ExprNode) -> Result<BoxedExpression> {
131 use PbType as E;
132
133 let build_child = |prost: &'_ ExprNode| self.build(prost);
134
135 match prost.get_rex_node()? {
136 RexNode::InputRef(_) => InputRefExpression::build_boxed(prost, build_child),
137 RexNode::Constant(_) => LiteralExpression::build_boxed(prost, build_child),
138 RexNode::Udf(_) => UserDefinedFunction::build_boxed(prost, build_child),
139
140 RexNode::FuncCall(_) => match prost.function_type() {
141 E::All | E::Some => SomeAllExpression::build_boxed(prost, build_child),
143
144 _ => FuncCallBuilder::build_boxed(prost, build_child),
146 },
147
148 RexNode::Now(_) => unreachable!("now should not be built at backend"),
149
150 RexNode::SecretRef(sr) => {
151 use risingwave_common::secret::LocalSecretManager;
152 use risingwave_pb::secret::SecretRef as PbSecretRef;
153
154 let pb_ref = PbSecretRef {
155 secret_id: sr.secret_id.into(),
156 ref_as: sr.ref_as,
157 };
158 let value = LocalSecretManager::global()
159 .fill_secret(pb_ref)
160 .map_err(|e| anyhow::anyhow!(e))?;
161 Ok(
162 LiteralExpression::new(DataType::Varchar, Some(ScalarImpl::Utf8(value.into())))
163 .boxed(),
164 )
165 }
166 }
167 }
168}
169
170pub(crate) trait Build: SyncExpression + Sized {
172 fn build(
176 prost: &ExprNode,
177 build_child: impl Fn(&ExprNode) -> Result<BoxedExpression>,
178 ) -> Result<Self>;
179
180 #[cfg(test)]
183 fn build_for_test(prost: &ExprNode) -> Result<Self> {
184 Self::build(prost, build_from_prost)
185 }
186}
187
188pub(crate) trait BuildBoxed: 'static {
190 fn build_boxed(
192 prost: &ExprNode,
193 build_child: impl Fn(&ExprNode) -> Result<BoxedExpression>,
194 ) -> Result<BoxedExpression>;
195}
196
197impl<E: Build + 'static> BuildBoxed for E {
199 fn build_boxed(
200 prost: &ExprNode,
201 build_child: impl Fn(&ExprNode) -> Result<BoxedExpression>,
202 ) -> Result<BoxedExpression> {
203 Self::build(prost, build_child).map(SyncExpressionBoxExt::boxed)
204 }
205}
206
207struct FuncCallBuilder;
209
210impl BuildBoxed for FuncCallBuilder {
211 fn build_boxed(
212 prost: &ExprNode,
213 build_child: impl Fn(&ExprNode) -> Result<BoxedExpression>,
214 ) -> Result<BoxedExpression> {
215 let func_type = prost.function_type();
216 let ret_type = DataType::from(prost.get_return_type().unwrap());
217 let func_call = prost
218 .get_rex_node()?
219 .as_func_call()
220 .expect("not a func call");
221
222 let children = func_call
223 .get_children()
224 .iter()
225 .map(build_child)
226 .try_collect()?;
227
228 build_func(func_type, ret_type, children)
229 }
230}
231
232pub fn build_func(
234 func: PbType,
235 ret_type: DataType,
236 children: Vec<BoxedExpression>,
237) -> Result<BoxedExpression> {
238 let args = children.iter().map(|c| c.return_type()).collect_vec();
239 let desc = FUNCTION_REGISTRY.get(func, &args, &ret_type)?;
240 desc.build_scalar(ret_type, children)
241}
242
243pub fn build_func_non_strict(
248 func: PbType,
249 ret_type: DataType,
250 children: Vec<BoxedExpression>,
251 error_report: impl EvalErrorReport + 'static,
252) -> Result<NonStrictExpression> {
253 let expr = build_func(func, ret_type, children)?;
254 let wrapped = ExprBuilder::new_non_strict(error_report).wrap(expr);
255 Ok(match wrapped {
256 BoxedExpression::Sync(expr) => NonStrictExpression::Sync(expr),
257 BoxedExpression::Async(expr) => NonStrictExpression::Async(expr),
258 })
259}
260
261pub(super) fn get_children_and_return_type(prost: &ExprNode) -> Result<(&[ExprNode], DataType)> {
262 let ret_type = DataType::from(prost.get_return_type().unwrap());
263 if let RexNode::FuncCall(func_call) = prost.get_rex_node().unwrap() {
264 Ok((func_call.get_children(), ret_type))
265 } else {
266 bail!("Expected RexNode::FuncCall");
267 }
268}
269
270pub fn build_from_pretty(s: impl AsRef<str>) -> BoxedExpression {
293 let tokens = lexer(s.as_ref());
294 Parser::new(tokens.into_iter()).parse_expression()
295}
296
297struct Parser<Iter: Iterator> {
298 tokens: Peekable<Iter>,
299}
300
301impl<Iter: Iterator<Item = Token>> Parser<Iter> {
302 fn new(tokens: Iter) -> Self {
303 Self {
304 tokens: tokens.peekable(),
305 }
306 }
307
308 fn parse_expression(&mut self) -> BoxedExpression {
309 match self.tokens.next().expect("Unexpected end of input") {
310 Token::Index(index) => {
311 assert_eq!(self.tokens.next(), Some(Token::Colon), "Expected a Colon");
312 let ty = self.parse_type();
313 InputRefExpression::new(ty, index).boxed()
314 }
315 Token::LParen => {
316 let func = self.parse_function();
317 assert_eq!(self.tokens.next(), Some(Token::Colon), "Expected a Colon");
318 let ty = self.parse_type();
319
320 let mut children = Vec::new();
321 while self.tokens.peek() != Some(&Token::RParen) {
322 children.push(self.parse_expression());
323 }
324 self.tokens.next(); build_func(func, ty, children).expect("Failed to build")
327 }
328 Token::Literal(value) => {
329 assert_eq!(self.tokens.next(), Some(Token::Colon), "Expected a Colon");
330 let ty = self.parse_type();
331 let value = match value.as_str() {
332 "null" | "NULL" => None,
333 _ => Some(ScalarImpl::from_text(&value, &ty).expect_str("value", &value)),
334 };
335 LiteralExpression::new(ty, value).boxed()
336 }
337 _ => panic!("Unexpected token"),
338 }
339 }
340
341 fn parse_type(&mut self) -> DataType {
342 match self.tokens.next().expect("Unexpected end of input") {
343 Token::Literal(name) => {
344 let mut processed_name = name.replace('_', " ");
345
346 if processed_name.starts_with("map") {
349 processed_name = processed_name.replace('<', "(").replace('>', ")");
350 }
351
352 processed_name
353 .parse::<DataType>()
354 .expect_str("type", &processed_name)
355 }
356 t => panic!("Expected a Literal, got {t:?}"),
357 }
358 }
359
360 fn parse_function(&mut self) -> PbType {
361 match self.tokens.next().expect("Unexpected end of input") {
362 Token::Literal(name) => {
363 PbType::from_str_name(&name.to_uppercase()).expect_str("function", &name)
364 }
365 t => panic!("Expected a Literal, got {t:?}"),
366 }
367 }
368}
369
370#[derive(Debug, PartialEq, Clone)]
371pub(crate) enum Token {
372 LParen,
373 RParen,
374 Colon,
375 Index(usize),
376 Literal(String),
377}
378
379pub(crate) fn lexer(input: &str) -> Vec<Token> {
380 let mut tokens = Vec::new();
381 let mut chars = input.chars().peekable();
382 while let Some(c) = chars.next() {
383 let token = match c {
384 '(' => Token::LParen,
385 ')' => Token::RParen,
386 ':' => Token::Colon,
387 '$' => {
388 let mut number = String::new();
389 while let Some(c) = chars.peek()
390 && c.is_ascii_digit()
391 {
392 number.push(chars.next().unwrap());
393 }
394 let index = number.parse::<usize>().expect("Invalid number");
395 Token::Index(index)
396 }
397 ' ' | '\t' | '\r' | '\n' => continue,
398 _ => {
399 let mut literal = String::new();
400 literal.push(c);
401 while let Some(&c) = chars.peek()
402 && !matches!(c, '(' | ')' | ':' | ' ' | '\t' | '\r' | '\n')
403 {
404 literal.push(chars.next().unwrap());
405 }
406 Token::Literal(literal)
407 }
408 };
409 tokens.push(token);
410 }
411 tokens
412}
413
414pub(crate) trait ExpectExt<T> {
415 fn expect_str(self, what: &str, s: &str) -> T;
416}
417
418impl<T> ExpectExt<T> for Option<T> {
419 #[track_caller]
420 fn expect_str(self, what: &str, s: &str) -> T {
421 match self {
422 Some(x) => x,
423 None => panic!("expect {what} in {s:?}"),
424 }
425 }
426}
427
428impl<T, E> ExpectExt<T> for std::result::Result<T, E> {
429 #[track_caller]
430 fn expect_str(self, what: &str, s: &str) -> T {
431 match self {
432 Ok(x) => x,
433 Err(_) => panic!("expect {what} in {s:?}"),
434 }
435 }
436}