@@ -197,12 +197,14 @@ impl DefaultPhysicalPlanner {
197
197
} )
198
198
. collect :: < Result < Vec < _ > > > ( ) ?;
199
199
200
- let strategy = compute_aggregation_strategy ( input_exec. as_ref ( ) , & groups) ;
200
+ let ( strategy, order) =
201
+ compute_aggregation_strategy ( input_exec. as_ref ( ) , & groups) ;
201
202
// TODO: fix cubestore planning and re-enable.
202
203
if false && input_exec. output_partitioning ( ) . partition_count ( ) == 1 {
203
204
// A single pass is enough for 1 partition.
204
205
return Ok ( Arc :: new ( HashAggregateExec :: try_new (
205
206
strategy,
207
+ order,
206
208
AggregateMode :: Full ,
207
209
groups,
208
210
aggregates,
@@ -214,6 +216,7 @@ impl DefaultPhysicalPlanner {
214
216
let mut initial_aggr: Arc < dyn ExecutionPlan > =
215
217
Arc :: new ( HashAggregateExec :: try_new (
216
218
strategy,
219
+ order. clone ( ) ,
217
220
AggregateMode :: Partial ,
218
221
groups. clone ( ) ,
219
222
aggregates. clone ( ) ,
@@ -238,6 +241,7 @@ impl DefaultPhysicalPlanner {
238
241
// and the expressions corresponding to the respective aggregate
239
242
Ok ( Arc :: new ( HashAggregateExec :: try_new (
240
243
strategy,
244
+ order,
241
245
AggregateMode :: Final ,
242
246
final_group
243
247
. iter ( )
@@ -957,19 +961,25 @@ pub fn evaluate_const(expr: Arc<dyn PhysicalExpr>) -> Result<Arc<dyn PhysicalExp
957
961
pub fn compute_aggregation_strategy (
958
962
input : & dyn ExecutionPlan ,
959
963
group_key : & [ ( Arc < dyn PhysicalExpr > , String ) ] ,
960
- ) -> AggregateStrategy {
961
- if !group_key. is_empty ( ) && input_sorted_by_group_key ( input, & group_key) {
962
- AggregateStrategy :: InplaceSorted
964
+ ) -> ( AggregateStrategy , /*sort_order*/ Option < Vec < usize > > ) {
965
+ let mut sort_order = Vec :: new ( ) ;
966
+ if !group_key. is_empty ( )
967
+ && input_sorted_by_group_key ( input, & group_key, & mut sort_order)
968
+ {
969
+ ( AggregateStrategy :: InplaceSorted , Some ( sort_order) )
963
970
} else {
964
- AggregateStrategy :: Hash
971
+ ( AggregateStrategy :: Hash , None )
965
972
}
966
973
}
967
974
968
975
fn input_sorted_by_group_key (
969
976
input : & dyn ExecutionPlan ,
970
977
group_key : & [ ( Arc < dyn PhysicalExpr > , String ) ] ,
978
+ sort_order : & mut Vec < usize > ,
971
979
) -> bool {
972
980
assert ! ( !group_key. is_empty( ) ) ;
981
+ sort_order. clear ( ) ;
982
+
973
983
let hints = input. output_hints ( ) ;
974
984
// We check the group key is a prefix of the sort key.
975
985
let sort_key = hints. sort_order ;
@@ -979,7 +989,8 @@ fn input_sorted_by_group_key(
979
989
let sort_key = sort_key. unwrap ( ) ;
980
990
// Tracks which elements of sort key are used in the group key or have a single value.
981
991
let mut sort_key_hit = vec ! [ false ; sort_key. len( ) ] ;
982
- for ( g, _) in group_key {
992
+ let mut sort_to_group = vec ! [ usize :: MAX ; sort_key. len( ) ] ;
993
+ for ( group_i, ( g, _) ) in group_key. iter ( ) . enumerate ( ) {
983
994
let col = g. as_any ( ) . downcast_ref :: < Column > ( ) ;
984
995
if col. is_none ( ) {
985
996
return false ;
@@ -989,11 +1000,15 @@ fn input_sorted_by_group_key(
989
1000
return false ;
990
1001
}
991
1002
let input_col = input_col. unwrap ( ) ;
992
- let sort_key_pos = sort_key. iter ( ) . find_position ( |i| * * i == input_col) ;
993
- if sort_key_pos. is_none ( ) {
994
- return false ;
1003
+ let sort_key_pos = match sort_key. iter ( ) . find_position ( |i| * * i == input_col) {
1004
+ None => return false ,
1005
+ Some ( ( p, _) ) => p,
1006
+ } ;
1007
+ sort_key_hit[ sort_key_pos] = true ;
1008
+ if sort_to_group[ sort_key_pos] != usize:: MAX {
1009
+ return false ; // Bail out to simplify code a bit. This should not happen in practice.
995
1010
}
996
- sort_key_hit [ sort_key_pos. unwrap ( ) . 0 ] = true ;
1011
+ sort_to_group [ sort_key_pos] = group_i ;
997
1012
}
998
1013
for i in 0 ..sort_key. len ( ) {
999
1014
if hints. single_value_columns . contains ( & sort_key[ i] ) {
@@ -1003,12 +1018,21 @@ fn input_sorted_by_group_key(
1003
1018
1004
1019
// At this point all elements of the group key mapped into some column of the sort key.
1005
1020
// This checks the group key is mapped into a prefix of the sort key.
1006
- sort_key_hit
1007
- . iter ( )
1008
- . skip_while ( |present| * * present)
1009
- . skip_while ( |present| !* * present)
1010
- . next ( )
1011
- . is_none ( )
1021
+ let pref_len = sort_key_hit. iter ( ) . take_while ( |present| * * present) . count ( ) ;
1022
+ if sort_key_hit[ pref_len..] . iter ( ) . any ( |present| * present) {
1023
+ return false ;
1024
+ }
1025
+
1026
+ assert ! ( sort_order. is_empty( ) ) ; // Cleared at the beginning of the function.
1027
+
1028
+ // Note that single-value columns might not have a mapping to the grouping key.
1029
+ sort_order. extend (
1030
+ sort_to_group
1031
+ . iter ( )
1032
+ . take ( pref_len)
1033
+ . filter ( |i| * * i != usize:: MAX ) ,
1034
+ ) ;
1035
+ true
1012
1036
}
1013
1037
1014
1038
fn tuple_err < T , R > ( value : ( Result < T > , Result < R > ) ) -> Result < ( T , R ) > {
0 commit comments