RyanMarcus opened a new issue, #21125:
URL: https://github.com/apache/datafusion/issues/21125

   ### Describe the bug
   
   When a table function is called with a tuple argument, the SQL parser 
preserves the argument, but DataFusion drops it during planning and 
`ContextProvider::get_table_function_source` receives an empty `args` vector.
   
   For example:
   
   ```sql
   SELECT * FROM my_func(('a', 'b', 'c'));
   ```
   
   ... will lead to a call equivalent to `get_table_function_source("my_func", 
vec![])`
   
   ### To Reproduce
   
   With `datafusion-sql` 53.0.0:
   
   ```
   use std::sync::Arc;
   
   use datafusion_common::{arrow::datatypes::DataType, config::ConfigOptions, 
DataFusionError};
   use datafusion_expr::{AggregateUDF, Expr, ScalarUDF, TableSource, WindowUDF};
   use datafusion_sql::{
       planner::{ContextProvider, SqlToRel},
       sqlparser::{dialect::GenericDialect, parser::Parser},
       TableReference,
   };
   
   struct Dummy;
   
   impl ContextProvider for Dummy {
       fn get_table_source(
           &self,
           _name: TableReference,
       ) -> Result<Arc<dyn TableSource>, DataFusionError> {
           unimplemented!()
       }
   
       fn get_table_function_source(
           &self,
           name: &str,
           args: Vec<Expr>,
       ) -> Result<Arc<dyn TableSource>, DataFusionError> {
           println!("table function name={name:?} args={args:#?}");
           unimplemented!()
       }
   
       fn get_function_meta(&self, _name: &str) -> Option<Arc<ScalarUDF>> { 
None }
       fn get_aggregate_meta(&self, _name: &str) -> Option<Arc<AggregateUDF>> { 
None }
       fn get_window_meta(&self, _name: &str) -> Option<Arc<WindowUDF>> { None }
       fn get_variable_type(&self, _variable_names: &[String]) -> 
Option<DataType> { None }
   
       fn options(&self) -> &ConfigOptions {
           static OPTIONS: std::sync::OnceLock<ConfigOptions> = 
std::sync::OnceLock::new();
           OPTIONS.get_or_init(ConfigOptions::default)
       }
   
       fn udf_names(&self) -> Vec<String> { vec![] }
       fn udaf_names(&self) -> Vec<String> { vec![] }
       fn udwf_names(&self) -> Vec<String> { vec![] }
   }
   
   fn main() {
       let sql = "select * from my_func(('a', 'b', 'c'))";
       let dialect = GenericDialect {};
       let ast = Parser::parse_sql(&dialect, sql).unwrap();
   
       println!("ast = {:#?}", ast[0]);
   
       let provider = Dummy;
       let sql_to_rel = SqlToRel::new(&provider);
       let _ = sql_to_rel.sql_statement_to_plan(ast[0].clone());
   }
   ```
   
   `Cargo.toml`:
   
   ```
   [dependencies]
   datafusion-common = "53.0.0"
   datafusion-expr = "53.0.0"
   datafusion-sql = "53.0.0"
   ```
   
   This prints: `table function name="my_func" args=[]`
   
   
   ### Expected behavior
   
   I would expect `get_table_function_source` to either get a non-empty 
argument list, or for planning to return an error.
   
   ### Additional context
   
   _No response_


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to