@@ -31,6 +31,7 @@ use datafusion_common::plan_err;
3131use datafusion_common:: tree_node:: { Transformed , TransformedResult , TreeNode } ;
3232use datafusion_physical_expr:: intervals:: utils:: { check_support, is_datatype_supported} ;
3333use datafusion_physical_plan:: joins:: SymmetricHashJoinExec ;
34+ use datafusion_physical_plan:: union:: UnionExec ;
3435use datafusion_physical_plan:: { get_plan_string, ExecutionPlanProperties } ;
3536
3637use datafusion_physical_optimizer:: PhysicalOptimizerRule ;
@@ -121,21 +122,34 @@ pub fn check_plan_sanity(
121122 check_finiteness_requirements ( plan. clone ( ) , optimizer_options) ?;
122123
123124 for ( ( idx, child) , sort_req, dist_req) in izip ! (
124- plan. children( ) . iter ( ) . enumerate( ) ,
125+ plan. children( ) . into_iter ( ) . enumerate( ) ,
125126 plan. required_input_ordering( ) . iter( ) ,
126127 plan. required_input_distribution( ) . iter( )
127128 ) {
128129 let child_eq_props = child. equivalence_properties ( ) ;
129130 if let Some ( sort_req) = sort_req {
130- if !child_eq_props. ordering_satisfy_requirement ( sort_req) {
131- let plan_str = get_plan_string ( & plan) ;
132- return plan_err ! (
133- "Plan: {:?} does not satisfy order requirements: {:?}. Child-{} order: {:?}" ,
134- plan_str,
135- sort_req,
136- idx,
137- child_eq_props. oeq_class
138- ) ;
131+ // The `EquivalenceProperties::ordering_satisfy_requirement` compares the oeq_class
132+ // orderings, minus their constants, to the requirement.
133+ //
134+ // For the UnionExec, it has the oeq_class orderings from it's children but does not
135+ // have the same constants. As such, the sort requirements cannot be fulfilled
136+ // without examination of the union's children with both the orderings & constants.
137+ let children = match child. as_any ( ) . downcast_ref :: < UnionExec > ( ) {
138+ Some ( union) => union. children ( ) ,
139+ _ => vec ! [ child] ,
140+ } ;
141+ for child in children {
142+ let child_eq_props = child. equivalence_properties ( ) ;
143+ if !child_eq_props. ordering_satisfy_requirement ( sort_req) {
144+ let plan_str = get_plan_string ( & plan) ;
145+ return plan_err ! (
146+ "Plan: {:?} does not satisfy order requirements: {:?}. Child-{} order: {:?}" ,
147+ plan_str,
148+ sort_req,
149+ idx,
150+ child_eq_props. oeq_class
151+ ) ;
152+ }
139153 }
140154 }
141155
0 commit comments