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