Skip to content

Commit cf76352

Browse files
authored
Improve error message when string functions receive Binary types (#19819)
## Which issue does this PR close? <!-- We generally require a GitHub issue to be filed for all bug fixes and enhancements and this helps us generate change logs for our releases. You can link an issue to this PR using the GitHub syntax. For example `Closes #123` indicates that this PR will close issue #123. --> - Related to #19004 and #19809. ## What changes are included in this PR? <!-- There is no need to duplicate the description in the issue here but it is sometimes worth providing a summary of the individual changes in this PR. --> Change internal error to user-facing error when function type coercion fails. Add helpful hint when Binary types are used with string functions. Before: ``` Internal error: Expect TypeSignatureClass::Native(...) but received NativeType::Binary, DataType: Binary ``` After: ``` Error: Function 'split_part' requires String, but received Binary (DataType: Binary). Hint: Binary types are not automatically coerced to String. Use CAST(column AS VARCHAR) to convert Binary data to String. ```
1 parent 7a09e27 commit cf76352

File tree

7 files changed

+26
-11
lines changed

7 files changed

+26
-11
lines changed

datafusion/expr/src/type_coercion/functions.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -635,8 +635,13 @@ fn get_valid_types(
635635
default_casted_type.default_cast_for(current_type)?;
636636
new_types.push(casted_type);
637637
} else {
638-
return internal_err!(
639-
"Expect {} but received NativeType::{}, DataType: {}",
638+
let hint = if matches!(current_native_type, NativeType::Binary) {
639+
"\n\nHint: Binary types are not automatically coerced to String. Use CAST(column AS VARCHAR) to convert Binary data to String."
640+
} else {
641+
""
642+
};
643+
return plan_err!(
644+
"Function '{function_name}' requires {}, but received {} (DataType: {}).{hint}",
640645
param.desired_type(),
641646
current_native_type,
642647
current_type

datafusion/sqllogictest/test_files/arrow_typeof.slt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ SELECT arrow_cast('1', 'Int16')
9595
query error
9696
SELECT arrow_cast('1')
9797

98-
query error Expect TypeSignatureClass::Native\(LogicalType\(Native\(String\), String\)\) but received NativeType::Int64, DataType: Int64
98+
query error DataFusion error: Error during planning: Function 'arrow_cast' requires TypeSignatureClass::Native\(LogicalType\(Native\(String\), String\)\), but received Int64 \(DataType: Int64\)
9999
SELECT arrow_cast('1', 43)
100100

101101
query error DataFusion error: Execution error: arrow_cast requires its second argument to be a non\-empty constant string

datafusion/sqllogictest/test_files/binary.slt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,3 +311,13 @@ Foo foo Foo foo
311311
NULL NULL NULL NULL
312312
Bar Bar Bar Bar
313313
FooBar fooBar FooBar fooBar
314+
315+
# show helpful error msg when Binary type is used with string functions
316+
query error DataFusion error: Error during planning: Function 'split_part' requires TypeSignatureClass::Native\(LogicalType\(Native\(String\), String\)\), but received Binary \(DataType: Binary\)\.\n\nHint: Binary types are not automatically coerced to String\. Use CAST\(column AS VARCHAR\) to convert Binary data to String\.
317+
SELECT split_part(binary, '~', 2) FROM t WHERE binary IS NOT NULL LIMIT 1;
318+
319+
# ensure the suggested CAST workaround works
320+
query T
321+
SELECT split_part(CAST(binary AS VARCHAR), 'o', 2) FROM t WHERE binary = X'466f6f';
322+
----
323+
(empty)

datafusion/sqllogictest/test_files/datetime/timestamps.slt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3064,7 +3064,7 @@ NULL
30643064
query error DataFusion error: Error during planning: Function 'make_date' expects 3 arguments but received 1
30653065
select make_date(1);
30663066

3067-
query error Expect TypeSignatureClass::Native\(LogicalType\(Native\(Int32\), Int32\)\) but received NativeType::Interval\(MonthDayNano\), DataType: Interval\(MonthDayNano\)
3067+
query error DataFusion error: Error during planning: Function 'make_date' requires TypeSignatureClass::Native\(LogicalType\(Native\(Int32\), Int32\)\), but received Interval\(MonthDayNano\) \(DataType: Interval\(MonthDayNano\)\)
30683068
select make_date(interval '1 day', '2001-05-21'::timestamp, '2001-05-21'::timestamp);
30693069

30703070
##########
@@ -3337,7 +3337,7 @@ select make_time(22, '', 27);
33373337
query error Cannot cast string '' to value of Int32 type
33383338
select make_time(22, 1, '');
33393339

3340-
query error Expect TypeSignatureClass::Native\(LogicalType\(Native\(Int32\), Int32\)\) but received NativeType::Float64, DataType: Float64
3340+
query error DataFusion error: Error during planning: Function 'make_time' requires TypeSignatureClass::Native\(LogicalType\(Native\(Int32\), Int32\)\), but received Float64 \(DataType: Float64\)
33413341
select make_time(arrow_cast(22, 'Float64'), 1, '');
33423342

33433343
##########
@@ -3952,7 +3952,7 @@ statement error
39523952
select to_local_time('2024-04-01T00:00:20Z'::timestamp, 'some string');
39533953

39543954
# invalid argument data type
3955-
statement error DataFusion error: Error during planning: Internal error: Expect TypeSignatureClass::Timestamp but received NativeType::String, DataType: Utf8
3955+
statement error DataFusion error: Error during planning: Function 'to_local_time' requires TypeSignatureClass::Timestamp, but received String \(DataType: Utf8\)
39563956
select to_local_time('2024-04-01T00:00:20Z');
39573957

39583958
# invalid timezone

datafusion/sqllogictest/test_files/encoding.slt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ CREATE TABLE test(
5555
;
5656

5757
# errors
58-
query error DataFusion error: Error during planning: Internal error: Expect TypeSignatureClass::Binary but received NativeType::Int64, DataType: Int64
58+
query error DataFusion error: Error during planning: Function 'encode' requires TypeSignatureClass::Binary, but received Int64 \(DataType: Int64\)
5959
select encode(12, 'hex');
6060

61-
query error DataFusion error: Error during planning: Internal error: Expect TypeSignatureClass::Binary but received NativeType::Int64, DataType: Int64
61+
query error DataFusion error: Error during planning: Function 'decode' requires TypeSignatureClass::Binary, but received Int64 \(DataType: Int64\)
6262
select decode(12, 'hex');
6363

6464
query error DataFusion error: Error during planning: There is no built\-in encoding named 'non_encoding', currently supported encodings are: base64, hex
@@ -73,7 +73,7 @@ select decode('', null) from test;
7373
query error DataFusion error: This feature is not implemented: Encoding must be a scalar; array specified encoding is not yet supported
7474
select decode('', hex_field) from test;
7575

76-
query error DataFusion error: Error during planning: Internal error: Expect TypeSignatureClass::Integer but received NativeType::String, DataType: Utf8View
76+
query error DataFusion error: Error during planning: Function 'to_hex' requires TypeSignatureClass::Integer, but received String \(DataType: Utf8View\)
7777
select to_hex(hex_field) from test;
7878

7979
query error DataFusion error: Execution error: Failed to decode value using base64

datafusion/sqllogictest/test_files/expr.slt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ select repeat('-1.2', arrow_cast(3, 'Int32'));
589589
----
590590
-1.2-1.2-1.2
591591

592-
query error DataFusion error: Error during planning: Internal error: Expect TypeSignatureClass::Native\(LogicalType\(Native\(Int64\), Int64\)\) but received NativeType::Float64, DataType: Float64
592+
query error DataFusion error: Error during planning: Function 'repeat' requires TypeSignatureClass::Native\(LogicalType\(Native\(Int64\), Int64\)\), but received Float64 \(DataType: Float64\)
593593
select repeat('-1.2', 3.2);
594594

595595
query T

datafusion/sqllogictest/test_files/scalar.slt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2069,7 +2069,7 @@ select position('' in '')
20692069
----
20702070
1
20712071

2072-
query error DataFusion error: Error during planning: Internal error: Expect TypeSignatureClass::Native\(LogicalType\(Native\(String\), String\)\) but received NativeType::Int64, DataType: Int64
2072+
query error DataFusion error: Error during planning: Function 'strpos' requires TypeSignatureClass::Native\(LogicalType\(Native\(String\), String\)\), but received Int64 \(DataType: Int64\)
20732073
select position(1 in 1)
20742074

20752075
query I

0 commit comments

Comments
 (0)