diff --git a/datafusion/sql/src/relation/mod.rs b/datafusion/sql/src/relation/mod.rs index 6558763ca4e42..14ccab870317e 100644 --- a/datafusion/sql/src/relation/mod.rs +++ b/datafusion/sql/src/relation/mod.rs @@ -151,7 +151,7 @@ impl SqlToRel<'_, S> { let args = func_args .args .into_iter() - .flat_map(|arg| { + .map(|arg| { if let FunctionArg::Unnamed(FunctionArgExpr::Expr(expr)) = arg { self.sql_expr_to_logical_expr( @@ -163,7 +163,7 @@ impl SqlToRel<'_, S> { plan_err!("Unsupported function argument type: {}", arg) } }) - .collect::>(); + .collect::>>()?; let provider = self .context_provider .get_table_function_source(&tbl_func_name, args)?; diff --git a/datafusion/sql/tests/sql_integration.rs b/datafusion/sql/tests/sql_integration.rs index 29c17be69ce5f..8edd3ae9c02f5 100644 --- a/datafusion/sql/tests/sql_integration.rs +++ b/datafusion/sql/tests/sql_integration.rs @@ -4588,6 +4588,26 @@ fn plan_create_index() { } } +#[test] +fn test_table_function_with_unsupported_arg_propagates_error() { + let sql = "SELECT * FROM my_func(('a', 'b', 'c'))"; + let dialect = &GenericDialect {}; + let state = MockSessionState::default(); + let context = MockContextProvider { state }; + let planner = SqlToRel::new(&context); + let result = DFParser::parse_sql_with_dialect(sql, dialect); + let mut ast = result.unwrap(); + let err = planner + .statement_to_plan(ast.pop_front().unwrap()) + .expect_err("query should have failed"); + let msg = err.strip_backtrace(); + assert!( + !msg.contains("Table Functions are not supported"), + "tuple argument error should be propagated before reaching get_table_function_source, got: {msg}" + ); + assert_contains!(msg, "Struct not supported"); +} + fn assert_field_not_found(mut err: DataFusionError, name: &str) { let err = loop { match err { diff --git a/datafusion/sqllogictest/test_files/table_functions.slt b/datafusion/sqllogictest/test_files/table_functions.slt index f0e00ffc69233..3d654c4195feb 100644 --- a/datafusion/sqllogictest/test_files/table_functions.slt +++ b/datafusion/sqllogictest/test_files/table_functions.slt @@ -397,7 +397,7 @@ SELECT * FROM range(TIMESTAMP '2023-01-03T00:00:00', TIMESTAMP '2023-01-01T00:00 # Single timestamp (start == end) query P -SELECT * FROM range(TIMESTAMP '2023-01-01T00:00:00', TIMESTAMP '2023-01-01T00:00:00', INTERVAL '1' DAY) +SELECT * FROM range(TIMESTAMP '2023-01-01T00:00:00', TIMESTAMP '2023-01-01T00:00:00', INTERVAL '1' DAY) ---- # Timestamp range with NULL values @@ -543,3 +543,16 @@ LIMIT 10; 1 1 1 + +# Test that unsupported function argument types are properly reported +# rather than being silently dropped (which previously caused a misleading +# "requires 1 to 3 arguments" error instead) + +statement error DataFusion error: Error during planning: Unsupported function argument type: start => 1 +SELECT * FROM generate_series(start => 1, stop => 5) + +statement error DataFusion error: Error during planning: Unsupported function argument type: \* +SELECT * FROM generate_series(*) + +statement error DataFusion error: Error during planning: Unsupported function argument type: t\.\* +SELECT * FROM generate_series(t.*)