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]

Reply via email to