This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git
The following commit(s) were added to refs/heads/main by this push:
new 058bcb0014 fix: custom nullability for format_string (#19173) (#19190)
058bcb0014 is described below
commit 058bcb0014eae420675dad549f9a263a4eeb96f1
Author: Kushagra S <[email protected]>
AuthorDate: Fri Dec 26 06:37:51 2025 +0530
fix: custom nullability for format_string (#19173) (#19190)
## Which issue does this PR close?
- Closes #19173
## What changes are included in this PR?
- includes custom nullability for `format_string`.
---------
Co-authored-by: Andrew Lamb <[email protected]>
---
.../spark/src/function/string/format_string.rs | 63 ++++++++++++++++++----
1 file changed, 54 insertions(+), 9 deletions(-)
diff --git a/datafusion/spark/src/function/string/format_string.rs
b/datafusion/spark/src/function/string/format_string.rs
index 5261251ced..73de985109 100644
--- a/datafusion/spark/src/function/string/format_string.rs
+++ b/datafusion/spark/src/function/string/format_string.rs
@@ -23,7 +23,7 @@ use core::num::FpCategory;
use arrow::{
array::{Array, ArrayRef, LargeStringArray, StringArray, StringViewArray},
- datatypes::DataType,
+ datatypes::{DataType, Field, FieldRef},
};
use bigdecimal::{
BigDecimal, ToPrimitive,
@@ -34,8 +34,8 @@ use datafusion_common::{
DataFusionError, Result, ScalarValue, exec_datafusion_err, exec_err,
plan_err,
};
use datafusion_expr::{
- ColumnarValue, ScalarFunctionArgs, ScalarUDFImpl, Signature, TypeSignature,
- Volatility,
+ ColumnarValue, ReturnFieldArgs, ScalarFunctionArgs, ScalarUDFImpl,
Signature,
+ TypeSignature, Volatility,
};
/// Spark-compatible `format_string` expression
@@ -78,14 +78,23 @@ impl ScalarUDFImpl for FormatStringFunc {
&self.signature
}
- fn return_type(&self, arg_types: &[DataType]) -> Result<DataType> {
- match arg_types[0] {
- DataType::Null => Ok(DataType::Utf8),
+ fn return_type(&self, _arg_types: &[DataType]) -> Result<DataType> {
+ datafusion_common::internal_err!(
+ "return_type should not be called, use return_field_from_args
instead"
+ )
+ }
+
+ fn return_field_from_args(&self, args: ReturnFieldArgs) ->
Result<FieldRef> {
+ match args.arg_fields[0].data_type() {
+ DataType::Null => {
+ Ok(Arc::new(Field::new("format_string", DataType::Utf8, true)))
+ }
DataType::Utf8 | DataType::LargeUtf8 | DataType::Utf8View => {
- Ok(arg_types[0].clone())
+ Ok(Arc::clone(&args.arg_fields[0]))
}
- _ => plan_err!(
- "The format_string function expects the first argument to be
Utf8, LargeUtf8 or Utf8View"
+ _ => exec_err!(
+ "format_string expects the first argument to be Utf8,
LargeUtf8 or Utf8View, got {} instead",
+ args.arg_fields[0].data_type()
),
}
}
@@ -2347,3 +2356,39 @@ fn trim_trailing_0s_hex(number: &str) -> &str {
}
number
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use arrow::datatypes::DataType::Utf8;
+ use datafusion_common::Result;
+
+ #[test]
+ fn test_format_string_nullability() -> Result<()> {
+ let func = FormatStringFunc::new();
+ let nullable_format: FieldRef = Arc::new(Field::new("fmt", Utf8,
true));
+
+ let out_nullable = func.return_field_from_args(ReturnFieldArgs {
+ arg_fields: &[nullable_format],
+ scalar_arguments: &[None],
+ })?;
+
+ assert!(
+ out_nullable.is_nullable(),
+ "format_string(fmt, ...) should be nullable when fmt is nullable"
+ );
+ let non_nullable_format: FieldRef = Arc::new(Field::new("fmt", Utf8,
false));
+
+ let out_non_nullable = func.return_field_from_args(ReturnFieldArgs {
+ arg_fields: &[non_nullable_format],
+ scalar_arguments: &[None],
+ })?;
+
+ assert!(
+ !out_non_nullable.is_nullable(),
+ "format_string(fmt, ...) should NOT be nullable when fmt is NOT
nullable"
+ );
+
+ Ok(())
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]