@@ -37,16 +37,25 @@ 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+ /// Equal expression values occur in one contiguous run within each
41+ /// partition, including across record batch boundaries, but the runs have
42+ /// no defined order.
43+ Grouped ,
44+ /// This alternative represents unordered data:
4145 #[ default]
4246 Unordered ,
43- // Singleton is used for single-valued literal numbers:
47+ /// Singleton is used for single-valued literal numbers:
4448 Singleton ,
4549}
4650
4751impl SortProperties {
4852 pub fn add ( & self , rhs : & Self ) -> Self {
4953 match ( self , rhs) {
54+ // Addition can collapse distinct values (for example through
55+ // floating-point rounding), which may join non-adjacent groups.
56+ ( Self :: Grouped , Self :: Singleton ) | ( Self :: Singleton , Self :: Grouped ) => {
57+ Self :: Unordered
58+ }
5059 ( Self :: Singleton , _) => * rhs,
5160 ( _, Self :: Singleton ) => * self ,
5261 ( Self :: Ordered ( lhs) , Self :: Ordered ( rhs) )
@@ -65,6 +74,11 @@ impl SortProperties {
6574 pub fn sub ( & self , rhs : & Self ) -> Self {
6675 match ( self , rhs) {
6776 ( Self :: Singleton , Self :: Singleton ) => Self :: Singleton ,
77+ // Subtraction can collapse distinct values (for example through
78+ // floating-point rounding), which may join non-adjacent groups.
79+ ( Self :: Grouped , Self :: Singleton ) | ( Self :: Singleton , Self :: Grouped ) => {
80+ Self :: Unordered
81+ }
6882 ( Self :: Singleton , Self :: Ordered ( rhs) ) => Self :: Ordered ( SortOptions {
6983 descending : !rhs. descending ,
7084 nulls_first : rhs. nulls_first ,
@@ -89,6 +103,9 @@ impl SortProperties {
89103 descending : !rhs. descending ,
90104 nulls_first : rhs. nulls_first ,
91105 } ) ,
106+ // Comparisons can map several non-adjacent grouped values to the
107+ // same boolean value, so they do not preserve grouping.
108+ ( Self :: Grouped , Self :: Singleton ) => Self :: Unordered ,
92109 ( _, Self :: Singleton ) => * self ,
93110 ( Self :: Ordered ( lhs) , Self :: Ordered ( rhs) )
94111 if lhs. descending != rhs. descending
@@ -147,6 +164,7 @@ mod sort_properties_test {
147164 const ASC_NL : SortProperties = ordered ( false , false ) ;
148165 const DESC_NF : SortProperties = ordered ( true , true ) ;
149166 const DESC_NL : SortProperties = ordered ( true , false ) ;
167+ const GROUPED : SortProperties = SortProperties :: Grouped ;
150168 const UNORDERED : SortProperties = SortProperties :: Unordered ;
151169 const SINGLETON : SortProperties = SortProperties :: Singleton ;
152170
@@ -197,6 +215,27 @@ mod sort_properties_test {
197215 SINGLETON ,
198216 SINGLETON ,
199217 ) ,
218+ (
219+ "add: may collapse grouped values" ,
220+ SortProperties :: add,
221+ GROUPED ,
222+ SINGLETON ,
223+ UNORDERED ,
224+ ) ,
225+ (
226+ "sub: may collapse grouped values" ,
227+ SortProperties :: sub,
228+ GROUPED ,
229+ SINGLETON ,
230+ UNORDERED ,
231+ ) ,
232+ (
233+ "comparison does not preserve grouping" ,
234+ SortProperties :: gt_or_gteq,
235+ GROUPED ,
236+ SINGLETON ,
237+ UNORDERED ,
238+ ) ,
200239 // `and` keeps ASC NULLS LAST / DESC NULLS FIRST, `or` keeps ASC
201240 // NULLS FIRST / DESC NULLS LAST. Both are commutative.
202241 (
@@ -482,7 +521,7 @@ impl Neg for SortProperties {
482521#[ derive( Debug , Clone ) ]
483522pub struct ExprProperties {
484523 /// Properties that describe the sorting behavior of the expression,
485- /// such as whether it is ordered, unordered, or a singleton value.
524+ /// such as whether it is ordered, grouped, unordered, or a singleton value.
486525 pub sort_properties : SortProperties ,
487526 /// A closed interval representing the range of possible values for
488527 /// the expression. Used to compute reliable bounds.
0 commit comments