@@ -357,17 +357,33 @@ impl<'scope, T: crate::render::RenderTimestamp + crate::render::MaybeBucketByTim
357357 // Key each row for the first stage directly: its bucket of the row hash, or zero when
358358 // the only stage is the final one and the hash would be discarded anyway.
359359 let first_modulus = buckets. first ( ) . copied ( ) . unwrap_or ( 1 ) ;
360+ // A group key that is the row's leading columns is a byte prefix of the row.
361+ let prefix_len = group_key
362+ . iter ( )
363+ . enumerate ( )
364+ . all ( |( index, column) | * column == index)
365+ . then_some ( group_key. len ( ) ) ;
360366 let mut collection = collection. map ( {
361367 move |row| {
362- let group_row = {
363- let bucket = if first_modulus == 1 {
364- 0
365- } else {
366- row. hashed ( ) % first_modulus
367- } ;
368- let datums = datum_vec. borrow_with ( & row) ;
369- let iterator = group_key. iter ( ) . map ( |i| datums[ * i] ) ;
370- pairer. merge ( std:: iter:: once ( Datum :: from ( bucket) ) , iterator)
368+ let bucket = if first_modulus == 1 {
369+ 0
370+ } else {
371+ row. hashed ( ) % first_modulus
372+ } ;
373+ let group_row = match prefix_len {
374+ Some ( prefix_len) => {
375+ let ( group, _) = row. split_at_datum ( prefix_len) ;
376+ let mut group_row = Row :: default ( ) ;
377+ let mut packer = group_row. packer ( ) ;
378+ packer. push ( Datum :: from ( bucket) ) ;
379+ packer. extend_by_row_ref ( group) ;
380+ group_row
381+ }
382+ None => {
383+ let datums = datum_vec. borrow_with ( & row) ;
384+ let iterator = group_key. iter ( ) . map ( |i| datums[ * i] ) ;
385+ pairer. merge ( std:: iter:: once ( Datum :: from ( bucket) ) , iterator)
386+ }
371387 } ;
372388 ( group_row, row)
373389 }
0 commit comments