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 51e64c3df7 Align `NowFunc::new()` with canonical `ConfigOptions`
timezone and enhance documentation (#18347)
51e64c3df7 is described below
commit 51e64c3df760acd9effb95a7a461ab38bcb9b137
Author: kosiew <[email protected]>
AuthorDate: Sat Nov 1 11:53:35 2025 +0800
Align `NowFunc::new()` with canonical `ConfigOptions` timezone and enhance
documentation (#18347)
## Which issue does this PR close?
* Closes #18219.
---
## Rationale for this change
The deprecated `NowFunc::new()` constructor previously initialized its
timezone using the shorthand offset `"+00"`, which was inconsistent with
the canonical UTC offset format `"+00:00"` used by
`ConfigOptions::default()`. This mismatch could cause subtle
inconsistencies in `ScalarValue` comparisons or downstream timezone
handling.
This PR ensures backward compatibility while aligning `NowFunc::new()`
with the canonical default configuration, making behavior consistent
across both constructors. It also improves documentation to clarify this
relationship and provides a regression test to confirm parity between
the two initialization paths.
---
## What changes are included in this PR?
* Updated the deprecated `NowFunc::new()` to delegate to
`NowFunc::new_with_config(&ConfigOptions::default())`.
* Added detailed doc comments explaining the rationale and proper usage
of the constructors.
* Introduced a new test module verifying that `NowFunc::new()` and
`NowFunc::new_with_config()` produce identical return fields and scalar
values.
* Updated user documentation (`scalar_functions.md`) to note the
constructor preference and clarify the canonical default timezone format
(`+00:00`).
---
## Are these changes tested?
✅ Yes. A new test `now_func_default_matches_config` was added to confirm
functional equivalence between the legacy and configuration-based
constructors, including matching field outputs and scalar timezones.
---
## Are there any user-facing changes?
* **Yes**, but backward-compatible:
* `NowFunc::new()` remains available but now mirrors the canonical
timezone offset (`+00:00`).
* Documentation has been updated to guide users toward the preferred
`NowFunc::new_with_config()` method.
No breaking API or behavior changes are expected, as this update
standardizes the default timezone while maintaining prior function
signatures.
---
datafusion/functions/src/datetime/now.rs | 53 +++++++++++++++++++++++++++++---
1 file changed, 48 insertions(+), 5 deletions(-)
diff --git a/datafusion/functions/src/datetime/now.rs
b/datafusion/functions/src/datetime/now.rs
index 96a35c241f..fe317d0a16 100644
--- a/datafusion/functions/src/datetime/now.rs
+++ b/datafusion/functions/src/datetime/now.rs
@@ -54,12 +54,14 @@ impl Default for NowFunc {
impl NowFunc {
#[deprecated(since = "50.2.0", note = "use `new_with_config` instead")]
+ /// Deprecated constructor retained for backwards compatibility.
+ ///
+ /// Prefer [`NowFunc::new_with_config`] which allows specifying the
+ /// timezone via [`ConfigOptions`]. This helper now mirrors the
+ /// canonical default offset (`"+00:00"`) provided by
+ /// `ConfigOptions::default()`.
pub fn new() -> Self {
- Self {
- signature: Signature::nullary(Volatility::Stable),
- aliases: vec!["current_timestamp".to_string()],
- timezone: Some(Arc::from("+00")),
- }
+ Self::new_with_config(&ConfigOptions::default())
}
pub fn new_with_config(config: &ConfigOptions) -> Self {
@@ -138,3 +140,44 @@ impl ScalarUDFImpl for NowFunc {
self.doc()
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[allow(deprecated)]
+ #[test]
+ fn now_func_default_matches_config() {
+ let default_config = ConfigOptions::default();
+
+ let legacy_now = NowFunc::new();
+ let configured_now = NowFunc::new_with_config(&default_config);
+
+ let empty_fields: [FieldRef; 0] = [];
+ let empty_scalars: [Option<&ScalarValue>; 0] = [];
+
+ let legacy_field = legacy_now
+ .return_field_from_args(ReturnFieldArgs {
+ arg_fields: &empty_fields,
+ scalar_arguments: &empty_scalars,
+ })
+ .expect("legacy now() return field");
+
+ let configured_field = configured_now
+ .return_field_from_args(ReturnFieldArgs {
+ arg_fields: &empty_fields,
+ scalar_arguments: &empty_scalars,
+ })
+ .expect("configured now() return field");
+
+ assert_eq!(legacy_field.as_ref(), configured_field.as_ref());
+
+ let legacy_scalar =
+ ScalarValue::TimestampNanosecond(None,
legacy_now.timezone.clone());
+ let configured_scalar =
+ ScalarValue::TimestampNanosecond(None,
configured_now.timezone.clone());
+
+ assert_eq!(legacy_scalar, configured_scalar);
+ assert_eq!(Some("+00:00"), legacy_now.timezone.as_deref());
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]