@@ -21,7 +21,7 @@ use datafusion_common::tree_node::{Transformed, TreeNode};
2121use datafusion_common:: { Result , ScalarValue } ;
2222use datafusion_expr:: Operator ;
2323use datafusion_physical_expr:: expressions:: { BinaryExpr , Column , Literal } ;
24- use datafusion_physical_expr:: PhysicalExpr ;
24+ use datafusion_physical_expr:: { PhysicalExpr , ScalarFunctionExpr } ;
2525use datafusion_physical_plan:: filter:: FilterExec ;
2626use datafusion_physical_plan:: projection:: { ProjectionExec , ProjectionExpr } ;
2727use datafusion_physical_plan:: rank:: RankExec ;
@@ -207,12 +207,29 @@ fn is_row_number(expr: &Arc<dyn WindowExpr>) -> bool {
207207}
208208
209209fn as_column ( expr : & dyn PhysicalExpr ) -> Option < & Column > {
210- expr. as_any ( ) . downcast_ref :: < Column > ( ) . or_else ( || {
211- // Look through a top-level CAST.
212- expr. as_any ( )
213- . downcast_ref :: < datafusion_physical_expr:: expressions:: CastExpr > ( )
214- . and_then ( |cast| cast. expr ( ) . as_any ( ) . downcast_ref :: < Column > ( ) )
215- } )
210+ expr. as_any ( )
211+ . downcast_ref :: < Column > ( )
212+ . or_else ( || {
213+ // Look through a top-level CAST.
214+ expr. as_any ( )
215+ . downcast_ref :: < datafusion_physical_expr:: expressions:: CastExpr > ( )
216+ . and_then ( |cast| cast. expr ( ) . as_any ( ) . downcast_ref :: < Column > ( ) )
217+ } )
218+ . or_else ( || {
219+ // Look through `to_decimal(col, ...)` wrappers produced by type coercion.
220+ expr. as_any ( )
221+ . downcast_ref :: < ScalarFunctionExpr > ( )
222+ . and_then ( |scalar| {
223+ if scalar. name ( ) . eq_ignore_ascii_case ( "to_decimal" ) {
224+ scalar
225+ . args ( )
226+ . first ( )
227+ . and_then ( |arg| as_column ( arg. as_ref ( ) ) )
228+ } else {
229+ None
230+ }
231+ } )
232+ } )
216233}
217234
218235fn scalar_to_usize ( value : & ScalarValue ) -> Option < usize > {
0 commit comments