Repository navigation
Conversation
|
If we decide to go this route, there is still some followup work:
For example this is how array function errors look like: > select array_extract(1,2,3);
Error during planning: Failed to coerce function call 'array_element(Int64, Int64, Int64)'. You might need to add explicit type casts.
Candidate functions:
array_element(array, index)
|
| select union_extract(union_column, 'bool') from union_table; | ||
|
|
||
| query error DataFusion error: Error during planning: 'union_extract' does not support zero arguments | ||
| query error Failed to coerce function call 'union_extract\(\)' |
There was a problem hiding this comment.
the old message about not supporting zero arguments seems like it was nicer
| 1 | ||
|
|
||
| query error DataFusion error: Error during planning: Function 'strpos' requires TypeSignatureClass::Native\(LogicalType\(Native\(String\), String\)\), but received Int64 \(DataType: Int64\) | ||
| query error Failed to coerce function call 'strpos\(Int64, Int64\)' |
There was a problem hiding this comment.
it feels like the previous messages were better even if they were more verbose, as they at least try to explain to a user what was expected. I do admit that the TypeSignatureClass::Native<... is not very user friendly, however
|
Yeah I was initially thinking of trying to cleanup the existing errors, specifically cases where they are really ugly (coercion API, also if the signature is a I can work towards keeping the existing specific error messages, but my main concern is how to deal with
However for cases where the input arguments match more than one of the datafusion/datafusion/functions/src/math/log.rs Lines 83 to 100 in 796c7d1
If we supply > select log(1, '');
Error during planning: Internal error: Function 'log' failed to match any signature, errors: Error during planning: Function 'log' expects 1 arguments but received 2,Error during planning: Function 'log' expects 1 arguments but received 2,Error during planning: Function 'log' requires TypeSignatureClass::Decimal, but received String (DataType: Utf8).,Error during planning: Function 'log' requires TypeSignatureClass::Float, but received String (DataType: Utf8)..
This issue was likely caused by a bug in DataFusion's code. Please help us to resolve this by filing a bug report in our issue tracker: https://github.com/apache/datafusion/issues No function matches the given name and argument types 'log(Int64, Utf8)'. You might need to add explicit type casts.
Candidate functions:
log(Coercion(TypeSignatureClass::Decimal))
log(Coercion(TypeSignatureClass::Float, implicit_coercion=ImplicitCoercion([Numeric], default_type=Float64))
log(Coercion(TypeSignatureClass::Float, implicit_coercion=ImplicitCoercion([Numeric], default_type=Float64), Coercion(TypeSignatureClass::Decimal))
log(Coercion(TypeSignatureClass::Float, implicit_coercion=ImplicitCoercion([Numeric], default_type=Float64), Coercion(TypeSignatureClass::Float, implicit_coercion=ImplicitCoercion([Numeric], default_type=Float64))
Maybe only for cases like this we erase the error message and only show candidate functions, like this PR does? |
## Which issue does this PR close? Part of apache#20501. This is a deliberately narrow slice of that issue, and it is the slice a maintainer previously asked for: apache#21032 attempted this fix as a large change (it also reworked `sum`/`avg` diagnostics and the public `first_value`/`last_value`/`nth_value` arity contracts), was asked to be split up, and then went stale. This PR is **one behaviour change and nothing else**. ## Rationale for this change `get_valid_types_with_udf` reports "no `OneOf` branch matched" with `internal_err!`. Every alternative signature failing means the *caller* passed the wrong number or types of arguments — a user mistake — yet the user is told: > This issue was likely caused by a bug in DataFusion's code. Please help us to resolve this by filing a bug report in our issue tracker: ... So an ordinary SQL typo invites a bug report, and the failure surfaces as `Internal error: ...` even though nothing internal went wrong. The maintainer comment on apache#20070 named exactly this ("Can try to fix the display + internal error reference"). ### Before / after `SELECT substr(1, 2)` Before: ```text Error during planning: Internal error: Function 'substr' failed to match any signature, errors: Error during planning: Function 'substr' requires String, but received Int64 (DataType: Int64).,Error during planning: Function 'substr' expects 3 arguments but received 2. This issue was likely caused by a bug in DataFusion's code. Please help us to resolve this by filing a bug report in our issue tracker: https://github.com/apache/datafusion/issues ``` After: ```text Error during planning: Function 'substr' failed to match any signature, errors: Error during planning: Function 'substr' requires String, but received Int64 (DataType: Int64).,Error during planning: Function 'substr' expects 3 arguments but received 2. ``` The message body, the candidate signatures, and the trailing "No function matches the given name and argument types ... You might need to add explicit type casts." line are all unchanged. Only the `Internal error` kind and the bug-report boilerplate are gone. ## What changes are included in this PR? - `datafusion/expr/src/type_coercion/functions.rs`: return `plan_err!` instead of `internal_err!` when every `OneOf` branch rejects the arguments. One line of behaviour change. - A unit test covering that failure. It mirrors `substr`'s real signature, so one branch fails on the argument type and the other on the arity. - Ten `sqllogictest` expectations that asserted the old user-visible text, in `array/array_range.slt`, `spark/math/round.slt`, `errors.slt` and `math.slt`. ## Are these changes tested? Yes. - The new unit test fails on `main` and passes with the change; `cargo test -p datafusion-expr --lib` is 282 passed, 0 failed. - `cargo fmt --all --check` is clean. - I audited every other expectation of this message. The remaining ones — `functions.slt`, `aggregate.slt`, `string_literal.slt`, `named_arguments.slt`, and one assertion in `datafusion/optimizer/src/analyzer/type_coercion.rs` — match on a substring that does not include the removed prefix, so they are unaffected. No `sqllogictest` file asserted the "This issue was likely caused by a bug..." boilerplate. I could not run the full `sqllogictest` suite locally (it needs a full `datafusion-core` build), so CI is the verification for the four updated `.slt` files. ## Scope Deliberately left out, to keep this reviewable: - the message is still verbose and still prefixes every branch error with `Error during planning:` — that is apache#19004; - `errors.join(",")` still runs the branch errors together without a separator, which is why the after-message reads `...(DataType: Int64).,Error during planning: ...`; - the arity phrasing suggested on apache#20070 (`log expects 1 to 2 arguments, got 3`) is a separate improvement. Happy to follow up on any of those in separate PRs.
Which issue does this PR close?
candidate functionssuggestions #15817 and Improve error messages when coercion fails #19004Rationale for this change
Current error message for calling functions with incorrect arguments isn't very user friendly. Some examples:
OneOfsignature, and we currently concatenate each error from each signature inside theOneOfresulting in a large error message that isn't very helpfulabs, which is niceCandidate functionswhich isn't very helpful (greatest(UserDefined)doesn't really help the user understand the available signatures since user defined is opaque)Contrast this with DuckDB:
Or Postgres:
It looks like they prefer to omit stating specific errors, and only give general advice; for DuckDB they list the available call types, for Postgres they omit this and leave it a simple error with only details on how it was called.
This PR looks into removing some of the word spam from error messages and tries to make them more consistent with each other.
What changes are included in this PR?
When a function call fails because no signatures match, the displayed error either:
coerce_typescall of the UDF (we omit candidate functions message)For example, user-defined:
For all other signatures:
Although it means we don't show a specific error anymore (see how
absno longer specifies it was because it received string instead of a numeric), I think this is an easier way to manage signature errors to be consistent for functions that have a single signature and those that areOneOftypes. It also aligns with DuckDB.Are these changes tested?
Yes.
Are there any user-facing changes?
Yes, error messages for failed function calls changes.