This is an automated email from the ASF dual-hosted git repository.

avantgardner pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-datafusion.git


The following commit(s) were added to refs/heads/main by this push:
     new 47bdda60b UDF zero params #5378 (#5380)
47bdda60b is described below

commit 47bdda60b992e2d17e0169133e7dd2a34483de59
Author: Jay Miller <[email protected]>
AuthorDate: Fri Feb 24 14:44:43 2023 -0500

    UDF zero params #5378 (#5380)
    
    * UDF zero params #5378
    
    * cippy
---
 datafusion/core/tests/sql/udf.rs        | 58 +++++++++++++++++++++++++++++++++
 datafusion/physical-expr/src/planner.rs |  5 ++-
 2 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/datafusion/core/tests/sql/udf.rs b/datafusion/core/tests/sql/udf.rs
index 4b68f30e9..a1c485956 100644
--- a/datafusion/core/tests/sql/udf.rs
+++ b/datafusion/core/tests/sql/udf.rs
@@ -121,6 +121,64 @@ async fn scalar_udf() -> Result<()> {
     Ok(())
 }
 
+#[tokio::test]
+async fn scalar_udf_zero_params() -> Result<()> {
+    let schema = Schema::new(vec![Field::new("a", DataType::Int32, false)]);
+
+    let batch = RecordBatch::try_new(
+        Arc::new(schema.clone()),
+        vec![Arc::new(Int32Array::from_slice([1, 10, 10, 100]))],
+    )?;
+    let ctx = SessionContext::new();
+
+    ctx.register_batch("t", batch)?;
+    // create function just returns 100 regardless of inp
+    let myfunc = |args: &[ArrayRef]| {
+        let num_rows = args[0].len();
+        Ok(Arc::new((0..num_rows).map(|_| 100).collect::<Int32Array>()) as 
ArrayRef)
+    };
+    let myfunc = make_scalar_function(myfunc);
+
+    ctx.register_udf(create_udf(
+        "get_100",
+        vec![],
+        Arc::new(DataType::Int32),
+        Volatility::Immutable,
+        myfunc,
+    ));
+
+    let result = plan_and_collect(&ctx, "select get_100() a from t").await?;
+    let expected = vec![
+        "+-----+", //
+        "| a   |", //
+        "+-----+", //
+        "| 100 |", //
+        "| 100 |", //
+        "| 100 |", //
+        "| 100 |", //
+        "+-----+", //
+    ];
+    assert_batches_eq!(expected, &result);
+
+    let result = plan_and_collect(&ctx, "select get_100() a").await?;
+    let expected = vec![
+        "+-----+", //
+        "| a   |", //
+        "+-----+", //
+        "| 100 |", //
+        "+-----+", //
+    ];
+    assert_batches_eq!(expected, &result);
+
+    let result = plan_and_collect(&ctx, "select get_100() from t where 
a=999").await?;
+    let expected = vec![
+        "++", //
+        "++",
+    ];
+    assert_batches_eq!(expected, &result);
+    Ok(())
+}
+
 /// tests the creation, registration and usage of a UDAF
 #[tokio::test]
 async fn simple_udaf() -> Result<()> {
diff --git a/datafusion/physical-expr/src/planner.rs 
b/datafusion/physical-expr/src/planner.rs
index 31d28f820..105de17c2 100644
--- a/datafusion/physical-expr/src/planner.rs
+++ b/datafusion/physical-expr/src/planner.rs
@@ -393,7 +393,10 @@ pub fn create_physical_expr(
                     execution_props,
                 )?);
             }
-
+            // udfs with zero params expect null array as input
+            if args.is_empty() {
+                physical_args.push(Arc::new(Literal::new(ScalarValue::Null)));
+            }
             udf::create_physical_expr(fun.clone().as_ref(), &physical_args, 
input_schema)
         }
         Expr::Between(Between {

Reply via email to