-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
base: main
Are you sure you want to change the base?
Conversation
cc @hawkfish I have a feeling that the new |
There was a problem hiding this 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"be"
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"NS"
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
You've got me - this has changed recently and I've been on holiday. @taniabogatsch ? |
90b87fb
to
43a1d84
Compare
43a1d84
to
da42e2d
Compare
Actually, a failing test on CI told me what to add to that file. Done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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...
There was a problem hiding this comment.
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. 👍
# 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 | ||
|
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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)
?
There was a problem hiding this comment.
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()
.
There was a problem hiding this comment.
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).
da42e2d
to
e7a2a18
Compare
See individual commits.