[go: up one dir, main page]

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

add core functions make_timestamp_ns(nanos) and epoch_ns(timestamp_ts) #14930

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

andreimatei
Copy link

See individual commits.

@andreimatei
Copy link
Author

cc @hawkfish

I have a feeling that the new make_timestamp_ns function should be listed in extension_entries.hpp, but I have failed to generate that file correctly. I've tried invoking it in different ways, but no matter what I do, the generate_extensions_function.py script deletes all core_functions entries for me. Perhaps I could get help with the right entry. Thanks!

Copy link
Contributor
@hawkfish hawkfish left a comment

Choose a reason for hiding this comment

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

Very minor stuff.

@@ -24,6 +24,8 @@ struct dtime_tz_t; // NOLINT

//! Type used to represent a TIMESTAMP. timestamp_t holds the microseconds since 1970-01-01.
struct timestamp_t { // NOLINT
// NOTE: The unit of value is microseconds for timestamp_t, but it can de
Copy link
Contributor

Choose a reason for hiding this comment

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

"be"

Copy link
Author

Choose a reason for hiding this comment

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

done

@@ -961,3 +961,9 @@ statement error
WITH parts(p) AS (VALUES (['year', 'month', 'day']), (['hour', 'minute', 'microsecond']))
SELECT DATE_PART(p, ts) FROM parts, timestamps;
----

# epoch_ns has nanosecond precision on TIMESTAMP_TS
Copy link
Contributor

Choose a reason for hiding this comment

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

"NS"

Copy link
Author

Choose a reason for hiding this comment

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

done

@@ -98,7 +98,7 @@ struct MakeTimestampOperator {

template <typename T, typename RESULT_TYPE>
static RESULT_TYPE Operation(T micros) {
return timestamp_t(micros);
return RESULT_TYPE(micros);
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we should rename micros to value or something?

Copy link
Author

Choose a reason for hiding this comment

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

separated change to its own commit and done

@hawkfish
Copy link
Contributor

cc @hawkfish

I have a feeling that the new make_timestamp_ns function should be listed in extension_entries.hpp, but I have failed to generate that file correctly. I've tried invoking it in different ways, but no matter what I do, the generate_extensions_function.py script deletes all core_functions entries for me. Perhaps I could get help with the right entry. Thanks!

You've got me - this has changed recently and I've been on holiday. @taniabogatsch ?

@andreimatei
Copy link
Author

You've got me - this has changed recently and I've been on holiday. @taniabogatsch ?

Actually, a failing test on CI told me what to add to that file. Done.

@andreimatei andreimatei marked this pull request as ready for review November 21, 2024 21:10
Copy link
Contributor
@taniabogatsch taniabogatsch left a comment

Choose a reason for hiding this comment

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

@hawkfish, indeed, there have been a few changes to the s, ms, ns types. See #14818.

@@ -189,6 +191,7 @@ class Timestamp {
DUCKDB_API static int64_t GetEpochMicroSeconds(timestamp_t timestamp);
//! Convert a timestamp to epoch (in nanoseconds)
DUCKDB_API static int64_t GetEpochNanoSeconds(timestamp_t timestamp);
DUCKDB_API static int64_t GetEpochNanoSeconds(timestamp_ns_t timestamp);
Copy link
Contributor

Choose a reason for hiding this comment

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

This is the same as directly accessing value, no? I'm unsure if we need it, but I'm also okay with adding it.

Copy link
Author

Choose a reason for hiding this comment

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

This is the same as directly accessing value, no?

Yes. But so is GetEpochMicroSeconds(timestamp_t timestamp) -- and that function exists.
So, if it's up to me, I'd leave it. But I don't know this code at all, so...

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, that's fine, we can leave it. 👍

Comment on lines +220 to +225
# From nanoseconds
query II
SELECT make_timestamp_ns(0), make_timestamp_ns(1684509234845000123);
----
1970-01-01 00:00:00 2023-05-19 15:13:54.845000123

Copy link
Contributor

Choose a reason for hiding this comment

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

Should we add tests for min and max values?

Copy link
Author

Choose a reason for hiding this comment

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

Do you mean make_timestamp_ns(-9,223,372,036,854,775,808) and make_timestamp_ns(9,223,372,036,854,775,807) ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, or you can find them in the built in table function test_all_types().

Copy link
Author
@andreimatei andreimatei Nov 25, 2024

Choose a reason for hiding this comment

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

I've added a test for the maximum values.

For negative values, I've ran into some problems:
make_timestamp_ns(-1) triggers an assertion:

select make_timestamp_ns(-1);
INTERNAL Error:
Information loss on integer cast: value -952 outside of target range [-128, 127]

I couldn't immediately figure out why, or how to get a stack trace for the respective exception.

select make_timestamp(-9223372036854775807) correctly says -infinity.

make_timestamp_ns(-9223372036854775806) says:

select make_timestamp_ns(-9223372036854775806);
Conversion Error:
Date out of range in timestamp_ns conversion

This is similar to make_timestamp(-9223372036854775806). I don't know if the behavior is good; I couldn't find a lower limit for make_timestamp() documented anywhere.

Would it be acceptable to reject any negative argument to make_timestamp_ns() ? I'll kindly take advice for how to proceed / if you could look into the assertion error if rejecting negative input is not acceptable, I'd appreciate it.

MakeTimestampOperator was claiming to be generic in the type of
timestamp it can produce, but in fact it was only producing timestamp_t.
Make it actually generic; in the next patch we'll use it to produce
timestamp_ns_t.
Add a function constructing a TIMESTAMP_NS from nanos since epoch. This
function is modeled after one of the overloads of make_timestamp(micros)
which constructs a TIMESTAMP.
Before this patch, epoch_ns only worked on TIMESTAMP input. Calling it
on a TIMESTAMP_NS implied a cast, which dropped from nanos resolution to
micros. This patch adds an overload for TIMESTAMP_NS.

Beyond being useful at face value, this new overload also means that you
now have a way of computing the difference between two TIMESTAMP_NS
values and retaining nanos precision (simply doing TIMESTAMP_NS -
TIMESTAMP_NS gives you an INTERVAL, which implies micros precision).
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