Skip to content

[SQL] Support for TIME/DATE/TIMESTAMP constructors#6315

Merged
mihaibudiu merged 1 commit into
feldera:mainfrom
mihaibudiu:make_time
May 27, 2026
Merged

[SQL] Support for TIME/DATE/TIMESTAMP constructors#6315
mihaibudiu merged 1 commit into
feldera:mainfrom
mihaibudiu:make_time

Conversation

@mihaibudiu

Copy link
Copy Markdown
Contributor

Adds support for 3 Spark functions

MAKE_TIME
MAKE_DATE
MAKE_TIMESTAMP

These functions are very difficult to implement otherwise (they require creating a string and parsing it), so I decided to build them as primitives. felderize flagged them as missing. See the tests and the documentation for a precise definition.

Two of these functions are polymorphic, accepting integers, decimals, and float for expressing fractional seconds; our Rust implementation is not polymorphic, so supporting all variants requires implementing multiple Rust functions, depending on argument types.

Checklist

  • Unit tests added/updated
  • Integration tests added/updated
  • Documentation updated
  • Changelog updated

| Function | Arguments | Result | Description | Example |
|----------|-----------|--------|-------------|---------|
|<a id="time_trunc"></a>`TIME_TRUNC(time, *unit*)` | `*unit*` is a time unit, as described above, between `HOUR` and `SECOND` | `TIME` | Rounds down the time to the specified time unit | `TIME_TRUNC('12:34:56.78', MINUTE)` => `12:34:00` |
|<a id="time_ceil"></a> `CEIL(time TO *unit*)` | `*unit*` is a time unit between `HOUR` and `MICROSECOND` | `TIME` | It rounds a time upward to the start of the next unit boundary unless the value is already exactly on that boundary. | `CEIL('17:01:00' TO HOUR)` => `18:00:00` |

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I just ordered these alphabetically

@mihaibudiu mihaibudiu requested a review from wilmaontherun May 25, 2026 18:12

@mythical-fred mythical-fred left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

A few blockers — see inline. Most important: year 9999 is rejected by an exclusive range (off-by-one vs. the documented date range), and MAKE_TIMESTAMP is not documented in datetime.md although the docs checkbox is checked.

Comment thread crates/sqllib/src/timestamp.rs Outdated
Comment thread crates/sqllib/src/timestamp.rs
Comment thread crates/sqllib/src/timestamp.rs Outdated
Comment thread crates/sqllib/src/timestamp.rs
|<a id="time_ceil"></a> `CEIL(time TO *unit*)` | `*unit*` is a time unit between `HOUR` and `MICROSECOND` | `TIME` | It rounds a time upward to the start of the next unit boundary unless the value is already exactly on that boundary. | `CEIL('17:01:00' TO HOUR)` => `18:00:00` |
|<a id="time_floor"></a>`FLOOR(time TO *unit*)` | `*unit*` is a time unit between `HOUR` and `MICROSECOND` | `TIME` | It rounds a time downward to the start of the next unit boundary unless the value is already exactly on that boundary. | `FLOOR('17:23:59' TO MINUTE)` => `17:23:00` |
|<a id="time_extract"></a>`EXTRACT(*unit* FROM time)` | `*unit*` is a time unit from `HOUR`, `MINUTE`, `SECOND`, `MILLISECOND` | `BIGINT` | Extracts the specified part | `EXTRACT(HOUR FROM '17:23:59')` => `17` |
| <a id="make_time"></a>`MAKE_TIME(hour, minute, second)` | Any numeric type; last argument can be fractional | `TIME` | Creates a `TIME` from a hour, minute, second; returns `NULL` if the `TIME` is invalid. | `MAKE_TIME(20, 1, 1)` => `20:01:01` |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

MAKE_TIMESTAMP is added as a new SQL function but is not documented in this file. The PR checklist has Documentation updated ticked, but only MAKE_DATE and MAKE_TIME rows are present. Please add an entry describing the 6-argument signature, the polymorphic second argument, and the NULL-on-invalid semantics. The pre-existing prose around line 222 about a user-defined MAKE_TIMESTAMP(SECONDS BIGINT) should also be reconciled — that example collides with the new built-in name and will confuse readers.

Comment thread docs.feldera.com/docs/sql/datetime.md Outdated
@mihaibudiu mihaibudiu force-pushed the make_time branch 3 times, most recently from 8284454 to 93dfa17 Compare May 25, 2026 21:05
Comment thread crates/sqllib/src/lib.rs Outdated

pub(crate) use some_polymorphic_function3;

// If there exists a function is f_t1_t2_t3(x: T, y: S, z: V) -> Option<U>, this creates

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.

Suggested change
// If there exists a function is f_t1_t2_t3(x: T, y: S, z: V) -> Option<U>, this creates
/// If there exists a function is f_t1_t2_t3(x: T, y: S, z: V) -> Option<U>, this creates
...

Comment thread crates/sqllib/src/lib.rs Outdated
// If there exists a function is f_t1_t2_t3(x: T, y: S, z: V) -> Option<U>, this creates
// seven functions:
// - f_t1_t2_t3N(x: T, y: S, z: Option<V>) -> Option<U>
// - f_t1_t2N_t2(x: T, y: Option<S>, z: V) -> Option<U>

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.

There may be a universe where you can solve this using some trait with impl for From<Option> and no ugly macro hacks

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It is a little sad that for implementing one SQL function sometimes I need tens of Rust functions. Maybe we are too strongly typed.

@mythical-fred mythical-fred left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All blockers from my previous review are addressed. Four nits inline — none blocking.

this.ensureInteger(node, ops, 0);
this.ensureInteger(node, ops, 1);
validateArgCount(node, operationName, ops.size(), 3);
validateArgCount(node, operationName, ops.size(), 3);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit: duplicate validateArgCount call — line 1713 already does the same check.

NULL
(1 row)

SELECT MAKE_DATE(9999, 12, 31);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit: duplicate test — MAKE_DATE(9999, 12, 31) is already tested at line 432.

01:02:03.5
(1 row)

SELECT MAKE_TIME(1, 2, 35e-1);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit: duplicate test — MAKE_TIME(1, 2, 35e-1) is already at line 293.

Comment thread docs.feldera.com/docs/sql/datetime.md Outdated
<td><code>TIMESTAMP</code></td>
<td>Rounds a timestamp upward to the start of the next unit boundary unless the value is already exactly on that boundary.</td>
<td><code>CEIL('2024-05-04 17:23:01' TO MINUTE)</code> => <code>2024-05-04 17:24:00</code></td>
<td>Creates a <code>TIMESTAMP</code> from parts; returns `NULL` if the result is not a valid timestamp.</td>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit: backtick markdown (NULL) won't render inside an HTML <td>. Use <code>NULL</code> instead.

@mihaibudiu mihaibudiu added this pull request to the merge queue May 25, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch May 26, 2026
@mihaibudiu mihaibudiu enabled auto-merge May 26, 2026 03:57
@mihaibudiu mihaibudiu added this pull request to the merge queue May 26, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 26, 2026
@mihaibudiu mihaibudiu added this pull request to the merge queue May 26, 2026
@gz gz removed this pull request from the merge queue due to a manual request May 26, 2026
@mihaibudiu mihaibudiu added this pull request to the merge queue May 26, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 26, 2026
@mihaibudiu mihaibudiu added this pull request to the merge queue May 26, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 27, 2026
Signed-off-by: Mihai Budiu <mbudiu@feldera.com>
@mihaibudiu mihaibudiu enabled auto-merge May 27, 2026 03:33
@mihaibudiu mihaibudiu added this pull request to the merge queue May 27, 2026
Merged via the queue into feldera:main with commit adb1ece May 27, 2026
1 check passed
@mihaibudiu mihaibudiu deleted the make_time branch May 27, 2026 10:22
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.

3 participants