diff --git a/datafusion/catalog/src/table.rs b/datafusion/catalog/src/table.rs index c6468fd5ad131..65e7336130618 100644 --- a/datafusion/catalog/src/table.rs +++ b/datafusion/catalog/src/table.rs @@ -552,8 +552,10 @@ pub trait TableProviderFactory: Debug + Sync + Send { /// Describes arguments provided to the table function call. pub struct TableFunctionArgs<'e, 's> { - /// Call arguments. + /// Call arguments (potentially coerced/simplified). exprs: &'e [Expr], + /// Original raw arguments before any coercion/simplification. + raw_exprs: &'e [Expr], /// Session within which the function is called. session: &'s dyn Session, } @@ -561,7 +563,11 @@ pub struct TableFunctionArgs<'e, 's> { impl<'e, 's> TableFunctionArgs<'e, 's> { /// Make a new [`TableFunctionArgs`]. pub fn new(exprs: &'e [Expr], session: &'s dyn Session) -> Self { - Self { exprs, session } + Self { + exprs, + raw_exprs: exprs, + session, + } } /// Get expressions passed as the called function arguments. @@ -569,12 +575,41 @@ impl<'e, 's> TableFunctionArgs<'e, 's> { self.exprs } + /// Get the original, unprocessed call arguments (before + /// type coercion and simplification). + /// + /// The arguments returned by [`Self::exprs`] may have been + /// type-coerced or simplified. Use this method to access the + /// arguments exactly as the user wrote them in the SQL query. + pub fn raw_exprs(&self) -> &'e [Expr] { + self.raw_exprs + } + /// Get a session where the table function is called. pub fn session(&self) -> &'s dyn Session { self.session } } +impl<'e, 's> TableFunctionArgs<'e, 's> { + /// Make a new [`TableFunctionArgs`] with separate processed and raw expressions. + /// + /// This is useful when the table function implementation needs + /// access to both the (possibly coerced/simplified) expressions + /// and the original expressions as written. + pub fn new_with_raw( + exprs: &'e [Expr], + raw_exprs: &'e [Expr], + session: &'s dyn Session, + ) -> Self { + Self { + exprs, + raw_exprs, + session, + } + } +} + /// A trait for table function implementations pub trait TableFunctionImpl: Debug + Sync + Send + Any { /// Create a table provider diff --git a/datafusion/core/src/execution/session_state.rs b/datafusion/core/src/execution/session_state.rs index ad525ac7b1bba..b1e1aefe714fb 100644 --- a/datafusion/core/src/execution/session_state.rs +++ b/datafusion/core/src/execution/session_state.rs @@ -1984,16 +1984,20 @@ impl ContextProvider for SessionContextProvider<'_> { .build(); let simplifier = ExprSimplifier::new(simplify_context); let schema = DFSchema::empty(); + let raw_args = args.clone(); let args = args .into_iter() .map(|arg| { + let backup = arg.clone(); simplifier .coerce(arg, &schema) .and_then(|e| simplifier.simplify(e)) + .unwrap_or(backup) }) - .collect::>>()?; - let provider = tbl_func - .create_table_provider_with_args(TableFunctionArgs::new(&args, self.state))?; + .collect::>(); + let provider = tbl_func.create_table_provider_with_args( + TableFunctionArgs::new_with_raw(&args, &raw_args, self.state), + )?; Ok(provider_as_source(provider)) }