Skip to content

Add missing datetime functions#1467

Merged
timsaucer merged 2 commits intoapache:mainfrom
timsaucer:feat/missing-datetime-functions
Apr 2, 2026
Merged

Add missing datetime functions#1467
timsaucer merged 2 commits intoapache:mainfrom
timsaucer:feat/missing-datetime-functions

Conversation

@timsaucer
Copy link
Copy Markdown
Member

Which issue does this PR close?

Closes #1451

Rationale for this change

Adds missing functions

What changes are included in this PR?

Expose rust code.
Add python wrapper.
Add unit tests.

Are there any user-facing changes?

New addition only

timsaucer and others added 2 commits March 30, 2026 13:01
…rmat

Closes apache#1451. Adds make_time Rust binding and Python wrapper, and adds
current_timestamp (alias for now) and date_format (alias for to_char)
Python functions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@timsaucer timsaucer marked this pull request as ready for review March 30, 2026 19:45
@timsaucer timsaucer requested a review from Copilot March 30, 2026 19:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Python-level exposure for missing DataFusion date/time functions requested in #1451, including Rust bindings where needed.

Changes:

  • Exposed make_time through the Rust functions module and registered it for Python.
  • Added Python wrappers for current_timestamp (alias of now) and date_format (alias of to_char), plus a new make_time wrapper.
  • Added unit tests covering the new aliases and make_time behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
python/tests/test_functions.py Adds tests validating current_timestamp/date_format aliases and make_time output.
python/datafusion/functions.py Exposes current_timestamp, date_format, and make_time in the public functions API.
crates/core/src/functions.rs Adds Rust-side make_time expression binding and registers it in the Python module init.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

@nuno-faria nuno-faria left a comment

Choose a reason for hiding this comment

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

Thanks @timsaucer.

Comment on lines +1954 to +1962
def current_timestamp() -> Expr:
"""Returns the current timestamp in nanoseconds.

See Also:
This is an alias for :py:func:`now`.
"""
return now()


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't know if it's critical but the resulting column name in this case will be now, while in DataFusion it's current_timestamp.

> select now();
+-------------------------------+
| now()                         |
+-------------------------------+
| 2026-04-02T15:46:14.652469200 |
+-------------------------------+
1 row(s) fetched.
Elapsed 0.001 seconds.

> select current_timestamp();
+----------------------------+
| current_timestamp()        |
+----------------------------+
| 2026-04-02T15:46:17.026273 |
+----------------------------+
1 row(s) fetched.
Elapsed 0.001 seconds.

Should this function call the Rust equivalent directly?

Comment on lines +1985 to +1993
def date_format(arg: Expr, formatter: Expr) -> Expr:
"""Returns a string representation of a date, time, timestamp or duration.

See Also:
This is an alias for :py:func:`to_char`.
"""
return to_char(arg, formatter)


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Similar issue here:

> select to_char('2026-12-13'::timestamp, '%Y/%m/%d');
+----------------------------------------------+
| to_char(Utf8("2026-12-13"),Utf8("%Y/%m/%d")) |
+----------------------------------------------+
| 2026/12/13                                   |
+----------------------------------------------+
1 row(s) fetched.
Elapsed 0.001 seconds.

> select date_format('2026-12-13'::timestamp, '%Y/%m/%d');
+-------------------------------------------------------------------------+
| date_format(CAST(Utf8("2026-12-13") AS Timestamp(ns)),Utf8("%Y/%m/%d")) |
+-------------------------------------------------------------------------+
| 2026/12/13                                                              |
+-------------------------------------------------------------------------+
1 row(s) fetched.
Elapsed 0.001 seconds.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I was looking at this. It's true that we do get the alias via SQL, but we actually will get this same behavior for all aliases. This impacts our existing things like:

from datafusion import SessionContext, functions as F, col
import pyarrow as pa
import numpy as np

data = [[1.0, 2.0, 3.0, 3.0], [4.0, 5.0, 3.0], [6.0]]
ctx = SessionContext()
batch = pa.RecordBatch.from_arrays([np.array(data, dtype=object)], names=["arr"])
df = ctx.create_dataframe([[batch]])

df.select(
    F.list_sort(col("arr")),
).show()

Results in:

DataFrame()
+----------------------------------------------------------------------------------+
| array_sort(c3b76956cf32e4475aab41190fde60912.arr,Utf8("ASC"),Utf8("NULLS LAST")) |
+----------------------------------------------------------------------------------+
| [1.0, 2.0, 3.0, 3.0]                                                             |
| [3.0, 4.0, 5.0]                                                                  |
| [6.0]                                                                            |
+----------------------------------------------------------------------------------+

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think this is okay for aliases. If you think it's a blocker we can open an issue to try to overcome this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not a problem for me as well. Just pointing it out just in case.

@timsaucer timsaucer merged commit 0113a6e into apache:main Apr 2, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add missing date/time functions (current_timestamp, date_format, make_time)

3 participants