@@ -20,7 +20,7 @@ use crate::planner::{ContextProvider, PlannerContext, SqlToRel};
20
20
use arrow:: datatypes:: DataType ;
21
21
use datafusion_common:: {
22
22
internal_datafusion_err, internal_err, not_impl_err, plan_datafusion_err, plan_err,
23
- DFSchema , Dependency , Result ,
23
+ DFSchema , Dependency , Diagnostic , Result , Span ,
24
24
} ;
25
25
use datafusion_expr:: expr:: { ScalarFunction , Unnest } ;
26
26
use datafusion_expr:: planner:: { PlannerResult , RawAggregateExpr , RawWindowExpr } ;
@@ -217,7 +217,7 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
217
217
// it shouldn't have ordering requirement as function argument
218
218
// required ordering should be defined in OVER clause.
219
219
let is_function_window = over. is_some ( ) ;
220
-
220
+ let sql_parser_span = name . 0 [ 0 ] . span ;
221
221
let name = if name. 0 . len ( ) > 1 {
222
222
// DF doesn't handle compound identifiers
223
223
// (e.g. "foo.bar") for function names yet
@@ -236,7 +236,6 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
236
236
}
237
237
}
238
238
}
239
-
240
239
// User-defined function (UDF) should have precedence
241
240
if let Some ( fm) = self . context_provider . get_function_meta ( & name) {
242
241
let args = self . function_args_to_expr ( args, schema, planner_context) ?;
@@ -259,7 +258,6 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
259
258
"Aggregate ORDER BY is not implemented for window functions"
260
259
) ;
261
260
}
262
-
263
261
// Then, window function
264
262
if let Some ( WindowType :: WindowSpec ( window) ) = over {
265
263
let partition_by = window
@@ -399,12 +397,21 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
399
397
) ) ) ;
400
398
}
401
399
}
402
-
403
400
// Could not find the relevant function, so return an error
404
401
if let Some ( suggested_func_name) =
405
402
suggest_valid_function ( & name, is_function_window, self . context_provider )
406
403
{
407
404
plan_err ! ( "Invalid function '{name}'.\n Did you mean '{suggested_func_name}'?" )
405
+ . map_err ( |e| {
406
+ let span = Span :: try_from_sqlparser_span ( sql_parser_span) ;
407
+ let mut diagnostic =
408
+ Diagnostic :: new_error ( format ! ( "Invalid function '{name}'" ) , span) ;
409
+ diagnostic. add_note (
410
+ format ! ( "Possible function '{}'" , suggested_func_name) ,
411
+ None ,
412
+ ) ;
413
+ e. with_diagnostic ( diagnostic)
414
+ } )
408
415
} else {
409
416
internal_err ! ( "No functions registered with this context." )
410
417
}
0 commit comments