1717
1818use std:: { ops:: Neg , sync:: Arc } ;
1919
20- use crate :: PhysicalExpr ;
2120use arrow_schema:: SortOptions ;
21+
22+ use crate :: PhysicalExpr ;
2223use datafusion_common:: tree_node:: { TreeNode , VisitRecursion } ;
2324use datafusion_common:: Result ;
2425
25- use itertools:: Itertools ;
26-
2726/// To propagate [`SortOptions`] across the [`PhysicalExpr`], it is insufficient
2827/// to simply use `Option<SortOptions>`: There must be a differentiation between
2928/// unordered columns and literal values, since literals may not break the ordering
@@ -35,11 +34,12 @@ use itertools::Itertools;
3534/// sorted data; however the ((a_ordered + 999) + c_ordered) expression can. Therefore,
3635/// we need two different variants for literals and unordered columns as literals are
3736/// often more ordering-friendly under most mathematical operations.
38- #[ derive( PartialEq , Debug , Clone , Copy ) ]
37+ #[ derive( PartialEq , Debug , Clone , Copy , Default ) ]
3938pub enum SortProperties {
4039 /// Use the ordinary [`SortOptions`] struct to represent ordered data:
4140 Ordered ( SortOptions ) ,
4241 // This alternative represents unordered data:
42+ #[ default]
4343 Unordered ,
4444 // Singleton is used for single-valued literal numbers:
4545 Singleton ,
@@ -151,34 +151,24 @@ impl Neg for SortProperties {
151151pub struct ExprOrdering {
152152 pub expr : Arc < dyn PhysicalExpr > ,
153153 pub state : SortProperties ,
154- pub children_states : Vec < SortProperties > ,
154+ pub children : Vec < ExprOrdering > ,
155155}
156156
157157impl ExprOrdering {
158158 /// Creates a new [`ExprOrdering`] with [`SortProperties::Unordered`] states
159159 /// for `expr` and its children.
160160 pub fn new ( expr : Arc < dyn PhysicalExpr > ) -> Self {
161- let size = expr. children ( ) . len ( ) ;
161+ let children = expr. children ( ) ;
162162 Self {
163163 expr,
164- state : SortProperties :: Unordered ,
165- children_states : vec ! [ SortProperties :: Unordered ; size ] ,
164+ state : Default :: default ( ) ,
165+ children : children . into_iter ( ) . map ( Self :: new ) . collect ( ) ,
166166 }
167167 }
168168
169- /// Updates this [`ExprOrdering`]'s children states with the given states.
170- pub fn with_new_children ( mut self , children_states : Vec < SortProperties > ) -> Self {
171- self . children_states = children_states;
172- self
173- }
174-
175- /// Creates new [`ExprOrdering`] objects for each child of the expression.
176- pub fn children_expr_orderings ( & self ) -> Vec < ExprOrdering > {
177- self . expr
178- . children ( )
179- . into_iter ( )
180- . map ( ExprOrdering :: new)
181- . collect ( )
169+ /// Get a reference to each child state.
170+ pub fn children_state ( & self ) -> Vec < SortProperties > {
171+ self . children . iter ( ) . map ( |c| c. state ) . collect ( )
182172 }
183173}
184174
@@ -187,8 +177,8 @@ impl TreeNode for ExprOrdering {
187177 where
188178 F : FnMut ( & Self ) -> Result < VisitRecursion > ,
189179 {
190- for child in self . children_expr_orderings ( ) {
191- match op ( & child) ? {
180+ for child in & self . children {
181+ match op ( child) ? {
192182 VisitRecursion :: Continue => { }
193183 VisitRecursion :: Skip => return Ok ( VisitRecursion :: Continue ) ,
194184 VisitRecursion :: Stop => return Ok ( VisitRecursion :: Stop ) ,
@@ -197,25 +187,19 @@ impl TreeNode for ExprOrdering {
197187 Ok ( VisitRecursion :: Continue )
198188 }
199189
200- fn map_children < F > ( self , transform : F ) -> Result < Self >
190+ fn map_children < F > ( mut self , transform : F ) -> Result < Self >
201191 where
202192 F : FnMut ( Self ) -> Result < Self > ,
203193 {
204- if self . children_states . is_empty ( ) {
194+ if self . children . is_empty ( ) {
205195 Ok ( self )
206196 } else {
207- let child_expr_orderings = self . children_expr_orderings ( ) ;
208- // After mapping over the children, the function `F` applies to the
209- // current object and updates its state.
210- Ok ( self . with_new_children (
211- child_expr_orderings
212- . into_iter ( )
213- // Update children states after this transformation:
214- . map ( transform)
215- // Extract the state (i.e. sort properties) information:
216- . map_ok ( |c| c. state )
217- . collect :: < Result < Vec < _ > > > ( ) ?,
218- ) )
197+ self . children = self
198+ . children
199+ . into_iter ( )
200+ . map ( transform)
201+ . collect :: < Result < Vec < _ > > > ( ) ?;
202+ Ok ( self )
219203 }
220204 }
221205}
0 commit comments