risingwave_expr/aggregate/
def.rs1use std::fmt::Display;
18use std::iter::Peekable;
19use std::str::FromStr;
20
21use anyhow::Context;
22use enum_as_inner::EnumAsInner;
23use itertools::Itertools;
24use risingwave_common::bail;
25use risingwave_common::types::{DataType, Datum};
26use risingwave_common::util::sort_util::{ColumnOrder, OrderType};
27use risingwave_common::util::value_encoding::DatumFromProtoExt;
28pub use risingwave_pb::expr::agg_call::PbKind as PbAggKind;
29use risingwave_pb::expr::{
30 PbAggCall, PbAggType, PbExprNode, PbInputRef, PbUserDefinedFunctionMetadata,
31};
32
33use crate::Result;
34use crate::expr::{BoxedExpression, ExpectExt, LiteralExpression, Token, build_from_prost};
35
36#[derive(Debug, Clone)]
42pub struct AggCall {
43 pub agg_type: AggType,
45
46 pub args: AggArgs,
48
49 pub return_type: DataType,
51
52 pub column_orders: Vec<ColumnOrder>,
54
55 pub filter: Option<BoxedExpression>,
57
58 pub distinct: bool,
60
61 pub direct_args: Vec<LiteralExpression>,
63}
64
65impl AggCall {
66 pub fn from_protobuf(agg_call: &PbAggCall) -> Result<Self> {
67 let agg_type = AggType::from_protobuf_flatten(
68 agg_call.get_kind()?,
69 agg_call.udf.as_ref(),
70 agg_call.scalar.as_ref(),
71 )?;
72 let args = AggArgs::from_protobuf(agg_call.get_args())?;
73 let column_orders = agg_call
74 .get_order_by()
75 .iter()
76 .map(|col_order| {
77 let col_idx = col_order.get_column_index() as usize;
78 let order_type = OrderType::from_protobuf(col_order.get_order_type().unwrap());
79 ColumnOrder::new(col_idx, order_type)
80 })
81 .collect();
82 let filter = match agg_call.filter {
83 Some(ref pb_filter) => Some(build_from_prost(pb_filter)?), None => None,
85 };
86 let direct_args = agg_call
87 .direct_args
88 .iter()
89 .map(|arg| {
90 let data_type = DataType::from(arg.get_type().unwrap());
91 LiteralExpression::new(
92 data_type.clone(),
93 Datum::from_protobuf(arg.get_datum().unwrap(), &data_type).unwrap(),
94 )
95 })
96 .collect_vec();
97 Ok(AggCall {
98 agg_type,
99 args,
100 return_type: DataType::from(agg_call.get_return_type()?),
101 column_orders,
102 filter,
103 distinct: agg_call.distinct,
104 direct_args,
105 })
106 }
107
108 pub fn from_pretty(s: impl AsRef<str>) -> Self {
116 let tokens = crate::expr::lexer(s.as_ref());
117 Parser::new(tokens.into_iter()).parse_aggregation()
118 }
119
120 pub fn with_filter(mut self, filter: BoxedExpression) -> Self {
121 self.filter = Some(filter);
122 self
123 }
124}
125
126struct Parser<Iter: Iterator> {
127 tokens: Peekable<Iter>,
128}
129
130impl<Iter: Iterator<Item = Token>> Parser<Iter> {
131 fn new(tokens: Iter) -> Self {
132 Self {
133 tokens: tokens.peekable(),
134 }
135 }
136
137 fn parse_aggregation(&mut self) -> AggCall {
138 assert_eq!(self.tokens.next(), Some(Token::LParen), "Expected a (");
139 let func = self.parse_function();
140 assert_eq!(self.tokens.next(), Some(Token::Colon), "Expected a Colon");
141 let ty = self.parse_type();
142
143 let mut distinct = false;
144 let mut children = Vec::new();
145 let mut column_orders = Vec::new();
146 while matches!(self.tokens.peek(), Some(Token::Index(_))) {
147 children.push(self.parse_arg());
148 }
149 if matches!(self.tokens.peek(), Some(Token::Literal(s)) if s == "distinct") {
150 distinct = true;
151 self.tokens.next(); }
153 if matches!(self.tokens.peek(), Some(Token::Literal(s)) if s == "orderby") {
154 self.tokens.next(); while matches!(self.tokens.peek(), Some(Token::Index(_))) {
156 column_orders.push(self.parse_orderkey());
157 }
158 }
159 self.tokens.next(); AggCall {
162 agg_type: AggType::from_protobuf_flatten(func, None, None).unwrap(),
163 args: AggArgs {
164 data_types: children.iter().map(|(_, ty)| ty.clone()).collect(),
165 val_indices: children.iter().map(|(idx, _)| *idx).collect(),
166 },
167 return_type: ty,
168 column_orders,
169 filter: None,
170 distinct,
171 direct_args: Vec::new(),
172 }
173 }
174
175 fn parse_type(&mut self) -> DataType {
176 match self.tokens.next().expect("Unexpected end of input") {
177 Token::Literal(name) => name.parse::<DataType>().expect_str("type", &name),
178 t => panic!("Expected a Literal, got {t:?}"),
179 }
180 }
181
182 fn parse_arg(&mut self) -> (usize, DataType) {
183 let idx = match self.tokens.next().expect("Unexpected end of input") {
184 Token::Index(idx) => idx,
185 t => panic!("Expected an Index, got {t:?}"),
186 };
187 assert_eq!(self.tokens.next(), Some(Token::Colon), "Expected a Colon");
188 let ty = self.parse_type();
189 (idx, ty)
190 }
191
192 fn parse_function(&mut self) -> PbAggKind {
193 match self.tokens.next().expect("Unexpected end of input") {
194 Token::Literal(name) => {
195 PbAggKind::from_str_name(&name.to_uppercase()).expect_str("function", &name)
196 }
197 t => panic!("Expected a Literal, got {t:?}"),
198 }
199 }
200
201 fn parse_orderkey(&mut self) -> ColumnOrder {
202 let idx = match self.tokens.next().expect("Unexpected end of input") {
203 Token::Index(idx) => idx,
204 t => panic!("Expected an Index, got {t:?}"),
205 };
206 assert_eq!(self.tokens.next(), Some(Token::Colon), "Expected a Colon");
207 let order = match self.tokens.next().expect("Unexpected end of input") {
208 Token::Literal(s) if s == "asc" => OrderType::ascending(),
209 Token::Literal(s) if s == "desc" => OrderType::descending(),
210 t => panic!("Expected asc or desc, got {t:?}"),
211 };
212 ColumnOrder::new(idx, order)
213 }
214}
215
216#[derive(Debug, Clone, PartialEq, Eq, Hash, EnumAsInner)]
218pub enum AggType {
219 Builtin(PbAggKind),
223
224 UserDefined(PbUserDefinedFunctionMetadata),
226
227 WrapScalar(PbExprNode),
229}
230
231impl Display for AggType {
232 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
233 match self {
234 Self::Builtin(kind) => write!(f, "{}", kind.as_str_name().to_lowercase()),
235 Self::UserDefined(_) => write!(f, "udaf"),
236 Self::WrapScalar(_) => write!(f, "wrap_scalar"),
237 }
238 }
239}
240
241impl FromStr for AggType {
243 type Err = ();
244
245 fn from_str(s: &str) -> Result<Self, Self::Err> {
246 let kind = PbAggKind::from_str(s)?;
247 Ok(AggType::Builtin(kind))
248 }
249}
250
251impl From<PbAggKind> for AggType {
252 fn from(pb: PbAggKind) -> Self {
253 assert!(!matches!(
254 pb,
255 PbAggKind::Unspecified | PbAggKind::UserDefined | PbAggKind::WrapScalar
256 ));
257 AggType::Builtin(pb)
258 }
259}
260
261impl AggType {
262 pub fn from_protobuf_flatten(
263 pb_kind: PbAggKind,
264 user_defined: Option<&PbUserDefinedFunctionMetadata>,
265 scalar: Option<&PbExprNode>,
266 ) -> Result<Self> {
267 match pb_kind {
268 PbAggKind::UserDefined => {
269 let user_defined = user_defined.context("expect user defined")?;
270 Ok(AggType::UserDefined(user_defined.clone()))
271 }
272 PbAggKind::WrapScalar => {
273 let scalar = scalar.context("expect scalar")?;
274 Ok(AggType::WrapScalar(scalar.clone()))
275 }
276 PbAggKind::Unspecified => bail!("Unrecognized agg."),
277 _ => Ok(AggType::Builtin(pb_kind)),
278 }
279 }
280
281 pub fn to_protobuf_simple(&self) -> PbAggKind {
282 match self {
283 Self::Builtin(pb) => *pb,
284 Self::UserDefined(_) => PbAggKind::UserDefined,
285 Self::WrapScalar(_) => PbAggKind::WrapScalar,
286 }
287 }
288
289 pub fn from_protobuf(pb_type: &PbAggType) -> Result<Self> {
290 match PbAggKind::try_from(pb_type.kind).context("no such aggregate function type")? {
291 PbAggKind::Unspecified => bail!("Unrecognized agg."),
292 PbAggKind::UserDefined => Ok(AggType::UserDefined(pb_type.get_udf_meta()?.clone())),
293 PbAggKind::WrapScalar => Ok(AggType::WrapScalar(pb_type.get_scalar_expr()?.clone())),
294 kind => Ok(AggType::Builtin(kind)),
295 }
296 }
297
298 pub fn to_protobuf(&self) -> PbAggType {
299 match self {
300 Self::Builtin(kind) => PbAggType {
301 kind: *kind as _,
302 udf_meta: None,
303 scalar_expr: None,
304 },
305 Self::UserDefined(udf_meta) => PbAggType {
306 kind: PbAggKind::UserDefined as _,
307 udf_meta: Some(udf_meta.clone()),
308 scalar_expr: None,
309 },
310 Self::WrapScalar(scalar_expr) => PbAggType {
311 kind: PbAggKind::WrapScalar as _,
312 udf_meta: None,
313 scalar_expr: Some(scalar_expr.clone()),
314 },
315 }
316 }
317}
318
319pub mod agg_types {
323 #[macro_export]
326 macro_rules! rewritten {
327 () => {
328 AggType::Builtin(
329 PbAggKind::Avg
330 | PbAggKind::StddevPop
331 | PbAggKind::StddevSamp
332 | PbAggKind::VarPop
333 | PbAggKind::VarSamp
334 | PbAggKind::Grouping
335 | PbAggKind::ApproxPercentile
338 | PbAggKind::ArgMin
339 | PbAggKind::ArgMax
340 )
341 };
342 }
343 pub use rewritten;
344
345 #[macro_export]
348 macro_rules! result_unaffected_by_order_by {
349 () => {
350 AggType::Builtin(PbAggKind::BitAnd
351 | PbAggKind::BitOr
352 | PbAggKind::BitXor | PbAggKind::BoolAnd
354 | PbAggKind::BoolOr
355 | PbAggKind::Min
356 | PbAggKind::Max
357 | PbAggKind::Sum
358 | PbAggKind::Sum0
359 | PbAggKind::Count
360 | PbAggKind::Avg
361 | PbAggKind::ApproxCountDistinct
362 | PbAggKind::VarPop
363 | PbAggKind::VarSamp
364 | PbAggKind::StddevPop
365 | PbAggKind::StddevSamp)
366 };
367 }
368 pub use result_unaffected_by_order_by;
369
370 #[macro_export]
374 macro_rules! must_have_order_by {
375 () => {
376 AggType::Builtin(
377 PbAggKind::FirstValue
378 | PbAggKind::LastValue
379 | PbAggKind::PercentileCont
380 | PbAggKind::PercentileDisc
381 | PbAggKind::Mode,
382 )
383 };
384 }
385 pub use must_have_order_by;
386
387 #[macro_export]
390 macro_rules! result_unaffected_by_distinct {
391 () => {
392 AggType::Builtin(
393 PbAggKind::BitAnd
394 | PbAggKind::BitOr
395 | PbAggKind::BoolAnd
396 | PbAggKind::BoolOr
397 | PbAggKind::Min
398 | PbAggKind::Max
399 | PbAggKind::ApproxCountDistinct,
400 )
401 };
402 }
403 pub use result_unaffected_by_distinct;
404
405 #[macro_export]
407 macro_rules! simply_cannot_two_phase {
408 () => {
409 AggType::Builtin(
410 PbAggKind::StringAgg
411 | PbAggKind::ApproxCountDistinct
412 | PbAggKind::ArrayAgg
413 | PbAggKind::JsonbAgg
414 | PbAggKind::JsonbObjectAgg
415 | PbAggKind::FirstValue
416 | PbAggKind::LastValue
417 | PbAggKind::PercentileCont
418 | PbAggKind::PercentileDisc
419 | PbAggKind::Mode
420 | PbAggKind::BoolAnd
423 | PbAggKind::BoolOr
424 | PbAggKind::BitAnd
425 | PbAggKind::BitOr
426 )
427 | AggType::UserDefined(_)
428 | AggType::WrapScalar(_)
429 };
430 }
431 pub use simply_cannot_two_phase;
432
433 #[macro_export]
436 macro_rules! single_value_state {
437 () => {
438 AggType::Builtin(
439 PbAggKind::Sum
440 | PbAggKind::Sum0
441 | PbAggKind::Count
442 | PbAggKind::BitAnd
443 | PbAggKind::BitOr
444 | PbAggKind::BitXor
445 | PbAggKind::BoolAnd
446 | PbAggKind::BoolOr
447 | PbAggKind::ApproxCountDistinct
448 | PbAggKind::InternalLastSeenValue
449 | PbAggKind::ApproxPercentile,
450 ) | AggType::UserDefined(_)
451 };
452 }
453 pub use single_value_state;
454
455 #[macro_export]
458 macro_rules! single_value_state_iff_in_append_only {
459 () => {
460 AggType::Builtin(PbAggKind::Max | PbAggKind::Min)
461 };
462 }
463 pub use single_value_state_iff_in_append_only;
464
465 #[macro_export]
467 macro_rules! materialized_input_state {
468 () => {
469 AggType::Builtin(
470 PbAggKind::Min
471 | PbAggKind::Max
472 | PbAggKind::FirstValue
473 | PbAggKind::LastValue
474 | PbAggKind::StringAgg
475 | PbAggKind::ArrayAgg
476 | PbAggKind::JsonbAgg
477 | PbAggKind::JsonbObjectAgg
478 | PbAggKind::PercentileCont
479 | PbAggKind::PercentileDisc
480 | PbAggKind::Mode,
481 ) | AggType::WrapScalar(_)
482 };
483 }
484 pub use materialized_input_state;
485
486 #[macro_export]
488 macro_rules! ordered_set {
489 () => {
490 AggType::Builtin(
491 PbAggKind::PercentileCont
492 | PbAggKind::PercentileDisc
493 | PbAggKind::Mode
494 | PbAggKind::ApproxPercentile,
495 )
496 };
497 }
498 pub use ordered_set;
499}
500
501impl AggType {
502 pub fn partial_to_total(&self) -> Option<Self> {
504 match self {
505 AggType::Builtin(
506 PbAggKind::BitXor
507 | PbAggKind::Min
508 | PbAggKind::Max
509 | PbAggKind::Sum
510 | PbAggKind::InternalLastSeenValue,
511 ) => Some(self.clone()),
512 AggType::Builtin(PbAggKind::Sum0 | PbAggKind::Count) => {
513 Some(Self::Builtin(PbAggKind::Sum0))
514 }
515 agg_types::simply_cannot_two_phase!() => None,
516 agg_types::rewritten!() => None,
517 AggType::Builtin(
519 PbAggKind::Unspecified | PbAggKind::UserDefined | PbAggKind::WrapScalar,
520 ) => None,
521 }
522 }
523}
524
525#[derive(Clone, Debug, Default)]
527pub struct AggArgs {
528 data_types: Box<[DataType]>,
529 val_indices: Box<[usize]>,
530}
531
532impl AggArgs {
533 pub fn from_protobuf(args: &[PbInputRef]) -> Result<Self> {
534 Ok(AggArgs {
535 data_types: args
536 .iter()
537 .map(|arg| DataType::from(arg.get_type().unwrap()))
538 .collect(),
539 val_indices: args.iter().map(|arg| arg.get_index() as usize).collect(),
540 })
541 }
542
543 pub fn arg_types(&self) -> &[DataType] {
545 &self.data_types
546 }
547
548 pub fn val_indices(&self) -> &[usize] {
550 &self.val_indices
551 }
552}
553
554impl FromIterator<(DataType, usize)> for AggArgs {
555 fn from_iter<T: IntoIterator<Item = (DataType, usize)>>(iter: T) -> Self {
556 let (data_types, val_indices): (Vec<_>, Vec<_>) = iter.into_iter().unzip();
557 AggArgs {
558 data_types: data_types.into(),
559 val_indices: val_indices.into(),
560 }
561 }
562}