Skip to content

Commit 3f81613

Browse files
authored
Remove GroupsAccumulator::supports_convert_to_state and require convert_to_state (#23489)
## Which issue does this PR close? <!-- We generally require a GitHub issue to be filed for all bug fixes and enhancements and this helps us generate change logs for our releases. You can link an issue to this PR using the GitHub syntax. For example `Closes #123` indicates that this PR will close issue #123. --> - Closes #23081. ## Rationale for this change <!-- Why are you proposing this change? If this is already explained clearly in the issue then this section is not needed. Explaining clearly why changes are proposed helps reviewers understand your changes and offer better suggestions for fixes. --> Following #23275, all `GroupsAccumulator` implementations now provide `convert_to_state`. The `supports_convert_to_state` capability flag is therefore no longer needed. ## What changes are included in this PR? <!-- There is no need to duplicate the description in the issue here but it is sometimes worth providing a summary of the individual changes in this PR. --> - Make `GroupsAccumulator::convert_to_state` a required trait method. - Remove `GroupsAccumulator::supports_convert_to_state` and its implementations. - Remove the corresponding capability checks from hash aggregation. - Simplify skip-partial aggregation to use the required `convert_to_state` implementation directly. - Add a regression test covering the partial hash aggregation skip path. - Document the breaking trait change in the 55.0.0 upgrading guide. - Remove `FFI_GroupsAccumulator::supports_convert_to_state`. This changes the FFI ABI layout, so providers and consumers must be rebuilt against DataFusion 55. ## Are these changes tested? <!-- We typically require tests for all PRs in order to: 1. Prevent the code from being accidentally broken by subsequent changes 2. Serve as another way to document the expected behavior of the code If tests are not included in your PR, please explain why (for example, are they covered by existing tests)? --> Yes. Added a regression test verifying that skip-partial aggregation uses the required `convert_to_state` implementation without a capability flag. Existing physical-plan and FFI tests continue to pass. ## Are there any user-facing changes? <!-- If there are user-facing changes then we may require documentation to be updated before approving the PR. --> <!-- If there are any breaking changes to public APIs, please add the `api change` label. --> Yes. This is a breaking Rust API change for external `GroupsAccumulator` implementations: - `convert_to_state` must now be implemented. - `supports_convert_to_state` should be removed. The migration is documented in the 55.0.0 upgrading guide. The `FFI_GroupsAccumulator` layout has changed. FFI providers and consumers must be rebuilt against DataFusion 55 and must not exchange this struct with older major versions.
1 parent 82f1b36 commit 3f81613

28 files changed

Lines changed: 56 additions & 146 deletions

File tree

datafusion-examples/examples/udf/advanced_udaf.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -393,11 +393,6 @@ impl GroupsAccumulator for GeometricMeanGroupsAccumulator {
393393
Arc::new(counts) as ArrayRef,
394394
])
395395
}
396-
397-
fn supports_convert_to_state(&self) -> bool {
398-
true
399-
}
400-
401396
fn size(&self) -> usize {
402397
self.counts.capacity() * size_of::<u32>()
403398
+ self.prods.capacity() * size_of::<Float64Type>()

datafusion/core/tests/user_defined/user_defined_aggregates.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -888,11 +888,6 @@ impl GroupsAccumulator for TestGroupsAccumulator {
888888
as ArrayRef,
889889
])
890890
}
891-
892-
fn supports_convert_to_state(&self) -> bool {
893-
true
894-
}
895-
896891
fn size(&self) -> usize {
897892
size_of::<u64>()
898893
}

datafusion/expr-common/src/groups_accumulator.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
//! Vectorized [`GroupsAccumulator`]
1919
2020
use arrow::array::{ArrayRef, BooleanArray};
21-
use datafusion_common::{Result, not_impl_err, utils::split_vec_min_alloc};
21+
use datafusion_common::{Result, utils::split_vec_min_alloc};
2222

2323
/// Describes how many rows should be emitted during grouping.
2424
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -231,17 +231,9 @@ pub trait GroupsAccumulator: Send + std::any::Any {
231231
/// [`Accumulator::state`]: crate::accumulator::Accumulator::state
232232
fn convert_to_state(
233233
&self,
234-
_values: &[ArrayRef],
235-
_opt_filter: Option<&BooleanArray>,
236-
) -> Result<Vec<ArrayRef>> {
237-
not_impl_err!("Input batch conversion to state not implemented")
238-
}
239-
240-
/// Returns `true` if [`Self::convert_to_state`] is implemented to support
241-
/// intermediate aggregate state conversion.
242-
fn supports_convert_to_state(&self) -> bool {
243-
false
244-
}
234+
values: &[ArrayRef],
235+
opt_filter: Option<&BooleanArray>,
236+
) -> Result<Vec<ArrayRef>>;
245237

246238
/// Amount of memory used to store the state of this accumulator,
247239
/// in bytes.

datafusion/ffi/src/udaf/groups_accumulator.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ pub struct FFI_GroupsAccumulator {
7373
opt_filter: FFI_Option<WrappedArray>,
7474
) -> FFI_Result<SVec<WrappedArray>>,
7575

76-
pub supports_convert_to_state: bool,
77-
7876
/// Release the memory of the private data when it is no longer being used.
7977
pub release: unsafe extern "C" fn(accumulator: &mut Self),
8078

@@ -247,7 +245,6 @@ impl From<Box<dyn GroupsAccumulator>> for FFI_GroupsAccumulator {
247245
return accumulator.accumulator;
248246
}
249247

250-
let supports_convert_to_state = accumulator.supports_convert_to_state();
251248
let private_data = GroupsAccumulatorPrivateData { accumulator };
252249

253250
Self {
@@ -257,7 +254,6 @@ impl From<Box<dyn GroupsAccumulator>> for FFI_GroupsAccumulator {
257254
state: state_fn_wrapper,
258255
merge_batch: merge_batch_fn_wrapper,
259256
convert_to_state: convert_to_state_fn_wrapper,
260-
supports_convert_to_state,
261257

262258
release: release_fn_wrapper,
263259
private_data: Box::into_raw(Box::new(private_data)) as *mut c_void,
@@ -421,10 +417,6 @@ impl GroupsAccumulator for ForeignGroupsAccumulator {
421417
.collect()
422418
}
423419
}
424-
425-
fn supports_convert_to_state(&self) -> bool {
426-
self.accumulator.supports_convert_to_state
427-
}
428420
}
429421

430422
#[repr(C)]

datafusion/functions-aggregate-common/src/aggregate/count_distinct/groups.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,11 +207,6 @@ where
207207

208208
Ok(vec![Arc::new(builder.finish())])
209209
}
210-
211-
fn supports_convert_to_state(&self) -> bool {
212-
true
213-
}
214-
215210
fn size(&self) -> usize {
216211
size_of::<Self>()
217212
+ self.seen.capacity() * (size_of::<(usize, T::Native)>() + size_of::<u64>())

datafusion/functions-aggregate-common/src/aggregate/groups_accumulator.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -441,10 +441,6 @@ impl GroupsAccumulator for GroupsAccumulatorAdapter {
441441

442442
Ok(arrays)
443443
}
444-
445-
fn supports_convert_to_state(&self) -> bool {
446-
true
447-
}
448444
}
449445

450446
/// Extension trait for [`Vec`] to account for allocations.

datafusion/functions-aggregate-common/src/aggregate/groups_accumulator/bool_op.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,4 @@ where
156156

157157
Ok(vec![Arc::new(values_filtered)])
158158
}
159-
160-
fn supports_convert_to_state(&self) -> bool {
161-
true
162-
}
163159
}

datafusion/functions-aggregate-common/src/aggregate/groups_accumulator/prim_op.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,6 @@ where
189189

190190
Ok(vec![Arc::new(state_values)])
191191
}
192-
193-
fn supports_convert_to_state(&self) -> bool {
194-
true
195-
}
196-
197192
fn size(&self) -> usize {
198193
self.values.capacity() * size_of::<T::Native>() + self.null_state.size()
199194
}

datafusion/functions-aggregate/src/approx_distinct.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -615,11 +615,6 @@ impl GroupsAccumulator for HllGroupsAccumulator {
615615

616616
Ok(vec![Arc::new(builder.finish())])
617617
}
618-
619-
fn supports_convert_to_state(&self) -> bool {
620-
true
621-
}
622-
623618
fn size(&self) -> usize {
624619
self.groups.capacity() * size_of::<GroupHll>()
625620
+ self.allocated_bytes

datafusion/functions-aggregate/src/array_agg.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -793,11 +793,6 @@ impl GroupsAccumulator for ArrayAggGroupsAccumulator {
793793

794794
Ok(vec![Arc::new(list_array)])
795795
}
796-
797-
fn supports_convert_to_state(&self) -> bool {
798-
true
799-
}
800-
801796
fn size(&self) -> usize {
802797
self.batches
803798
.iter()

0 commit comments

Comments
 (0)