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::physical_planner::create_aggregate_expr_and_maybe_filter;
37use datafusion_common::{Column, ScalarValue};
38use datafusion_expr::expr::{AggregateFunction, AggregateFunctionParams};
39use datafusion_expr::function::StateFieldsArgs;
40use datafusion_expr::{
41 Accumulator, Aggregate, AggregateUDF, AggregateUDFImpl, EmitTo, Expr, ExprSchemable,
42 GroupsAccumulator, LogicalPlan, Signature,
43};
44use datafusion_physical_expr::aggregate::AggregateFunctionExpr;
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 (original_phy_expr, _filter, _ordering) = create_aggregate_expr_and_maybe_filter(
214 aggr_expr,
215 aggr.input.schema(),
216 aggr.input.schema().as_arrow(),
217 &Default::default(),
218 )?;
219
220 let merge_func = MergeWrapper::new(
221 (*aggr_func.func).clone(),
222 original_phy_expr,
223 original_input_fields,
224 )?;
225 let arg = Expr::Column(Column::new_unqualified(lower_state_output_col_name));
226 let expr = AggregateFunction {
227 func: Arc::new(merge_func.into()),
228 params: AggregateFunctionParams {
232 args: vec![arg],
233 distinct: aggr_func.params.distinct,
234 filter: None,
235 order_by: vec![],
236 null_treatment: aggr_func.params.null_treatment,
237 },
238 };
239
240 let expr = Expr::AggregateFunction(expr).alias(aggr_expr.schema_name().to_string());
243 upper_aggr_exprs.push(expr);
244 }
245
246 let mut lower = aggr.clone();
247 lower.aggr_expr = lower_aggr_exprs;
248 let lower_plan = LogicalPlan::Aggregate(lower);
249
250 let lower_plan = lower_plan.recompute_schema()?;
252
253 let fixed_lower_plan =
256 FixStateUdafOrderingAnalyzer.analyze(lower_plan, &Default::default())?;
257
258 let upper = Aggregate::try_new(
259 Arc::new(fixed_lower_plan.clone()),
260 upper_group_exprs,
261 upper_aggr_exprs.clone(),
262 )?;
263 let aggr_plan = LogicalPlan::Aggregate(aggr);
264
265 let upper_check = upper;
267 let upper_plan = LogicalPlan::Aggregate(upper_check).recompute_schema()?;
268 if *upper_plan.schema() != *aggr_plan.schema() {
269 return Err(datafusion_common::DataFusionError::Internal(format!(
270 "Upper aggregate plan's schema is not the same as the original aggregate plan's schema: \n[transformed]:{}\n[original]:{}",
271 upper_plan.schema(),
272 aggr_plan.schema()
273 )));
274 }
275
276 Ok(StepAggrPlan {
277 lower_state: fixed_lower_plan,
278 upper_merge: upper_plan,
279 })
280 }
281}
282
283#[derive(Debug, Clone, PartialEq, Eq, Hash)]
285pub struct StateWrapper {
286 inner: AggregateUDF,
287 name: String,
288 ordering: Vec<FieldRef>,
290 distinct: bool,
292}
293
294impl StateWrapper {
295 pub fn new(inner: AggregateUDF) -> datafusion_common::Result<Self> {
297 let name = aggr_state_func_name(inner.name());
298 Ok(Self {
299 inner,
300 name,
301 ordering: vec![],
302 distinct: false,
303 })
304 }
305
306 pub fn inner(&self) -> &AggregateUDF {
307 &self.inner
308 }
309
310 pub fn deduce_aggr_return_type(
314 &self,
315 acc_args: &datafusion_expr::function::AccumulatorArgs,
316 ) -> datafusion_common::Result<FieldRef> {
317 let input_fields = acc_args
318 .exprs
319 .iter()
320 .map(|e| e.return_field(acc_args.schema))
321 .collect::<Result<Vec<_>, _>>()?;
322 self.inner.return_field(&input_fields).inspect_err(|e| {
323 common_telemetry::error!(
324 "StateWrapper: {:#?}\nacc_args:{:?}\nerror:{:?}",
325 &self,
326 &acc_args,
327 e
328 );
329 })
330 }
331
332 fn fix_inner_acc_args<'b>(
333 &self,
334 mut acc_args: datafusion_expr::function::AccumulatorArgs<'b>,
335 ) -> datafusion_common::Result<datafusion_expr::function::AccumulatorArgs<'b>> {
336 acc_args.return_field = self.deduce_aggr_return_type(&acc_args)?;
337 Ok(acc_args)
338 }
339}
340
341impl AggregateUDFImpl for StateWrapper {
342 fn accumulator<'a, 'b>(
343 &'a self,
344 acc_args: datafusion_expr::function::AccumulatorArgs<'b>,
345 ) -> datafusion_common::Result<Box<dyn Accumulator>> {
346 let state_type = acc_args.return_type().clone();
348 let inner = self.inner.accumulator(self.fix_inner_acc_args(acc_args)?)?;
349
350 Ok(Box::new(StateAccum::new(inner, state_type)?))
351 }
352
353 fn groups_accumulator_supported(
354 &self,
355 acc_args: datafusion_expr::function::AccumulatorArgs,
356 ) -> bool {
357 self.fix_inner_acc_args(acc_args)
358 .map(|args| self.inner.inner().groups_accumulator_supported(args))
359 .unwrap_or(false)
360 }
361
362 fn create_groups_accumulator(
363 &self,
364 acc_args: datafusion_expr::function::AccumulatorArgs,
365 ) -> datafusion_common::Result<Box<dyn GroupsAccumulator>> {
366 let state_type = acc_args.return_type().clone();
367 let inner = self
368 .inner
369 .inner()
370 .create_groups_accumulator(self.fix_inner_acc_args(acc_args)?)?;
371 Ok(Box::new(StateGroupsAccum::new(inner, state_type)?))
372 }
373
374 fn as_any(&self) -> &dyn std::any::Any {
375 self
376 }
377 fn name(&self) -> &str {
378 self.name.as_str()
379 }
380
381 fn is_nullable(&self) -> bool {
382 self.inner.is_nullable()
383 }
384
385 fn return_type(&self, arg_types: &[DataType]) -> datafusion_common::Result<DataType> {
388 let input_fields = &arg_types
389 .iter()
390 .map(|x| Arc::new(Field::new("x", x.clone(), false)))
391 .collect::<Vec<_>>();
392
393 let state_fields_args = StateFieldsArgs {
394 name: self.inner().name(),
395 input_fields,
396 return_field: self.inner.return_field(input_fields)?,
397 ordering_fields: &self.ordering,
399 is_distinct: self.distinct,
400 };
401 let state_fields = self.inner.state_fields(state_fields_args)?;
402
403 let state_fields = state_fields
404 .into_iter()
405 .map(|f| {
406 let mut f = f.as_ref().clone();
407 f.set_nullable(true);
409 Arc::new(f)
410 })
411 .collect::<Vec<_>>();
412
413 let struct_field = DataType::Struct(state_fields.into());
414 Ok(struct_field)
415 }
416
417 fn state_fields(
419 &self,
420 args: datafusion_expr::function::StateFieldsArgs,
421 ) -> datafusion_common::Result<Vec<FieldRef>> {
422 let state_fields_args = StateFieldsArgs {
423 name: args.name,
424 input_fields: args.input_fields,
425 return_field: self.inner.return_field(args.input_fields)?,
426 ordering_fields: args.ordering_fields,
427 is_distinct: args.is_distinct,
428 };
429 self.inner.state_fields(state_fields_args)
430 }
431
432 fn signature(&self) -> &Signature {
434 self.inner.signature()
435 }
436
437 fn coerce_types(&self, arg_types: &[DataType]) -> datafusion_common::Result<Vec<DataType>> {
439 self.inner.coerce_types(arg_types)
440 }
441
442 fn value_from_stats(
443 &self,
444 statistics_args: &datafusion_expr::StatisticsArgs,
445 ) -> Option<ScalarValue> {
446 let inner = self.inner().inner().as_any();
447 let can_use_stat = inner.is::<Count>() || inner.is::<Max>() || inner.is::<Min>();
450 if !can_use_stat {
451 return None;
452 }
453
454 let state_type = if let DataType::Struct(fields) = &statistics_args.return_type {
456 if fields.is_empty() {
457 return None;
458 }
459 fields[0].data_type().clone()
460 } else {
461 return None;
462 };
463
464 let fixed_args = datafusion_expr::StatisticsArgs {
465 statistics: statistics_args.statistics,
466 return_type: &state_type,
467 is_distinct: statistics_args.is_distinct,
468 exprs: statistics_args.exprs,
469 };
470
471 let ret = self.inner().value_from_stats(&fixed_args)?;
472
473 let fields = if let DataType::Struct(fields) = &statistics_args.return_type {
475 fields
476 } else {
477 return None;
478 };
479
480 let array = ret.to_array().ok()?;
481
482 let struct_array = StructArray::new(fields.clone(), vec![array], None);
483 let ret = ScalarValue::Struct(Arc::new(struct_array));
484 Some(ret)
485 }
486}
487
488#[derive(Debug)]
491pub struct StateAccum {
492 inner: Box<dyn Accumulator>,
493 state_fields: Fields,
494}
495
496pub struct StateGroupsAccum {
497 inner: Box<dyn GroupsAccumulator>,
498 state_fields: Fields,
499}
500
501impl StateGroupsAccum {
502 fn new(
503 inner: Box<dyn GroupsAccumulator>,
504 state_type: DataType,
505 ) -> datafusion_common::Result<Self> {
506 let DataType::Struct(fields) = state_type else {
507 return Err(datafusion_common::DataFusionError::Internal(format!(
508 "Expected a struct type for state, got: {:?}",
509 state_type
510 )));
511 };
512 Ok(Self {
513 inner,
514 state_fields: fields,
515 })
516 }
517
518 fn wrap_state_arrays(&self, arrays: Vec<ArrayRef>) -> datafusion_common::Result<ArrayRef> {
519 let array_type = arrays
520 .iter()
521 .map(|array| array.data_type().clone())
522 .collect::<Vec<_>>();
523 let expected_type = self
524 .state_fields
525 .iter()
526 .map(|field| field.data_type().clone())
527 .collect::<Vec<_>>();
528 if array_type != expected_type {
529 debug!(
530 "State mismatch, expected: {}, got: {} for expected fields: {:?} and given array types: {:?}",
531 self.state_fields.len(),
532 arrays.len(),
533 self.state_fields,
534 array_type,
535 );
536 let guess_schema = arrays
537 .iter()
538 .enumerate()
539 .map(|(index, array)| {
540 Field::new(
541 format!("col_{index}[mismatch_state]").as_str(),
542 array.data_type().clone(),
543 true,
544 )
545 })
546 .collect::<Fields>();
547 let array = StructArray::try_new(guess_schema, arrays, None)?;
548 return Ok(Arc::new(array));
549 }
550
551 Ok(Arc::new(StructArray::try_new(
552 self.state_fields.clone(),
553 arrays,
554 None,
555 )?))
556 }
557}
558
559impl GroupsAccumulator for StateGroupsAccum {
560 fn update_batch(
561 &mut self,
562 values: &[ArrayRef],
563 group_indices: &[usize],
564 opt_filter: Option<&BooleanArray>,
565 total_num_groups: usize,
566 ) -> datafusion_common::Result<()> {
567 self.inner
568 .update_batch(values, group_indices, opt_filter, total_num_groups)
569 }
570
571 fn merge_batch(
572 &mut self,
573 values: &[ArrayRef],
574 group_indices: &[usize],
575 opt_filter: Option<&BooleanArray>,
576 total_num_groups: usize,
577 ) -> datafusion_common::Result<()> {
578 self.inner
579 .merge_batch(values, group_indices, opt_filter, total_num_groups)
580 }
581
582 fn evaluate(&mut self, emit_to: EmitTo) -> datafusion_common::Result<ArrayRef> {
583 let state = self.inner.state(emit_to)?;
584 self.wrap_state_arrays(state)
585 }
586
587 fn state(&mut self, emit_to: EmitTo) -> datafusion_common::Result<Vec<ArrayRef>> {
588 self.inner.state(emit_to)
589 }
590
591 fn convert_to_state(
592 &self,
593 values: &[ArrayRef],
594 opt_filter: Option<&BooleanArray>,
595 ) -> datafusion_common::Result<Vec<ArrayRef>> {
596 self.inner.convert_to_state(values, opt_filter)
597 }
598
599 fn supports_convert_to_state(&self) -> bool {
600 self.inner.supports_convert_to_state()
601 }
602
603 fn size(&self) -> usize {
604 self.inner.size()
605 }
606}
607
608impl StateAccum {
609 pub fn new(
610 inner: Box<dyn Accumulator>,
611 state_type: DataType,
612 ) -> datafusion_common::Result<Self> {
613 let DataType::Struct(fields) = state_type else {
614 return Err(datafusion_common::DataFusionError::Internal(format!(
615 "Expected a struct type for state, got: {:?}",
616 state_type
617 )));
618 };
619 Ok(Self {
620 inner,
621 state_fields: fields,
622 })
623 }
624}
625
626impl Accumulator for StateAccum {
627 fn evaluate(&mut self) -> datafusion_common::Result<ScalarValue> {
628 let state = self.inner.state()?;
629
630 let array = state
631 .iter()
632 .map(|s| s.to_array())
633 .collect::<Result<Vec<_>, _>>()?;
634 let array_type = array
635 .iter()
636 .map(|a| a.data_type().clone())
637 .collect::<Vec<_>>();
638 let expected_type: Vec<_> = self
639 .state_fields
640 .iter()
641 .map(|f| f.data_type().clone())
642 .collect();
643 if array_type != expected_type {
644 debug!(
645 "State mismatch, expected: {}, got: {} for expected fields: {:?} and given array types: {:?}",
646 self.state_fields.len(),
647 array.len(),
648 self.state_fields,
649 array_type,
650 );
651 let guess_schema = array
652 .iter()
653 .enumerate()
654 .map(|(index, array)| {
655 Field::new(
656 format!("col_{index}[mismatch_state]").as_str(),
657 array.data_type().clone(),
658 true,
659 )
660 })
661 .collect::<Fields>();
662 let arr = StructArray::try_new(guess_schema, array, None)?;
663
664 return Ok(ScalarValue::Struct(Arc::new(arr)));
665 }
666
667 let struct_array = StructArray::try_new(self.state_fields.clone(), array, None)?;
668 Ok(ScalarValue::Struct(Arc::new(struct_array)))
669 }
670
671 fn merge_batch(
672 &mut self,
673 states: &[datatypes::arrow::array::ArrayRef],
674 ) -> datafusion_common::Result<()> {
675 self.inner.merge_batch(states)
676 }
677
678 fn update_batch(
679 &mut self,
680 values: &[datatypes::arrow::array::ArrayRef],
681 ) -> datafusion_common::Result<()> {
682 self.inner.update_batch(values)
683 }
684
685 fn size(&self) -> usize {
686 self.inner.size()
687 }
688
689 fn state(&mut self) -> datafusion_common::Result<Vec<ScalarValue>> {
690 self.inner.state()
691 }
692}
693
694#[derive(Debug, Clone)]
701pub(crate) struct DeltaMergeWrapper {
702 inner: AggregateUDF,
703 name: String,
704 signature: Signature,
705 inner_types: Vec<DataType>,
706 state_type: DataType,
707}
708
709impl DeltaMergeWrapper {
710 pub(crate) fn new(
715 inner: AggregateUDF,
716 state_name: &str,
717 inner_types: Vec<DataType>,
718 state_type: DataType,
719 ) -> Self {
720 let mut wrapper_types = inner_types.clone();
721 wrapper_types.push(state_type.clone());
722 Self {
723 name: aggr_delta_merge_func_name(state_name),
724 signature: Signature::exact(wrapper_types, inner.signature().volatility),
725 inner,
726 inner_types,
727 state_type,
728 }
729 }
730
731 fn resolve_inner_args(
732 &self,
733 input_fields: &[FieldRef],
734 ) -> datafusion_common::Result<Vec<FieldRef>> {
735 if input_fields.len() != self.inner_types.len() + 1 {
736 return Err(datafusion_common::DataFusionError::Plan(
737 "delta merge requires parameters, delta state, and persisted state".to_string(),
738 ));
739 }
740 for (field, expected_type) in input_fields[..self.inner_types.len()]
741 .iter()
742 .zip(&self.inner_types)
743 {
744 if field.data_type() != expected_type {
745 return Err(datafusion_common::DataFusionError::Plan(format!(
746 "delta merge argument type does not match its exact signature: {:?} != {expected_type:?}",
747 field.data_type()
748 )));
749 }
750 }
751 let persisted = &input_fields[self.inner_types.len()];
752 if persisted.data_type() != &self.state_type && persisted.data_type() != &DataType::Null {
753 return Err(datafusion_common::DataFusionError::Plan(format!(
754 "persisted state type does not match the exact state type: {:?} != {:?}",
755 persisted.data_type(),
756 self.state_type
757 )));
758 }
759 Ok(input_fields[..self.inner_types.len()].to_vec())
760 }
761}
762
763impl AggregateUDFImpl for DeltaMergeWrapper {
764 fn accumulator<'a, 'b>(
765 &'a self,
766 acc_args: datafusion_expr::function::AccumulatorArgs<'b>,
767 ) -> datafusion_common::Result<Box<dyn Accumulator>> {
768 if acc_args.exprs.len() != acc_args.expr_fields.len() {
769 return Err(datafusion_common::DataFusionError::Plan(
770 "delta merge expression and field arities differ".to_string(),
771 ));
772 }
773 let inner_fields = self.resolve_inner_args(acc_args.expr_fields)?;
774 for (expr, expected_type) in acc_args.exprs.iter().zip(
775 self.inner_types
776 .iter()
777 .chain(std::iter::once(&self.state_type)),
778 ) {
779 if expr.data_type(acc_args.schema)? != *expected_type {
780 return Err(datafusion_common::DataFusionError::Internal(
781 "delta merge physical expression type is not resolved".to_string(),
782 ));
783 }
784 }
785 let state_index = self.inner_types.len() - 1;
786 let inner_args = datafusion_expr::function::AccumulatorArgs {
787 return_field: acc_args.return_field,
788 schema: acc_args.schema,
789 ignore_nulls: acc_args.ignore_nulls,
790 order_bys: acc_args.order_bys,
791 is_reversed: acc_args.is_reversed,
792 name: self.inner.name(),
793 is_distinct: acc_args.is_distinct,
794 exprs: &acc_args.exprs[..=state_index],
795 expr_fields: &inner_fields,
796 };
797 Ok(Box::new(DeltaMergeAccum {
798 inner: self.inner.accumulator(inner_args)?,
799 params: state_index,
800 }))
801 }
802
803 fn as_any(&self) -> &dyn std::any::Any {
804 self
805 }
806
807 fn name(&self) -> &str {
808 &self.name
809 }
810
811 fn is_nullable(&self) -> bool {
812 self.inner.is_nullable()
813 }
814
815 fn return_type(&self, arg_types: &[DataType]) -> datafusion_common::Result<DataType> {
816 let fields = arg_types
817 .iter()
818 .enumerate()
819 .map(|(index, data_type)| {
820 Arc::new(Field::new(index.to_string(), data_type.clone(), true))
821 })
822 .collect::<Vec<_>>();
823 let inner_fields = self.resolve_inner_args(&fields)?;
824 self.inner.return_type(
825 &inner_fields
826 .iter()
827 .map(|field| field.data_type().clone())
828 .collect::<Vec<_>>(),
829 )
830 }
831
832 fn return_field(&self, arg_fields: &[FieldRef]) -> datafusion_common::Result<FieldRef> {
833 let inner_fields = self.resolve_inner_args(arg_fields)?;
834 self.inner.return_field(&inner_fields)
835 }
836
837 fn signature(&self) -> &Signature {
838 &self.signature
839 }
840
841 fn state_fields(
842 &self,
843 args: datafusion_expr::function::StateFieldsArgs,
844 ) -> datafusion_common::Result<Vec<FieldRef>> {
845 let inner_fields = self.resolve_inner_args(args.input_fields)?;
846 self.inner
847 .state_fields(datafusion_expr::function::StateFieldsArgs {
848 name: args.name,
849 input_fields: &inner_fields,
850 return_field: args.return_field,
851 ordering_fields: args.ordering_fields,
852 is_distinct: args.is_distinct,
853 })
854 }
855}
856
857impl PartialEq for DeltaMergeWrapper {
858 fn eq(&self, other: &Self) -> bool {
859 self.name == other.name && self.inner == other.inner
860 }
861}
862impl Eq for DeltaMergeWrapper {}
863impl Hash for DeltaMergeWrapper {
864 fn hash<H: Hasher>(&self, state: &mut H) {
865 self.name.hash(state);
866 self.inner.hash(state);
867 }
868}
869
870#[derive(Debug)]
871struct DeltaMergeAccum {
872 inner: Box<dyn Accumulator>,
873 params: usize,
874}
875
876impl Accumulator for DeltaMergeAccum {
877 fn evaluate(&mut self) -> datafusion_common::Result<ScalarValue> {
878 self.inner.evaluate()
879 }
880
881 fn update_batch(&mut self, values: &[ArrayRef]) -> datafusion_common::Result<()> {
882 if values.len() != self.params + 2 {
883 return Err(datafusion_common::DataFusionError::Plan(format!(
884 "delta merge expected {} arguments, got {}",
885 self.params + 2,
886 values.len()
887 )));
888 }
889 let mut inner_values = values[..self.params + 1].to_vec();
892 self.inner.update_batch(&inner_values)?;
893 inner_values[self.params] = values[self.params + 1].clone();
894 self.inner.update_batch(&inner_values)
895 }
896
897 fn merge_batch(&mut self, states: &[ArrayRef]) -> datafusion_common::Result<()> {
898 self.inner.merge_batch(states)
899 }
900
901 fn size(&self) -> usize {
902 self.inner.size()
903 }
904
905 fn state(&mut self) -> datafusion_common::Result<Vec<ScalarValue>> {
906 self.inner.state()
907 }
908}
909
910#[derive(Debug, Clone)]
915pub struct MergeWrapper {
916 inner: AggregateUDF,
917 name: String,
918 merge_signature: Signature,
919 original_phy_expr: Arc<AggregateFunctionExpr>,
921 return_field: FieldRef,
922}
923impl MergeWrapper {
924 pub fn new(
925 inner: AggregateUDF,
926 original_phy_expr: Arc<AggregateFunctionExpr>,
927 original_input_fields: Vec<FieldRef>,
928 ) -> datafusion_common::Result<Self> {
929 let name = aggr_merge_func_name(inner.name());
930 let merge_signature = Signature::user_defined(datafusion_expr::Volatility::Immutable);
932 let return_field = inner.return_field(&original_input_fields)?.clone();
933
934 Ok(Self {
935 inner,
936 name,
937 merge_signature,
938 original_phy_expr,
939 return_field,
940 })
941 }
942
943 pub fn inner(&self) -> &AggregateUDF {
944 &self.inner
945 }
946}
947
948impl AggregateUDFImpl for MergeWrapper {
949 fn accumulator<'a, 'b>(
950 &'a self,
951 acc_args: datafusion_expr::function::AccumulatorArgs<'b>,
952 ) -> datafusion_common::Result<Box<dyn Accumulator>> {
953 if acc_args.exprs.len() != 1
954 || !matches!(
955 acc_args.exprs[0].data_type(acc_args.schema)?,
956 DataType::Struct(_)
957 )
958 {
959 return Err(datafusion_common::DataFusionError::Internal(format!(
960 "Expected one struct type as input, got: {:?}",
961 acc_args.schema
962 )));
963 }
964 let input_type = acc_args.exprs[0].data_type(acc_args.schema)?;
965 let DataType::Struct(fields) = input_type else {
966 return Err(datafusion_common::DataFusionError::Internal(format!(
967 "Expected a struct type for input, got: {:?}",
968 input_type
969 )));
970 };
971
972 let inner_accum = self.original_phy_expr.create_accumulator()?;
973 Ok(Box::new(MergeAccum::new(inner_accum, &fields)))
974 }
975
976 fn as_any(&self) -> &dyn std::any::Any {
977 self
978 }
979 fn name(&self) -> &str {
980 self.name.as_str()
981 }
982
983 fn is_nullable(&self) -> bool {
984 self.inner.is_nullable()
985 }
986
987 fn return_type(&self, _arg_types: &[DataType]) -> datafusion_common::Result<DataType> {
990 Ok(self.return_field.data_type().clone())
992 }
993
994 fn return_field(&self, _arg_fields: &[FieldRef]) -> datafusion_common::Result<FieldRef> {
996 Ok(self.return_field.clone())
997 }
998
999 fn signature(&self) -> &Signature {
1000 &self.merge_signature
1001 }
1002
1003 fn coerce_types(&self, arg_types: &[DataType]) -> datafusion_common::Result<Vec<DataType>> {
1005 if arg_types.len() != 1 || !matches!(arg_types.first(), Some(DataType::Struct(_))) {
1007 return Err(datafusion_common::DataFusionError::Internal(format!(
1008 "Expected one struct type as input, got: {:?}",
1009 arg_types
1010 )));
1011 }
1012 Ok(arg_types.to_vec())
1013 }
1014
1015 fn state_fields(
1017 &self,
1018 _args: datafusion_expr::function::StateFieldsArgs,
1019 ) -> datafusion_common::Result<Vec<FieldRef>> {
1020 self.original_phy_expr.state_fields()
1021 }
1022}
1023
1024impl PartialEq for MergeWrapper {
1025 fn eq(&self, other: &Self) -> bool {
1026 self.inner == other.inner
1027 }
1028}
1029
1030impl Eq for MergeWrapper {}
1031
1032impl Hash for MergeWrapper {
1033 fn hash<H: Hasher>(&self, state: &mut H) {
1034 self.inner.hash(state);
1035 }
1036}
1037
1038#[derive(Debug)]
1042pub struct MergeAccum {
1043 inner: Box<dyn Accumulator>,
1044 state_fields: Fields,
1045}
1046
1047impl MergeAccum {
1048 pub fn new(inner: Box<dyn Accumulator>, state_fields: &Fields) -> Self {
1049 Self {
1050 inner,
1051 state_fields: state_fields.clone(),
1052 }
1053 }
1054}
1055
1056impl Accumulator for MergeAccum {
1057 fn evaluate(&mut self) -> datafusion_common::Result<ScalarValue> {
1058 self.inner.evaluate()
1059 }
1060
1061 fn merge_batch(&mut self, states: &[arrow::array::ArrayRef]) -> datafusion_common::Result<()> {
1062 self.inner.merge_batch(states)
1063 }
1064
1065 fn update_batch(&mut self, values: &[arrow::array::ArrayRef]) -> datafusion_common::Result<()> {
1066 let value = values.first().ok_or_else(|| {
1067 datafusion_common::DataFusionError::Internal("No values provided for merge".to_string())
1068 })?;
1069 let struct_arr = value
1071 .as_any()
1072 .downcast_ref::<StructArray>()
1073 .ok_or_else(|| {
1074 datafusion_common::DataFusionError::Internal(format!(
1075 "Expected StructArray, got: {:?}",
1076 value.data_type()
1077 ))
1078 })?;
1079 let fields = struct_arr.fields();
1080 if fields != &self.state_fields {
1081 debug!(
1082 "State fields mismatch, expected: {:?}, got: {:?}",
1083 self.state_fields, fields
1084 );
1085 }
1087
1088 let state_columns = struct_arr.columns();
1091 self.inner.merge_batch(state_columns)
1092 }
1093
1094 fn size(&self) -> usize {
1095 self.inner.size()
1096 }
1097
1098 fn state(&mut self) -> datafusion_common::Result<Vec<ScalarValue>> {
1099 self.inner.state()
1100 }
1101}