@@ -37,16 +37,24 @@ use arrow::datatypes::DataType;
3737pub enum SortProperties {
3838 /// Use the ordinary [`SortOptions`] struct to represent ordered data:
3939 Ordered ( SortOptions ) ,
40- // This alternative represents unordered data:
40+ /// Within each partition, all rows with the same value for this expression
41+ /// form one contiguous run. The runs may occur in any order.
42+ Grouped ,
43+ /// This alternative represents unordered data:
4144 #[ default]
4245 Unordered ,
43- // Singleton is used for single-valued literal numbers:
46+ /// Singleton is used for single-valued literal numbers:
4447 Singleton ,
4548}
4649
4750impl SortProperties {
4851 pub fn add ( & self , rhs : & Self ) -> Self {
4952 match ( self , rhs) {
53+ // Addition can collapse distinct values (for example through
54+ // floating-point rounding), which may join non-adjacent groups.
55+ ( Self :: Grouped , Self :: Singleton ) | ( Self :: Singleton , Self :: Grouped ) => {
56+ Self :: Unordered
57+ }
5058 ( Self :: Singleton , _) => * rhs,
5159 ( _, Self :: Singleton ) => * self ,
5260 ( Self :: Ordered ( lhs) , Self :: Ordered ( rhs) )
@@ -65,6 +73,11 @@ impl SortProperties {
6573 pub fn sub ( & self , rhs : & Self ) -> Self {
6674 match ( self , rhs) {
6775 ( Self :: Singleton , Self :: Singleton ) => Self :: Singleton ,
76+ // Subtraction can collapse distinct values (for example through
77+ // floating-point rounding), which may join non-adjacent groups.
78+ ( Self :: Grouped , Self :: Singleton ) | ( Self :: Singleton , Self :: Grouped ) => {
79+ Self :: Unordered
80+ }
6881 ( Self :: Singleton , Self :: Ordered ( rhs) ) => Self :: Ordered ( SortOptions {
6982 descending : !rhs. descending ,
7083 nulls_first : rhs. nulls_first ,
@@ -89,6 +102,9 @@ impl SortProperties {
89102 descending : !rhs. descending ,
90103 nulls_first : rhs. nulls_first ,
91104 } ) ,
105+ // Comparisons can map several non-adjacent grouped values to the
106+ // same boolean value, so they do not preserve grouping.
107+ ( Self :: Grouped , Self :: Singleton ) => Self :: Unordered ,
92108 ( _, Self :: Singleton ) => * self ,
93109 ( Self :: Ordered ( lhs) , Self :: Ordered ( rhs) )
94110 if lhs. descending != rhs. descending
@@ -147,6 +163,7 @@ mod sort_properties_test {
147163 const ASC_NL : SortProperties = ordered ( false , false ) ;
148164 const DESC_NF : SortProperties = ordered ( true , true ) ;
149165 const DESC_NL : SortProperties = ordered ( true , false ) ;
166+ const GROUPED : SortProperties = SortProperties :: Grouped ;
150167 const UNORDERED : SortProperties = SortProperties :: Unordered ;
151168 const SINGLETON : SortProperties = SortProperties :: Singleton ;
152169
@@ -197,6 +214,27 @@ mod sort_properties_test {
197214 SINGLETON ,
198215 SINGLETON ,
199216 ) ,
217+ (
218+ "add: may collapse grouped values" ,
219+ SortProperties :: add,
220+ GROUPED ,
221+ SINGLETON ,
222+ UNORDERED ,
223+ ) ,
224+ (
225+ "sub: may collapse grouped values" ,
226+ SortProperties :: sub,
227+ GROUPED ,
228+ SINGLETON ,
229+ UNORDERED ,
230+ ) ,
231+ (
232+ "comparison does not preserve grouping" ,
233+ SortProperties :: gt_or_gteq,
234+ GROUPED ,
235+ SINGLETON ,
236+ UNORDERED ,
237+ ) ,
200238 // `and` keeps ASC NULLS LAST / DESC NULLS FIRST, `or` keeps ASC
201239 // NULLS FIRST / DESC NULLS LAST. Both are commutative.
202240 (
@@ -482,7 +520,7 @@ impl Neg for SortProperties {
482520#[ derive( Debug , Clone ) ]
483521pub struct ExprProperties {
484522 /// Properties that describe the sorting behavior of the expression,
485- /// such as whether it is ordered, unordered, or a singleton value.
523+ /// such as whether it is ordered, grouped, unordered, or a singleton value.
486524 pub sort_properties : SortProperties ,
487525 /// A closed interval representing the range of possible values for
488526 /// the expression. Used to compute reliable bounds.
0 commit comments