15
15
// specific language governing permissions and limitations
16
16
// under the License.
17
17
18
+ use std:: any:: Any ;
18
19
#[ cfg( test) ]
19
20
use std:: collections:: HashMap ;
20
21
use std:: { sync:: Arc , vec} ;
@@ -29,7 +30,8 @@ use datafusion_common::{
29
30
use datafusion_common:: { plan_err, ParamValues } ;
30
31
use datafusion_expr:: {
31
32
logical_plan:: { LogicalPlan , Prepare } ,
32
- AggregateUDF , ScalarUDF , TableSource , WindowUDF ,
33
+ AggregateUDF , ColumnarValue , ScalarUDF , ScalarUDFImpl , Signature , TableSource ,
34
+ Volatility , WindowUDF ,
33
35
} ;
34
36
use datafusion_sql:: {
35
37
parser:: DFParser ,
@@ -2671,13 +2673,62 @@ fn logical_plan_with_dialect_and_options(
2671
2673
dialect : & dyn Dialect ,
2672
2674
options : ParserOptions ,
2673
2675
) -> Result < LogicalPlan > {
2674
- let context = MockContextProvider :: default ( ) ;
2676
+ let context = MockContextProvider :: default ( ) . with_udf ( make_udf (
2677
+ "nullif" ,
2678
+ vec ! [ DataType :: Int32 , DataType :: Int32 ] ,
2679
+ DataType :: Int32 ,
2680
+ ) ) ;
2681
+
2675
2682
let planner = SqlToRel :: new_with_options ( & context, options) ;
2676
2683
let result = DFParser :: parse_sql_with_dialect ( sql, dialect) ;
2677
2684
let mut ast = result?;
2678
2685
planner. statement_to_plan ( ast. pop_front ( ) . unwrap ( ) )
2679
2686
}
2680
2687
2688
+ fn make_udf ( name : & ' static str , args : Vec < DataType > , return_type : DataType ) -> ScalarUDF {
2689
+ ScalarUDF :: new_from_impl ( DummyUDF :: new ( name, args, return_type) )
2690
+ }
2691
+
2692
+ /// Mocked UDF
2693
+ #[ derive( Debug ) ]
2694
+ struct DummyUDF {
2695
+ name : & ' static str ,
2696
+ signature : Signature ,
2697
+ return_type : DataType ,
2698
+ }
2699
+
2700
+ impl DummyUDF {
2701
+ fn new ( name : & ' static str , args : Vec < DataType > , return_type : DataType ) -> Self {
2702
+ Self {
2703
+ name,
2704
+ signature : Signature :: exact ( args, Volatility :: Immutable ) ,
2705
+ return_type,
2706
+ }
2707
+ }
2708
+ }
2709
+
2710
+ impl ScalarUDFImpl for DummyUDF {
2711
+ fn as_any ( & self ) -> & dyn Any {
2712
+ self
2713
+ }
2714
+
2715
+ fn name ( & self ) -> & str {
2716
+ & self . name
2717
+ }
2718
+
2719
+ fn signature ( & self ) -> & Signature {
2720
+ & self . signature
2721
+ }
2722
+
2723
+ fn return_type ( & self , arg_types : & [ DataType ] ) -> Result < DataType > {
2724
+ Ok ( self . return_type . clone ( ) )
2725
+ }
2726
+
2727
+ fn invoke ( & self , args : & [ ColumnarValue ] ) -> Result < ColumnarValue > {
2728
+ unimplemented ! ( "DummyUDF::invoke" )
2729
+ }
2730
+ }
2731
+
2681
2732
/// Create logical plan, write with formatter, compare to expected output
2682
2733
fn quick_test ( sql : & str , expected : & str ) {
2683
2734
let plan = logical_plan ( sql) . unwrap ( ) ;
@@ -2724,13 +2775,19 @@ fn prepare_stmt_replace_params_quick_test(
2724
2775
#[ derive( Default ) ]
2725
2776
struct MockContextProvider {
2726
2777
options : ConfigOptions ,
2778
+ udfs : HashMap < String , Arc < ScalarUDF > > ,
2727
2779
udafs : HashMap < String , Arc < AggregateUDF > > ,
2728
2780
}
2729
2781
2730
2782
impl MockContextProvider {
2731
2783
fn options_mut ( & mut self ) -> & mut ConfigOptions {
2732
2784
& mut self . options
2733
2785
}
2786
+
2787
+ fn with_udf ( mut self , udf : ScalarUDF ) -> Self {
2788
+ self . udfs . insert ( udf. name ( ) . to_string ( ) , Arc :: new ( udf) ) ;
2789
+ self
2790
+ }
2734
2791
}
2735
2792
2736
2793
impl ContextProvider for MockContextProvider {
@@ -2823,8 +2880,8 @@ impl ContextProvider for MockContextProvider {
2823
2880
}
2824
2881
}
2825
2882
2826
- fn get_function_meta ( & self , _name : & str ) -> Option < Arc < ScalarUDF > > {
2827
- None
2883
+ fn get_function_meta ( & self , name : & str ) -> Option < Arc < ScalarUDF > > {
2884
+ self . udfs . get ( name ) . map ( Arc :: clone )
2828
2885
}
2829
2886
2830
2887
fn get_aggregate_meta ( & self , name : & str ) -> Option < Arc < AggregateUDF > > {
0 commit comments