1515// specific language governing permissions and limitations
1616// under the License.
1717
18+ use std:: marker:: PhantomData ;
1819use std:: sync:: Arc ;
1920
2021use arrow:: datatypes:: SchemaRef ;
@@ -23,6 +24,8 @@ use datafusion_common::{Result, internal_err};
2324use datafusion_expr:: EmitTo ;
2425
2526use crate :: aggregates:: AggregateExec ;
27+ use crate :: aggregates:: group_values:: new_group_values;
28+ use crate :: aggregates:: order:: GroupOrdering ;
2629
2730use super :: common:: {
2831 AggregateHashTable , AggregateHashTableBuffer , AggregateHashTableState , FinalMarker ,
@@ -46,6 +49,36 @@ impl AggregateHashTable<FinalMarker> {
4649 )
4750 }
4851
52+ pub ( in crate :: aggregates) fn empty_like ( & self ) -> Result < Self > {
53+ let AggregateHashTableState :: Building ( state) = & self . state else {
54+ return internal_err ! (
55+ "cannot create empty final hash aggregate table from non-building state"
56+ ) ;
57+ } ;
58+
59+ let group_schema = state. group_by . group_schema ( & self . input_schema ) ?;
60+ let group_values = new_group_values ( group_schema, & GroupOrdering :: None ) ?;
61+ let accumulators = state
62+ . accumulators
63+ . iter ( )
64+ . map ( |acc| acc. empty_like ( ) )
65+ . collect :: < Result < Vec < _ > > > ( ) ?;
66+
67+ Ok ( AggregateHashTable {
68+ group_by_metrics : self . group_by_metrics . clone ( ) ,
69+ input_schema : Arc :: clone ( & self . input_schema ) ,
70+ output_schema : Arc :: clone ( & self . output_schema ) ,
71+ batch_size : self . batch_size ,
72+ state : AggregateHashTableState :: Building ( AggregateHashTableBuffer {
73+ group_by : Arc :: clone ( & state. group_by ) ,
74+ group_values,
75+ batch_group_indices : Default :: default ( ) ,
76+ accumulators,
77+ } ) ,
78+ _mode : PhantomData ,
79+ } )
80+ }
81+
4982 /// Emits the next batch of aggregated group keys and final aggregate values.
5083 ///
5184 /// The output batch size is determined by `self.batch_size`.
0 commit comments