Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 59 additions & 13 deletions datafusion/expr/src/type_coercion/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,24 +325,20 @@ fn get_valid_types_with_udf<F: UDFCoercionExt>(
},
TypeSignature::OneOf(signatures) => {
let mut res = vec![];
let mut errors = vec![];
for sig in signatures {
match get_valid_types_with_udf(sig, current_types, func) {
Ok(valid_types) => {
res.extend(valid_types);
}
Err(e) => {
errors.push(e.to_string());
}
if let Ok(valid_types) =
get_valid_types_with_udf(sig, current_types, func)
{
res.extend(valid_types);
}
}

// Every signature failed, return the joined error
// Every signature failed, return a neutral planning error rather than
// a branch-specific error that may not match the best overload.
if res.is_empty() {
return internal_err!(
"Function '{}' failed to match any signature, errors: {}",
func.name(),
errors.join(",")
return plan_err!(
"Function '{}' failed to match any signature",
func.name()
);
} else {
res
Expand Down Expand Up @@ -1223,6 +1219,56 @@ mod tests {
Ok(())
}

#[test]
fn test_one_of_uses_generic_plan_error_instead_of_internal_error() {
let current_fields = vec![Arc::new(Field::new("t", DataType::Boolean, true))];
let signature = Signature::one_of(
vec![
Signature::coercible(
vec![Coercion::new_exact(TypeSignatureClass::Decimal)],
Volatility::Immutable,
)
.type_signature
.clone(),
Signature::coercible(
vec![Coercion::new_exact(TypeSignatureClass::Duration)],
Volatility::Immutable,
)
.type_signature
.clone(),
],
Volatility::Immutable,
);

let err = fields_with_udf(&current_fields, &MockUdf(signature)).unwrap_err();
let err = err.to_string();

assert_eq!(
err,
"Error during planning: Function 'test' failed to match any signature"
);
assert!(!err.contains("Internal error"));
assert!(!err.contains("TypeSignatureClass"));
}

#[test]
fn test_one_of_uses_generic_plan_error_for_arity_mismatch() {
let current_fields = vec![Arc::new(Field::new("t", DataType::Int32, true))];
let signature = Signature::one_of(
vec![TypeSignature::Any(2), TypeSignature::Any(3)],
Volatility::Immutable,
);

let err = fields_with_udf(&current_fields, &MockUdf(signature)).unwrap_err();
let err = err.to_string();

assert_eq!(
err,
"Error during planning: Function 'test' failed to match any signature"
);
assert!(!err.contains("Internal error"));
}

#[test]
fn test_nested_wildcard_fixed_size_lists() -> Result<()> {
let type_into = DataType::FixedSizeList(
Expand Down
8 changes: 4 additions & 4 deletions datafusion/sqllogictest/test_files/array.slt
Original file line number Diff line number Diff line change
Expand Up @@ -7798,17 +7798,17 @@ select generate_series(arrow_cast('2021-01-01T00:00:00', 'Timestamp(Nanosecond,
[2021-01-01T00:00:00-05:00, 2021-01-01T01:29:54.500-05:00, 2021-01-01T02:59:49-05:00, 2021-01-01T04:29:43.500-05:00, 2021-01-01T05:59:38-05:00]

## mixing types for timestamps is not supported
query error DataFusion error: Error during planning: Internal error: Function 'generate_series' failed to match any signature
query error DataFusion error: Error during planning: Function 'generate_series' failed to match any signature(.|\n)*generate_series\(Timestamp\(ns, "-05:00"\), Date32, Interval\(MonthDayNano\)\)(.|\n)*Candidate functions:
select generate_series(arrow_cast('2021-01-01T00:00:00', 'Timestamp(Nanosecond, Some("-05:00"))'), DATE '2021-01-02', INTERVAL '1' HOUR);

## mixing types not allowed even if an argument is null
query error DataFusion error: Error during planning: Internal error: Function 'generate_series' failed to match any signature
query error DataFusion error: Error during planning: Function 'generate_series' failed to match any signature(.|\n)*generate_series\(Timestamp\(ns\), Date32, Null\)(.|\n)*Candidate functions:
select generate_series(TIMESTAMP '1992-09-01', DATE '1993-03-01', NULL);

query error DataFusion error: Error during planning: Internal error: Function 'generate_series' failed to match any signature
query error DataFusion error: Error during planning: Function 'generate_series' failed to match any signature(.|\n)*generate_series\(Int64, Utf8, Utf8\)(.|\n)*Candidate functions:
select generate_series(1, '2024-01-01', '2025-01-02');

query error DataFusion error: Error during planning: Internal error: Function 'generate_series' failed to match any signature
query error DataFusion error: Error during planning: Function 'generate_series' failed to match any signature(.|\n)*generate_series\(Timestamp\(ns\), Utf8, Interval\(MonthDayNano\)\)(.|\n)*Candidate functions:
select generate_series('2024-01-01'::timestamp, '2025-01-02', interval '1 day');

## should return NULL
Expand Down
5 changes: 4 additions & 1 deletion datafusion/sqllogictest/test_files/errors.slt
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,16 @@ from aggregate_test_100
order by c9

# WindowFunction wrong signature
statement error DataFusion error: Error during planning: Internal error: Function 'nth_value' failed to match any signature
statement error DataFusion error: Error during planning: Function 'nth_value' failed to match any signature(.|\n)*nth_value\(Int32, Int64, Int64\)(.|\n)*Candidate functions:
select
c9,
nth_value(c5, 2, 3) over (order by c9) as nv1
from aggregate_test_100
order by c9

query error DataFusion error: Error during planning: Function 'sum' failed to match any signature(.|\n)*sum\(Boolean\)(.|\n)*Candidate functions:
select sum(bool_col) from (values (true), (false), (null)) as t(bool_col);


# nth_value with wrong name
statement error DataFusion error: Error during planning: Invalid function 'nth_vlue'.\nDid you mean 'nth_value'?
Expand Down
4 changes: 2 additions & 2 deletions datafusion/sqllogictest/test_files/functions.slt
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,10 @@ SELECT substr('alphabet', NULL, 2)
----
NULL

statement error Function 'substr' failed to match any signature
statement error DataFusion error: Error during planning: Function 'substr' failed to match any signature(.|\n)*Candidate functions:
SELECT substr(1, 3)

statement error Function 'substr' failed to match any signature
statement error DataFusion error: Error during planning: Function 'substr' failed to match any signature(.|\n)*Candidate functions:
SELECT substr(1, 3, 4)

query T
Expand Down
2 changes: 1 addition & 1 deletion datafusion/sqllogictest/test_files/named_arguments.slt
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ SELECT substr("STR" => 'hello world', "start_pos" => 7);

# Error: wrong number of arguments
# This query provides only 1 argument but substr requires 2 or 3
query error Function 'substr' failed to match any signature
query error DataFusion error: Error during planning: Function 'substr' failed to match any signature(.|\n)*Candidate functions:
SELECT substr(str => 'hello world');

#############
Expand Down
4 changes: 2 additions & 2 deletions datafusion/sqllogictest/test_files/string/string_literal.slt
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,10 @@ SELECT substr('Hello🌏世界', 5, 3)
----
o🌏世

statement error Function 'substr' failed to match any signature
statement error DataFusion error: Error during planning: Function 'substr' failed to match any signature(.|\n)*Candidate functions:
SELECT substr(1, 3)

statement error Function 'substr' failed to match any signature
statement error DataFusion error: Error during planning: Function 'substr' failed to match any signature(.|\n)*Candidate functions:
SELECT substr(1, 3, 4)

statement error Execution error: negative substring length not allowed
Expand Down
Loading