1use std::hash::{Hash, Hasher};
26use std::sync::Arc;
27
28use arrow::array::{ArrayRef, BooleanArray, StructArray};
29use arrow_schema::{FieldRef, Fields};
30use common_telemetry::debug;
31use datafusion::functions_aggregate::all_default_aggregate_functions;
32use datafusion::functions_aggregate::count::Count;
33use datafusion::functions_aggregate::min_max::{Max, Min};
34use datafusion::optimizer::AnalyzerRule;
35use datafusion::optimizer::analyzer::type_coercion::TypeCoercion;
36use datafusion_common::{Column, ScalarValue};
37use datafusion_expr::expr::{AggregateFunction, AggregateFunctionParams};
38use datafusion_expr::function::StateFieldsArgs;
39use datafusion_expr::physical_planning_context::PhysicalPlanningContext;
40use datafusion_expr::{
41 Accumulator, Aggregate, AggregateUDF, AggregateUDFImpl, EmitTo, Expr, ExprSchemable,
42 GroupsAccumulator, LogicalPlan, Signature,
43};
44use datafusion_physical_expr::aggregate::{AggregateFunctionExpr, LoweredAggregateBuilder};
45use datatypes::arrow::datatypes::{DataType, Field};
46
47use crate::aggrs::aggr_wrapper::fix_order::FixStateUdafOrderingAnalyzer;
48use crate::function_registry::{FUNCTION_REGISTRY, FunctionRegistry};
49
50pub mod fix_order;
51#[cfg(test)]
52mod tests;
53
54pub fn aggr_state_func_name(aggr_name: &str) -> String {
58 format!("__{}_state", aggr_name)
59}
60
61pub fn aggr_merge_func_name(aggr_name: &str) -> String {
65 format!("__{}_merge", aggr_name)
66}
67
68pub fn aggr_delta_merge_func_name(state_aggregate_name: &str) -> String {
71 format!("__{}_delta_merge", state_aggregate_name)
72}
73
74pub fn is_all_aggr_exprs_steppable(aggr_exprs: &[Expr]) -> bool {
79 aggr_exprs.iter().all(|expr| {
80 if let Some(aggr_func) = get_aggr_func(expr) {
81 if aggr_func.params.distinct {
82 return false;
85 }
86
87 FUNCTION_REGISTRY.is_aggr_func_exist(&aggr_state_func_name(aggr_func.func.name()))
89 } else {
90 false
91 }
92 })
93}
94
95pub fn get_aggr_func(expr: &Expr) -> Option<&datafusion_expr::expr::AggregateFunction> {
96 let mut expr_ref = expr;
97 while let Expr::Alias(alias) = expr_ref {
98 expr_ref = &alias.expr;
99 }
100 if let Expr::AggregateFunction(aggr_func) = expr_ref {
101 Some(aggr_func)
102 } else {
103 None
104 }
105}
106
107#[derive(Debug, Clone)]
112pub struct StateMergeHelper;
113
114#[allow(unused)]
116#[derive(Debug, Clone)]
117pub struct StepAggrPlan {
118 pub upper_merge: LogicalPlan,
120 pub lower_state: LogicalPlan,
122}
123
124impl StateMergeHelper {
125 pub fn register(registry: &FunctionRegistry) {
128 let all_default = all_default_aggregate_functions();
129 let greptime_custom_aggr_functions = registry.aggregate_functions();
130
131 let supported = all_default
133 .into_iter()
134 .chain(greptime_custom_aggr_functions.into_iter().map(Arc::new))
135 .collect::<Vec<_>>();
136 debug!(
137 "Registering state functions for supported: {:?}",
138 supported.iter().map(|f| f.name()).collect::<Vec<_>>()
139 );
140
141 let state_func = supported.into_iter().filter_map(|f| {
142 StateWrapper::new((*f).clone())
143 .inspect_err(
144 |e| common_telemetry::error!(e; "Failed to register state function for {:?}", f),
145 )
146 .ok()
147 .map(AggregateUDF::new_from_impl)
148 });
149
150 for func in state_func {
151 registry.register_aggr(func);
152 }
153 }
154
155 pub fn split_aggr_node(aggr_plan: Aggregate) -> datafusion_common::Result<StepAggrPlan> {
158 let aggr = {
159 let aggr_plan = TypeCoercion::new().analyze(
161 LogicalPlan::Aggregate(aggr_plan).clone(),
162 &Default::default(),
163 )?;
164 if let LogicalPlan::Aggregate(aggr) = aggr_plan {
165 aggr
166 } else {
167 return Err(datafusion_common::DataFusionError::Internal(format!(
168 "Failed to coerce expressions in aggregate plan, expected Aggregate, got: {:?}",
169 aggr_plan
170 )));
171 }
172 };
173 let mut lower_aggr_exprs = vec![];
174 let mut upper_aggr_exprs = vec![];
175
176 let upper_group_exprs = aggr
179 .group_expr
180 .iter()
181 .map(|c| c.qualified_name())
182 .map(|(r, c)| Expr::Column(Column::new(r, c)))
183 .collect();
184
185 for aggr_expr in aggr.aggr_expr.iter() {
186 let Some(aggr_func) = get_aggr_func(aggr_expr) else {
187 return Err(datafusion_common::DataFusionError::NotImplemented(format!(
188 "Unsupported aggregate expression for step aggr optimize: {:?}",
189 aggr_expr
190 )));
191 };
192
193 let original_input_fields = aggr_func
194 .params
195 .args
196 .iter()
197 .map(|e| e.to_field(&aggr.input.schema()).map(|(_, field)| field))
198 .collect::<Result<Vec<_>, _>>()?;
199
200 let state_func = StateWrapper::new((*aggr_func.func).clone())?;
202
203 let expr = AggregateFunction {
204 func: Arc::new(state_func.into()),
205 params: aggr_func.params.clone(),
206 };
207 let expr = Expr::AggregateFunction(expr);
208 let lower_state_output_col_name = expr.schema_name().to_string();
209
210 lower_aggr_exprs.push(expr);
211
212 let (name, human_display) = match aggr_expr {
214 Expr::Alias(alias) => (alias.name.clone(), aggr_expr.human_display().to_string()),
215 Expr::AggregateFunction(_) => (
216 aggr_expr.schema_name().to_string(),
217 aggr_expr.human_display().to_string(),
218 ),
219 _ => unreachable!("aggregate expression was validated above"),
220 };
221 let original_phy_expr = LoweredAggregateBuilder::new(
222 aggr_expr,
223 aggr.input.schema(),
224 aggr.input.schema().as_arrow(),
225 &Default::default(),
226 &PhysicalPlanningContext::default(),
227 )
228 .with_name(name)
229 .with_human_display(human_display)
230 .build()?
231 .aggregate;
232
233 let merge_func = MergeWrapper::new(
234 (*aggr_func.func).clone(),
235 original_phy_expr,
236 original_input_fields,
237 )?;
238 let arg = Expr::Column(Column::new_unqualified(lower_state_output_col_name));
239 let expr = AggregateFunction {
240 func: Arc::new(merge_func.into()),
241 params: AggregateFunctionParams {
245 args: vec![arg],
246 distinct: aggr_func.params.distinct,
247 filter: None,
248 order_by: vec![],
249 null_treatment: aggr_func.params.null_treatment,
250 },
251 };
252
253 let expr = Expr::AggregateFunction(expr).alias(aggr_expr.schema_name().to_string());
256 upper_aggr_exprs.push(expr);
257 }
258
259 let mut lower = aggr.clone();
260 lower.aggr_expr = lower_aggr_exprs;
261 let lower_plan = LogicalPlan::Aggregate(lower);
262
263 let lower_plan = lower_plan.recompute_schema()?;
265
266 let fixed_lower_plan =
269 FixStateUdafOrderingAnalyzer.analyze(lower_plan, &Default::default())?;
270
271 let upper = Aggregate::try_new(
272 Arc::new(fixed_lower_plan.clone()),
273 upper_group_exprs,
274 upper_aggr_exprs.clone(),
275 )?;
276 let aggr_plan = LogicalPlan::Aggregate(aggr);
277
278 let upper_check = upper;
280 let upper_plan = LogicalPlan::Aggregate(upper_check).recompute_schema()?;
281 if *upper_plan.schema() != *aggr_plan.schema() {
282 return Err(datafusion_common::DataFusionError::Internal(format!(
283 "Upper aggregate plan's schema is not the same as the original aggregate plan's schema: \n[transformed]:{}\n[original]:{}",
284 upper_plan.schema(),
285 aggr_plan.schema()
286 )));
287 }
288
289 Ok(StepAggrPlan {
290 lower_state: fixed_lower_plan,
291 upper_merge: upper_plan,
292 })
293 }
294}
295
296#[derive(Debug, Clone, PartialEq, Eq, Hash)]
298pub struct StateWrapper {
299 inner: AggregateUDF,
300 name: String,
301 ordering: Vec<FieldRef>,
303 distinct: bool,
305}
306
307impl StateWrapper {
308 pub fn new(inner: AggregateUDF) -> datafusion_common::Result<Self> {
310 let name = aggr_state_func_name(inner.name());
311 Ok(Self {
312 inner,
313 name,
314 ordering: vec![],
315 distinct: false,
316 })
317 }
318
319 pub fn inner(&self) -> &AggregateUDF {
320 &self.inner
321 }
322
323 pub fn deduce_aggr_return_type(
327 &self,
328 acc_args: &datafusion_expr::function::AccumulatorArgs,
329 ) -> datafusion_common::Result<FieldRef> {
330 let input_fields = acc_args
331 .exprs
332 .iter()
333 .map(|e| e.return_field(acc_args.schema))
334 .collect::<Result<Vec<_>, _>>()?;
335 self.inner.return_field(&input_fields).inspect_err(|e| {
336 common_telemetry::error!(
337 "StateWrapper: {:#?}\nacc_args:{:?}\nerror:{:?}",
338 &self,
339 &acc_args,
340 e
341 );
342 })
343 }
344
345 fn fix_inner_acc_args<'b>(
346 &self,
347 mut acc_args: datafusion_expr::function::AccumulatorArgs<'b>,
348 ) -> datafusion_common::Result<datafusion_expr::function::AccumulatorArgs<'b>> {
349 acc_args.return_field = self.deduce_aggr_return_type(&acc_args)?;
350 Ok(acc_args)
351 }
352}
353
354impl AggregateUDFImpl for StateWrapper {
355 fn accumulator<'a, 'b>(
356 &'a self,
357 acc_args: datafusion_expr::function::AccumulatorArgs<'b>,
358 ) -> datafusion_common::Result<Box<dyn Accumulator>> {
359 let state_type = acc_args.return_type().clone();
361 let inner = self.inner.accumulator(self.fix_inner_acc_args(acc_args)?)?;
362
363 Ok(Box::new(StateAccum::new(inner, state_type)?))
364 }
365
366 fn groups_accumulator_supported(
367 &self,
368 acc_args: datafusion_expr::function::AccumulatorArgs,
369 ) -> bool {
370 self.fix_inner_acc_args(acc_args)
371 .map(|args| self.inner.inner().groups_accumulator_supported(args))
372 .unwrap_or(false)
373 }
374
375 fn create_groups_accumulator(
376 &self,
377 acc_args: datafusion_expr::function::AccumulatorArgs,
378 ) -> datafusion_common::Result<Box<dyn GroupsAccumulator>> {
379 let state_type = acc_args.return_type().clone();
380 let inner = self
381 .inner
382 .inner()
383 .create_groups_accumulator(self.fix_inner_acc_args(acc_args)?)?;
384 Ok(Box::new(StateGroupsAccum::new(inner, state_type)?))
385 }
386
387 fn name(&self) -> &str {
388 self.name.as_str()
389 }
390
391 fn is_nullable(&self) -> bool {
392 self.inner.is_nullable()
393 }
394
395 fn return_type(&self, arg_types: &[DataType]) -> datafusion_common::Result<DataType> {
398 let input_fields = &arg_types
399 .iter()
400 .map(|x| Arc::new(Field::new("x", x.clone(), false)))
401 .collect::<Vec<_>>();
402
403 let state_fields_args = StateFieldsArgs {
404 name: self.inner().name(),
405 input_fields,
406 return_field: self.inner.return_field(input_fields)?,
407 ordering_fields: &self.ordering,
409 is_distinct: self.distinct,
410 };
411 let state_fields = self.inner.state_fields(state_fields_args)?;
412
413 let state_fields = state_fields
414 .into_iter()
415 .map(|f| {
416 let mut f = f.as_ref().clone();
417 f.set_nullable(true);
419 Arc::new(f)
420 })
421 .collect::<Vec<_>>();
422
423 let struct_field = DataType::Struct(state_fields.into());
424 Ok(struct_field)
425 }
426
427 fn state_fields(
429 &self,
430 args: datafusion_expr::function::StateFieldsArgs,
431 ) -> datafusion_common::Result<Vec<FieldRef>> {
432 let state_fields_args = StateFieldsArgs {
433 name: args.name,
434 input_fields: args.input_fields,
435 return_field: self.inner.return_field(args.input_fields)?,
436 ordering_fields: args.ordering_fields,
437 is_distinct: args.is_distinct,
438 };
439 self.inner.state_fields(state_fields_args)
440 }
441
442 fn signature(&self) -> &Signature {
444 self.inner.signature()
445 }
446
447 fn coerce_types(&self, arg_types: &[DataType]) -> datafusion_common::Result<Vec<DataType>> {
449 self.inner.coerce_types(arg_types)
450 }
451
452 fn value_from_stats(
453 &self,
454 statistics_args: &datafusion_expr::StatisticsArgs,
455 ) -> Option<ScalarValue> {
456 let inner = self.inner().inner();
457 let can_use_stat = inner.is::<Count>() || inner.is::<Max>() || inner.is::<Min>();
460 if !can_use_stat {
461 return None;
462 }
463
464 let state_type = if let DataType::Struct(fields) = &statistics_args.return_type {
466 if fields.is_empty() {
467 return None;
468 }
469 fields[0].data_type().clone()
470 } else {
471 return None;
472 };
473
474 let fixed_args = datafusion_expr::StatisticsArgs {
475 statistics: statistics_args.statistics,
476 return_type: &state_type,
477 is_distinct: statistics_args.is_distinct,
478 exprs: statistics_args.exprs,
479 };
480
481 let ret = self.inner().value_from_stats(&fixed_args)?;
482
483 let fields = if let DataType::Struct(fields) = &statistics_args.return_type {
485 fields
486 } else {
487 return None;
488 };
489
490 let array = ret.to_array().ok()?;
491
492 let struct_array = StructArray::new(fields.clone(), vec![array], None);
493 let ret = ScalarValue::Struct(Arc::new(struct_array));
494 Some(ret)
495 }
496}
497
498#[derive(Debug)]
501pub struct StateAccum {
502 inner: Box<dyn Accumulator>,
503 state_fields: Fields,
504}
505
506pub struct StateGroupsAccum {
507 inner: Box<dyn GroupsAccumulator>,
508 state_fields: Fields,
509}
510
511impl StateGroupsAccum {
512 fn new(
513 inner: Box<dyn GroupsAccumulator>,
514 state_type: DataType,
515 ) -> datafusion_common::Result<Self> {
516 let DataType::Struct(fields) = state_type else {
517 return Err(datafusion_common::DataFusionError::Internal(format!(
518 "Expected a struct type for state, got: {:?}",
519 state_type
520 )));
521 };
522 Ok(Self {
523 inner,
524 state_fields: fields,
525 })
526 }
527
528 fn wrap_state_arrays(&self, arrays: Vec<ArrayRef>) -> datafusion_common::Result<ArrayRef> {
529 let array_type = arrays
530 .iter()
531 .map(|array| array.data_type().clone())
532 .collect::<Vec<_>>();
533 let expected_type = self
534 .state_fields
535 .iter()
536 .map(|field| field.data_type().clone())
537 .collect::<Vec<_>>();
538 if array_type != expected_type {
539 debug!(
540 "State mismatch, expected: {}, got: {} for expected fields: {:?} and given array types: {:?}",
541 self.state_fields.len(),
542 arrays.len(),
543 self.state_fields,
544 array_type,
545 );
546 let guess_schema = arrays
547 .iter()
548 .enumerate()
549 .map(|(index, array)| {
550 Field::new(
551 format!("col_{index}[mismatch_state]").as_str(),
552 array.data_type().clone(),
553 true,
554 )
555 })
556 .collect::<Fields>();
557 let array = StructArray::try_new(guess_schema, arrays, None)?;
558 return Ok(Arc::new(array));
559 }
560
561 Ok(Arc::new(StructArray::try_new(
562 self.state_fields.clone(),
563 arrays,
564 None,
565 )?))
566 }
567}
568
569impl GroupsAccumulator for StateGroupsAccum {
570 fn update_batch(
571 &mut self,
572 values: &[ArrayRef],
573 group_indices: &[usize],
574 opt_filter: Option<&BooleanArray>,
575 total_num_groups: usize,
576 ) -> datafusion_common::Result<()> {
577 self.inner
578 .update_batch(values, group_indices, opt_filter, total_num_groups)
579 }
580
581 fn merge_batch(
582 &mut self,
583 values: &[ArrayRef],
584 group_indices: &[usize],
585 total_num_groups: usize,
586 ) -> datafusion_common::Result<()> {
587 self.inner
588 .merge_batch(values, group_indices, total_num_groups)
589 }
590
591 fn evaluate(&mut self, emit_to: EmitTo) -> datafusion_common::Result<ArrayRef> {
592 let state = self.inner.state(emit_to)?;
593 self.wrap_state_arrays(state)
594 }
595
596 fn state(&mut self, emit_to: EmitTo) -> datafusion_common::Result<Vec<ArrayRef>> {
597 self.inner.state(emit_to)
598 }
599
600 fn convert_to_state(
601 &self,
602 values: &[ArrayRef],
603 opt_filter: Option<&BooleanArray>,
604 ) -> datafusion_common::Result<Vec<ArrayRef>> {
605 self.inner.convert_to_state(values, opt_filter)
606 }
607
608 fn size(&self) -> usize {
609 self.inner.size()
610 }
611}
612
613impl StateAccum {
614 pub fn new(
615 inner: Box<dyn Accumulator>,
616 state_type: DataType,
617 ) -> datafusion_common::Result<Self> {
618 let DataType::Struct(fields) = state_type else {
619 return Err(datafusion_common::DataFusionError::Internal(format!(
620 "Expected a struct type for state, got: {:?}",
621 state_type
622 )));
623 };
624 Ok(Self {
625 inner,
626 state_fields: fields,
627 })
628 }
629}
630
631impl Accumulator for StateAccum {
632 fn evaluate(&mut self) -> datafusion_common::Result<ScalarValue> {
633 let state = self.inner.state()?;
634
635 let array = state
636 .iter()
637 .map(|s| s.to_array())
638 .collect::<Result<Vec<_>, _>>()?;
639 let array_type = array
640 .iter()
641 .map(|a| a.data_type().clone())
642 .collect::<Vec<_>>();
643 let expected_type: Vec<_> = self
644 .state_fields
645 .iter()
646 .map(|f| f.data_type().clone())
647 .collect();
648 if array_type != expected_type {
649 debug!(
650 "State mismatch, expected: {}, got: {} for expected fields: {:?} and given array types: {:?}",
651 self.state_fields.len(),
652 array.len(),
653 self.state_fields,
654 array_type,
655 );
656 let guess_schema = array
657 .iter()
658 .enumerate()
659 .map(|(index, array)| {
660 Field::new(
661 format!("col_{index}[mismatch_state]").as_str(),
662 array.data_type().clone(),
663 true,
664 )
665 })
666 .collect::<Fields>();
667 let arr = StructArray::try_new(guess_schema, array, None)?;
668
669 return Ok(ScalarValue::Struct(Arc::new(arr)));
670 }
671
672 let struct_array = StructArray::try_new(self.state_fields.clone(), array, None)?;
673 Ok(ScalarValue::Struct(Arc::new(struct_array)))
674 }
675
676 fn merge_batch(
677 &mut self,
678 states: &[datatypes::arrow::array::ArrayRef],
679 ) -> datafusion_common::Result<()> {
680 self.inner.merge_batch(states)
681 }
682
683 fn update_batch(
684 &mut self,
685 values: &[datatypes::arrow::array::ArrayRef],
686 ) -> datafusion_common::Result<()> {
687 self.inner.update_batch(values)
688 }
689
690 fn size(&self) -> usize {
691 self.inner.size()
692 }
693
694 fn state(&mut self) -> datafusion_common::Result<Vec<ScalarValue>> {
695 self.inner.state()
696 }
697}
698
699#[derive(Debug, Clone)]
706pub(crate) struct DeltaMergeWrapper {
707 inner: AggregateUDF,
708 name: String,
709 signature: Signature,
710 inner_types: Vec<DataType>,
711 state_type: DataType,
712}
713
714impl DeltaMergeWrapper {
715 pub(crate) fn new(
720 inner: AggregateUDF,
721 state_name: &str,
722 inner_types: Vec<DataType>,
723 state_type: DataType,
724 ) -> Self {
725 let mut wrapper_types = inner_types.clone();
726 wrapper_types.push(state_type.clone());
727 Self {
728 name: aggr_delta_merge_func_name(state_name),
729 signature: Signature::exact(wrapper_types, inner.signature().volatility),
730 inner,
731 inner_types,
732 state_type,
733 }
734 }
735
736 fn resolve_inner_args(
737 &self,
738 input_fields: &[FieldRef],
739 ) -> datafusion_common::Result<Vec<FieldRef>> {
740 if input_fields.len() != self.inner_types.len() + 1 {
741 return Err(datafusion_common::DataFusionError::Plan(
742 "delta merge requires parameters, delta state, and persisted state".to_string(),
743 ));
744 }
745 for (field, expected_type) in input_fields[..self.inner_types.len()]
746 .iter()
747 .zip(&self.inner_types)
748 {
749 if field.data_type() != expected_type {
750 return Err(datafusion_common::DataFusionError::Plan(format!(
751 "delta merge argument type does not match its exact signature: {:?} != {expected_type:?}",
752 field.data_type()
753 )));
754 }
755 }
756 let persisted = &input_fields[self.inner_types.len()];
757 if persisted.data_type() != &self.state_type && persisted.data_type() != &DataType::Null {
758 return Err(datafusion_common::DataFusionError::Plan(format!(
759 "persisted state type does not match the exact state type: {:?} != {:?}",
760 persisted.data_type(),
761 self.state_type
762 )));
763 }
764 Ok(input_fields[..self.inner_types.len()].to_vec())
765 }
766}
767
768impl AggregateUDFImpl for DeltaMergeWrapper {
769 fn accumulator<'a, 'b>(
770 &'a self,
771 acc_args: datafusion_expr::function::AccumulatorArgs<'b>,
772 ) -> datafusion_common::Result<Box<dyn Accumulator>> {
773 if acc_args.exprs.len() != acc_args.expr_fields.len() {
774 return Err(datafusion_common::DataFusionError::Plan(
775 "delta merge expression and field arities differ".to_string(),
776 ));
777 }
778 let inner_fields = self.resolve_inner_args(acc_args.expr_fields)?;
779 for (expr, expected_type) in acc_args.exprs.iter().zip(
780 self.inner_types
781 .iter()
782 .chain(std::iter::once(&self.state_type)),
783 ) {
784 if expr.data_type(acc_args.schema)? != *expected_type {
785 return Err(datafusion_common::DataFusionError::Internal(
786 "delta merge physical expression type is not resolved".to_string(),
787 ));
788 }
789 }
790 let state_index = self.inner_types.len() - 1;
791 let inner_args = datafusion_expr::function::AccumulatorArgs {
792 return_field: acc_args.return_field,
793 schema: acc_args.schema,
794 ignore_nulls: acc_args.ignore_nulls,
795 order_bys: acc_args.order_bys,
796 is_reversed: acc_args.is_reversed,
797 name: self.inner.name(),
798 is_distinct: acc_args.is_distinct,
799 exprs: &acc_args.exprs[..=state_index],
800 expr_fields: &inner_fields,
801 };
802 Ok(Box::new(DeltaMergeAccum {
803 inner: self.inner.accumulator(inner_args)?,
804 params: state_index,
805 }))
806 }
807
808 fn name(&self) -> &str {
809 &self.name
810 }
811
812 fn is_nullable(&self) -> bool {
813 self.inner.is_nullable()
814 }
815
816 fn return_type(&self, arg_types: &[DataType]) -> datafusion_common::Result<DataType> {
817 let fields = arg_types
818 .iter()
819 .enumerate()
820 .map(|(index, data_type)| {
821 Arc::new(Field::new(index.to_string(), data_type.clone(), true))
822 })
823 .collect::<Vec<_>>();
824 let inner_fields = self.resolve_inner_args(&fields)?;
825 self.inner.return_type(
826 &inner_fields
827 .iter()
828 .map(|field| field.data_type().clone())
829 .collect::<Vec<_>>(),
830 )
831 }
832
833 fn return_field(&self, arg_fields: &[FieldRef]) -> datafusion_common::Result<FieldRef> {
834 let inner_fields = self.resolve_inner_args(arg_fields)?;
835 self.inner.return_field(&inner_fields)
836 }
837
838 fn signature(&self) -> &Signature {
839 &self.signature
840 }
841
842 fn state_fields(
843 &self,
844 args: datafusion_expr::function::StateFieldsArgs,
845 ) -> datafusion_common::Result<Vec<FieldRef>> {
846 let inner_fields = self.resolve_inner_args(args.input_fields)?;
847 self.inner
848 .state_fields(datafusion_expr::function::StateFieldsArgs {
849 name: args.name,
850 input_fields: &inner_fields,
851 return_field: args.return_field,
852 ordering_fields: args.ordering_fields,
853 is_distinct: args.is_distinct,
854 })
855 }
856}
857
858impl PartialEq for DeltaMergeWrapper {
859 fn eq(&self, other: &Self) -> bool {
860 self.name == other.name && self.inner == other.inner
861 }
862}
863impl Eq for DeltaMergeWrapper {}
864impl Hash for DeltaMergeWrapper {
865 fn hash<H: Hasher>(&self, state: &mut H) {
866 self.name.hash(state);
867 self.inner.hash(state);
868 }
869}
870
871#[derive(Debug)]
872struct DeltaMergeAccum {
873 inner: Box<dyn Accumulator>,
874 params: usize,
875}
876
877impl Accumulator for DeltaMergeAccum {
878 fn evaluate(&mut self) -> datafusion_common::Result<ScalarValue> {
879 self.inner.evaluate()
880 }
881
882 fn update_batch(&mut self, values: &[ArrayRef]) -> datafusion_common::Result<()> {
883 if values.len() != self.params + 2 {
884 return Err(datafusion_common::DataFusionError::Plan(format!(
885 "delta merge expected {} arguments, got {}",
886 self.params + 2,
887 values.len()
888 )));
889 }
890 let mut inner_values = values[..self.params + 1].to_vec();
893 self.inner.update_batch(&inner_values)?;
894 inner_values[self.params] = values[self.params + 1].clone();
895 self.inner.update_batch(&inner_values)
896 }
897
898 fn merge_batch(&mut self, states: &[ArrayRef]) -> datafusion_common::Result<()> {
899 self.inner.merge_batch(states)
900 }
901
902 fn size(&self) -> usize {
903 self.inner.size()
904 }
905
906 fn state(&mut self) -> datafusion_common::Result<Vec<ScalarValue>> {
907 self.inner.state()
908 }
909}
910
911#[derive(Debug, Clone)]
916pub struct MergeWrapper {
917 inner: AggregateUDF,
918 name: String,
919 merge_signature: Signature,
920 original_phy_expr: Arc<AggregateFunctionExpr>,
922 return_field: FieldRef,
923}
924impl MergeWrapper {
925 pub fn new(
926 inner: AggregateUDF,
927 original_phy_expr: Arc<AggregateFunctionExpr>,
928 original_input_fields: Vec<FieldRef>,
929 ) -> datafusion_common::Result<Self> {
930 let name = aggr_merge_func_name(inner.name());
931 let merge_signature = Signature::user_defined(datafusion_expr::Volatility::Immutable);
933 let return_field = inner.return_field(&original_input_fields)?.clone();
934
935 Ok(Self {
936 inner,
937 name,
938 merge_signature,
939 original_phy_expr,
940 return_field,
941 })
942 }
943
944 pub fn inner(&self) -> &AggregateUDF {
945 &self.inner
946 }
947}
948
949impl AggregateUDFImpl for MergeWrapper {
950 fn accumulator<'a, 'b>(
951 &'a self,
952 acc_args: datafusion_expr::function::AccumulatorArgs<'b>,
953 ) -> datafusion_common::Result<Box<dyn Accumulator>> {
954 if acc_args.exprs.len() != 1
955 || !matches!(
956 acc_args.exprs[0].data_type(acc_args.schema)?,
957 DataType::Struct(_)
958 )
959 {
960 return Err(datafusion_common::DataFusionError::Internal(format!(
961 "Expected one struct type as input, got: {:?}",
962 acc_args.schema
963 )));
964 }
965 let input_type = acc_args.exprs[0].data_type(acc_args.schema)?;
966 let DataType::Struct(fields) = input_type else {
967 return Err(datafusion_common::DataFusionError::Internal(format!(
968 "Expected a struct type for input, got: {:?}",
969 input_type
970 )));
971 };
972
973 let inner_accum = self.original_phy_expr.create_accumulator()?;
974 Ok(Box::new(MergeAccum::new(inner_accum, &fields)))
975 }
976
977 fn name(&self) -> &str {
978 self.name.as_str()
979 }
980
981 fn is_nullable(&self) -> bool {
982 self.inner.is_nullable()
983 }
984
985 fn return_type(&self, _arg_types: &[DataType]) -> datafusion_common::Result<DataType> {
988 Ok(self.return_field.data_type().clone())
990 }
991
992 fn return_field(&self, _arg_fields: &[FieldRef]) -> datafusion_common::Result<FieldRef> {
994 Ok(self.return_field.clone())
995 }
996
997 fn signature(&self) -> &Signature {
998 &self.merge_signature
999 }
1000
1001 fn coerce_types(&self, arg_types: &[DataType]) -> datafusion_common::Result<Vec<DataType>> {
1003 if arg_types.len() != 1 || !matches!(arg_types.first(), Some(DataType::Struct(_))) {
1005 return Err(datafusion_common::DataFusionError::Internal(format!(
1006 "Expected one struct type as input, got: {:?}",
1007 arg_types
1008 )));
1009 }
1010 Ok(arg_types.to_vec())
1011 }
1012
1013 fn state_fields(
1015 &self,
1016 _args: datafusion_expr::function::StateFieldsArgs,
1017 ) -> datafusion_common::Result<Vec<FieldRef>> {
1018 self.original_phy_expr.state_fields()
1019 }
1020}
1021
1022impl PartialEq for MergeWrapper {
1023 fn eq(&self, other: &Self) -> bool {
1024 self.inner == other.inner
1025 }
1026}
1027
1028impl Eq for MergeWrapper {}
1029
1030impl Hash for MergeWrapper {
1031 fn hash<H: Hasher>(&self, state: &mut H) {
1032 self.inner.hash(state);
1033 }
1034}
1035
1036#[derive(Debug)]
1040pub struct MergeAccum {
1041 inner: Box<dyn Accumulator>,
1042 state_fields: Fields,
1043}
1044
1045impl MergeAccum {
1046 pub fn new(inner: Box<dyn Accumulator>, state_fields: &Fields) -> Self {
1047 Self {
1048 inner,
1049 state_fields: state_fields.clone(),
1050 }
1051 }
1052}
1053
1054impl Accumulator for MergeAccum {
1055 fn evaluate(&mut self) -> datafusion_common::Result<ScalarValue> {
1056 self.inner.evaluate()
1057 }
1058
1059 fn merge_batch(&mut self, states: &[arrow::array::ArrayRef]) -> datafusion_common::Result<()> {
1060 self.inner.merge_batch(states)
1061 }
1062
1063 fn update_batch(&mut self, values: &[arrow::array::ArrayRef]) -> datafusion_common::Result<()> {
1064 let value = values.first().ok_or_else(|| {
1065 datafusion_common::DataFusionError::Internal("No values provided for merge".to_string())
1066 })?;
1067 let struct_arr = value
1069 .as_any()
1070 .downcast_ref::<StructArray>()
1071 .ok_or_else(|| {
1072 datafusion_common::DataFusionError::Internal(format!(
1073 "Expected StructArray, got: {:?}",
1074 value.data_type()
1075 ))
1076 })?;
1077 let fields = struct_arr.fields();
1078 if fields != &self.state_fields {
1079 debug!(
1080 "State fields mismatch, expected: {:?}, got: {:?}",
1081 self.state_fields, fields
1082 );
1083 }
1085
1086 let state_columns = struct_arr.columns();
1089 self.inner.merge_batch(state_columns)
1090 }
1091
1092 fn size(&self) -> usize {
1093 self.inner.size()
1094 }
1095
1096 fn state(&mut self) -> datafusion_common::Result<Vec<ScalarValue>> {
1097 self.inner.state()
1098 }
1099}