Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: to_char Function Now Correctly Handles DATE Values in DataFusion #14970

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

kosiew
Copy link
Contributor

@kosiew kosiew commented Mar 3, 2025

Which issue does this PR close?

Rationale for this change

After #14908, the to_char function was incorrectly returning NULL for valid DATE values due to improper handling of the DATE type. This fix ensures that to_char correctly formats non-null DATE values while preserving NULL values as expected.

This is a re-implementation of #14908

What changes are included in this PR?

  • Fixed the to_char function to properly process DATE values.
  • Added slt test cases to verify correct behavior when formatting DATE values.

Are these changes tested?

Yes, new test cases have been added to confirm that:

  1. to_char correctly formats valid DATE values.
  2. NULL values remain unaffected.

Are there any user-facing changes?

No breaking changes. Users will now see correctly formatted DATE values when using to_char, instead of unexpected NULL results.

@github-actions github-actions bot added the functions Changes to functions implementation label Mar 3, 2025
Comment on lines -681 to -707

#[test]
fn test_to_char_input_none_array() {
let date_array = Arc::new(Date32Array::from(vec![Some(18506), None])) as ArrayRef;
let format_array =
StringArray::from(vec!["%Y-%m-%d".to_string(), "%Y-%m-%d".to_string()]);
let args = datafusion_expr::ScalarFunctionArgs {
args: vec![
ColumnarValue::Array(date_array),
ColumnarValue::Array(Arc::new(format_array) as ArrayRef),
],
number_rows: 2,
return_type: &DataType::Utf8,
};
let result = ToCharFunc::new()
.invoke_with_args(args)
.expect("Expected no error");
if let ColumnarValue::Array(result) = result {
let result = result.as_any().downcast_ref::<StringArray>().unwrap();
assert_eq!(result.len(), 2);
// The first element is valid, second is null.
assert!(!result.is_null(0));
assert!(result.is_null(1));
} else {
panic!("Expected an array value");
}
}
Copy link
Contributor Author

@kosiew kosiew Mar 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove test which was added in #14908

@github-actions github-actions bot added the sqllogictest SQL Logic Tests (.slt) label Mar 3, 2025
Comment on lines -215 to -222
// fix https://github.com/apache/datafusion/issues/14884
// If the input date/time is null, return a null Utf8 result.
if array.is_null(0) {
return Ok(match is_scalar_expression {
true => ColumnarValue::Scalar(ScalarValue::Utf8(None)),
false => ColumnarValue::Array(new_null_array(&Utf8, array.len())),
});
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undo #14908

Comment on lines -263 to -269
// fix https://github.com/apache/datafusion/issues/14884
// If the date/time value is null, push None.
if arrays[0].is_null(idx) {
results.push(None);
continue;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undo #14908

Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @kosiew -- this makes sense to me

@@ -234,15 +226,21 @@ fn _to_char_scalar(
};

let formatter = ArrayFormatter::try_new(array.as_ref(), &format_options)?;
let formatted: Result<Vec<_>, ArrowError> = (0..array.len())
.map(|i| formatter.value(i).try_to_string())
let formatted: Result<Vec<Option<String>>, ArrowError> = (0..array.len())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
functions Changes to functions implementation sqllogictest SQL Logic Tests (.slt)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bug: to_char Function Returns NULL for Valid DATE Values in DataFusion
2 participants