Skip to content

Commit 51a384b

Browse files
authored
named arguments for table functions (#20)
1 parent 8970cfa commit 51a384b

File tree

8 files changed

+38
-18
lines changed

8 files changed

+38
-18
lines changed

datafusion-cli/src/functions.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,10 @@ fn fixed_len_byte_array_to_string(val: Option<&FixedLenByteArray>) -> Option<Str
320320
pub struct ParquetMetadataFunc {}
321321

322322
impl TableFunctionImpl for ParquetMetadataFunc {
323-
fn call(&self, exprs: &[Expr]) -> Result<Arc<dyn TableProvider>> {
323+
fn call(&self, exprs: &[(Expr, Option<String>)]) -> Result<Arc<dyn TableProvider>> {
324324
let filename = match exprs.first() {
325-
Some(Expr::Literal(ScalarValue::Utf8(Some(s)))) => s, // single quote: parquet_metadata('x.parquet')
326-
Some(Expr::Column(Column { name, .. })) => name, // double quote: parquet_metadata("x.parquet")
325+
Some((Expr::Literal(ScalarValue::Utf8(Some(s))), _)) => s, // single quote: parquet_metadata('x.parquet')
326+
Some((Expr::Column(Column { name, .. }), _)) => name, // double quote: parquet_metadata("x.parquet")
327327
_ => {
328328
return plan_err!(
329329
"parquet_metadata requires string argument as its input"

datafusion-examples/examples/simple_udtf.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,15 @@ impl TableProvider for LocalCsvTable {
132132
struct LocalCsvTableFunc {}
133133

134134
impl TableFunctionImpl for LocalCsvTableFunc {
135-
fn call(&self, exprs: &[Expr]) -> Result<Arc<dyn TableProvider>> {
136-
let Some(Expr::Literal(ScalarValue::Utf8(Some(ref path)))) = exprs.first() else {
135+
fn call(&self, exprs: &[(Expr, Option<String>)]) -> Result<Arc<dyn TableProvider>> {
136+
let Some((Expr::Literal(ScalarValue::Utf8(Some(ref path))), _)) = exprs.first()
137+
else {
137138
return plan_err!("read_csv requires at least one string argument");
138139
};
139140

140141
let limit = exprs
141142
.get(1)
142-
.map(|expr| {
143+
.map(|(expr, _)| {
143144
// try to simplify the expression, so 1+2 becomes 3, for example
144145
let execution_props = ExecutionProps::new();
145146
let info = SimplifyContext::new(&execution_props);

datafusion/catalog/src/table.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ pub trait TableProviderFactory: Debug + Sync + Send {
316316
/// A trait for table function implementations
317317
pub trait TableFunctionImpl: Debug + Sync + Send {
318318
/// Create a table provider
319-
fn call(&self, args: &[Expr]) -> Result<Arc<dyn TableProvider>>;
319+
fn call(&self, args: &[(Expr, Option<String>)]) -> Result<Arc<dyn TableProvider>>;
320320
}
321321

322322
/// A table that uses a function to generate data
@@ -345,7 +345,10 @@ impl TableFunction {
345345
}
346346

347347
/// Get the function implementation and generate a table
348-
pub fn create_table_provider(&self, args: &[Expr]) -> Result<Arc<dyn TableProvider>> {
348+
pub fn create_table_provider(
349+
&self,
350+
args: &[(Expr, Option<String>)],
351+
) -> Result<Arc<dyn TableProvider>> {
349352
self.fun.call(args)
350353
}
351354
}

datafusion/core/src/execution/session_state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1660,7 +1660,7 @@ impl ContextProvider for SessionContextProvider<'_> {
16601660
fn get_table_function_source(
16611661
&self,
16621662
name: &str,
1663-
args: Vec<Expr>,
1663+
args: Vec<(Expr, Option<String>)>,
16641664
) -> datafusion_common::Result<Arc<dyn TableSource>> {
16651665
let tbl_func = self
16661666
.state

datafusion/core/tests/user_defined/user_defined_table_functions.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,11 @@ impl SimpleCsvTable {
200200
struct SimpleCsvTableFunc {}
201201

202202
impl TableFunctionImpl for SimpleCsvTableFunc {
203-
fn call(&self, exprs: &[Expr]) -> Result<Arc<dyn TableProvider>> {
203+
fn call(&self, args: &[(Expr, Option<String>)]) -> Result<Arc<dyn TableProvider>> {
204+
dbg!(args);
204205
let mut new_exprs = vec![];
205206
let mut filepath = String::new();
206-
for expr in exprs {
207+
for (expr, _) in args {
207208
match expr {
208209
Expr::Literal(ScalarValue::Utf8(Some(ref path))) => {
209210
filepath.clone_from(path);

datafusion/expr/src/planner.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub trait ContextProvider {
5252
fn get_table_function_source(
5353
&self,
5454
_name: &str,
55-
_args: Vec<Expr>,
55+
_args: Vec<(Expr, Option<String>)>,
5656
) -> Result<Arc<dyn TableSource>> {
5757
not_impl_err!("Table Functions are not supported")
5858
}

datafusion/functions-table/src/generate_series.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,13 @@ struct GenerateSeriesFuncImpl {
188188
}
189189

190190
impl TableFunctionImpl for GenerateSeriesFuncImpl {
191-
fn call(&self, exprs: &[Expr]) -> Result<Arc<dyn TableProvider>> {
191+
fn call(&self, exprs: &[(Expr, Option<String>)]) -> Result<Arc<dyn TableProvider>> {
192192
if exprs.is_empty() || exprs.len() > 3 {
193193
return plan_err!("{} function requires 1 to 3 arguments", self.name);
194194
}
195195

196196
let mut normalize_args = Vec::new();
197-
for expr in exprs {
197+
for (expr, _) in exprs {
198198
match expr {
199199
Expr::Literal(ScalarValue::Null) => {}
200200
Expr::Literal(ScalarValue::Int64(Some(n))) => normalize_args.push(*n),
@@ -257,7 +257,7 @@ impl TableFunctionImpl for GenerateSeriesFuncImpl {
257257
pub struct GenerateSeriesFunc {}
258258

259259
impl TableFunctionImpl for GenerateSeriesFunc {
260-
fn call(&self, exprs: &[Expr]) -> Result<Arc<dyn TableProvider>> {
260+
fn call(&self, exprs: &[(Expr, Option<String>)]) -> Result<Arc<dyn TableProvider>> {
261261
let impl_func = GenerateSeriesFuncImpl {
262262
name: "generate_series",
263263
include_end: true,
@@ -270,7 +270,7 @@ impl TableFunctionImpl for GenerateSeriesFunc {
270270
pub struct RangeFunc {}
271271

272272
impl TableFunctionImpl for RangeFunc {
273-
fn call(&self, exprs: &[Expr]) -> Result<Arc<dyn TableProvider>> {
273+
fn call(&self, exprs: &[(Expr, Option<String>)]) -> Result<Arc<dyn TableProvider>> {
274274
let impl_func = GenerateSeriesFuncImpl {
275275
name: "range",
276276
include_end: false,

datafusion/sql/src/relation/mod.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,34 @@ impl<S: ContextProvider> SqlToRel<'_, S> {
4747
let args = func_args
4848
.args
4949
.into_iter()
50-
.flat_map(|arg| {
50+
.map(|arg| {
5151
if let FunctionArg::Unnamed(FunctionArgExpr::Expr(expr)) = arg
5252
{
5353
self.sql_expr_to_logical_expr(
5454
expr,
5555
&DFSchema::empty(),
5656
planner_context,
5757
)
58+
.map(|expr| (expr, None))
59+
} else if let FunctionArg::Named { name, arg, .. } = arg {
60+
if let FunctionArgExpr::Expr(expr) = arg {
61+
self.sql_expr_to_logical_expr(
62+
expr,
63+
&DFSchema::empty(),
64+
planner_context,
65+
)
66+
.map(|expr| (expr, Some(name.to_string())))
67+
} else {
68+
plan_err!(
69+
"Unsupported function argument type: {:?}",
70+
arg
71+
)
72+
}
5873
} else {
5974
plan_err!("Unsupported function argument type: {:?}", arg)
6075
}
6176
})
62-
.collect::<Vec<_>>();
77+
.collect::<Result<Vec<_>>>()?;
6378
let provider = self
6479
.context_provider
6580
.get_table_function_source(&tbl_func_name, args)?;

0 commit comments

Comments
 (0)