@@ -28,35 +28,37 @@ use crate::{utils, LogicalPlan, Projection, Subquery};
2828use arrow:: compute:: can_cast_types;
2929use arrow:: datatypes:: { DataType , Field } ;
3030use datafusion_common:: {
31- internal_err, plan_datafusion_err, plan_err, Column , DFField , DFSchema ,
32- DataFusionError , ExprSchema , Result ,
31+ internal_err, plan_datafusion_err, plan_err, Column , DFField , DataFusionError ,
32+ ExprSchema , Result ,
3333} ;
3434use std:: collections:: HashMap ;
3535use std:: sync:: Arc ;
3636
3737/// trait to allow expr to typable with respect to a schema
3838pub trait ExprSchemable {
3939 /// given a schema, return the type of the expr
40- fn get_type < S : ExprSchema > ( & self , schema : & S ) -> Result < DataType > ;
40+ fn get_type ( & self , schema : & dyn ExprSchema ) -> Result < DataType > ;
4141
4242 /// given a schema, return the nullability of the expr
43- fn nullable < S : ExprSchema > ( & self , input_schema : & S ) -> Result < bool > ;
43+ fn nullable ( & self , input_schema : & dyn ExprSchema ) -> Result < bool > ;
4444
4545 /// given a schema, return the expr's optional metadata
46- fn metadata < S : ExprSchema > ( & self , schema : & S ) -> Result < HashMap < String , String > > ;
46+ fn metadata ( & self , schema : & dyn ExprSchema ) -> Result < HashMap < String , String > > ;
4747
4848 /// convert to a field with respect to a schema
49- fn to_field ( & self , input_schema : & DFSchema ) -> Result < DFField > ;
49+ fn to_field ( & self , input_schema : & dyn ExprSchema ) -> Result < DFField > ;
5050
5151 /// cast to a type with respect to a schema
52- fn cast_to < S : ExprSchema > ( self , cast_to_type : & DataType , schema : & S ) -> Result < Expr > ;
52+ fn cast_to ( self , cast_to_type : & DataType , schema : & dyn ExprSchema ) -> Result < Expr > ;
5353}
5454
5555impl ExprSchemable for Expr {
5656 /// Returns the [arrow::datatypes::DataType] of the expression
5757 /// based on [ExprSchema]
5858 ///
59- /// Note: [DFSchema] implements [ExprSchema].
59+ /// Note: [`DFSchema`] implements [ExprSchema].
60+ ///
61+ /// [`DFSchema`]: datafusion_common::DFSchema
6062 ///
6163 /// # Examples
6264 ///
@@ -90,7 +92,7 @@ impl ExprSchemable for Expr {
9092 /// expression refers to a column that does not exist in the
9193 /// schema, or when the expression is incorrectly typed
9294 /// (e.g. `[utf8] + [bool]`).
93- fn get_type < S : ExprSchema > ( & self , schema : & S ) -> Result < DataType > {
95+ fn get_type ( & self , schema : & dyn ExprSchema ) -> Result < DataType > {
9496 match self {
9597 Expr :: Alias ( Alias { expr, name, .. } ) => match & * * expr {
9698 Expr :: Placeholder ( Placeholder { data_type, .. } ) => match & data_type {
@@ -136,7 +138,7 @@ impl ExprSchemable for Expr {
136138 fun. return_type ( & arg_data_types)
137139 }
138140 ScalarFunctionDefinition :: UDF ( fun) => {
139- Ok ( fun. return_type ( & arg_data_types ) ?)
141+ Ok ( fun. return_type_from_exprs ( args , schema ) ?)
140142 }
141143 ScalarFunctionDefinition :: Name ( _) => {
142144 internal_err ! ( "Function `Expr` with name should be resolved." )
@@ -213,14 +215,16 @@ impl ExprSchemable for Expr {
213215
214216 /// Returns the nullability of the expression based on [ExprSchema].
215217 ///
216- /// Note: [DFSchema] implements [ExprSchema].
218+ /// Note: [`DFSchema`] implements [ExprSchema].
219+ ///
220+ /// [`DFSchema`]: datafusion_common::DFSchema
217221 ///
218222 /// # Errors
219223 ///
220224 /// This function errors when it is not possible to compute its
221225 /// nullability. This happens when the expression refers to a
222226 /// column that does not exist in the schema.
223- fn nullable < S : ExprSchema > ( & self , input_schema : & S ) -> Result < bool > {
227+ fn nullable ( & self , input_schema : & dyn ExprSchema ) -> Result < bool > {
224228 match self {
225229 Expr :: Alias ( Alias { expr, .. } )
226230 | Expr :: Not ( expr)
@@ -327,7 +331,7 @@ impl ExprSchemable for Expr {
327331 }
328332 }
329333
330- fn metadata < S : ExprSchema > ( & self , schema : & S ) -> Result < HashMap < String , String > > {
334+ fn metadata ( & self , schema : & dyn ExprSchema ) -> Result < HashMap < String , String > > {
331335 match self {
332336 Expr :: Column ( c) => Ok ( schema. metadata ( c) ?. clone ( ) ) ,
333337 Expr :: Alias ( Alias { expr, .. } ) => expr. metadata ( schema) ,
@@ -339,7 +343,7 @@ impl ExprSchemable for Expr {
339343 ///
340344 /// So for example, a projected expression `col(c1) + col(c2)` is
341345 /// placed in an output field **named** col("c1 + c2")
342- fn to_field ( & self , input_schema : & DFSchema ) -> Result < DFField > {
346+ fn to_field ( & self , input_schema : & dyn ExprSchema ) -> Result < DFField > {
343347 match self {
344348 Expr :: Column ( c) => Ok ( DFField :: new (
345349 c. relation . clone ( ) ,
@@ -370,7 +374,7 @@ impl ExprSchemable for Expr {
370374 ///
371375 /// This function errors when it is impossible to cast the
372376 /// expression to the target [arrow::datatypes::DataType].
373- fn cast_to < S : ExprSchema > ( self , cast_to_type : & DataType , schema : & S ) -> Result < Expr > {
377+ fn cast_to ( self , cast_to_type : & DataType , schema : & dyn ExprSchema ) -> Result < Expr > {
374378 let this_type = self . get_type ( schema) ?;
375379 if this_type == * cast_to_type {
376380 return Ok ( self ) ;
@@ -394,10 +398,10 @@ impl ExprSchemable for Expr {
394398}
395399
396400/// return the schema [`Field`] for the type referenced by `get_indexed_field`
397- fn field_for_index < S : ExprSchema > (
401+ fn field_for_index (
398402 expr : & Expr ,
399403 field : & GetFieldAccess ,
400- schema : & S ,
404+ schema : & dyn ExprSchema ,
401405) -> Result < Field > {
402406 let expr_dt = expr. get_type ( schema) ?;
403407 match field {
@@ -457,7 +461,7 @@ mod tests {
457461 use super :: * ;
458462 use crate :: { col, lit} ;
459463 use arrow:: datatypes:: { DataType , Fields } ;
460- use datafusion_common:: { Column , ScalarValue , TableReference } ;
464+ use datafusion_common:: { Column , DFSchema , ScalarValue , TableReference } ;
461465
462466 macro_rules! test_is_expr_nullable {
463467 ( $EXPR_TYPE: ident) => { {
0 commit comments