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

builtins: implement to_timestamp for Unix epoch #82523

Merged
merged 1 commit into from
Jun 9, 2022
Merged

builtins: implement to_timestamp for Unix epoch #82523

merged 1 commit into from
Jun 9, 2022

Conversation

nnaka2992
Copy link
Contributor

fixes #77591

Previously, CockroachDB did not support to_timestamp(double precision)
In PostgreSQL, the function also handles INT, DECIMAL and text by casting,
so the commit also implements those for compatibility.

Release note (sql change): Add new function to_timestamp which
converts Unix epoch of FLOAT, INT, DECIMAL and text to Timestamp with time zone.

@nnaka2992 nnaka2992 requested a review from a team June 7, 2022 15:21
@blathers-crl
Copy link

blathers-crl bot commented Jun 7, 2022

Thank you for contributing to CockroachDB. Please ensure you have followed the guidelines for creating a PR.

My owl senses detect your PR is good for review. Please keep an eye out for any test failures in CI.

🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is otan.

@blathers-crl blathers-crl bot added the O-community Originated from the community label Jun 7, 2022
@cockroach-teamcity
Copy link
Member

This change is Reviewable

@blathers-crl
Copy link

blathers-crl bot commented Jun 7, 2022

Thank you for updating your pull request.

My owl senses detect your PR is good for review. Please keep an eye out for any test failures in CI.

🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is otan.

Copy link
Contributor

@otan otan left a comment

Choose a reason for hiding this comment

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

thanks! just some small tweaks.


## Test for invalid inputs
statement error to_timestamp\(\): invalid input for type text
SELECT to_timestamp('invalid')
Copy link
Contributor

Choose a reason for hiding this comment

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

can you add test cases for NaN too

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added test of to_timestamp() for testing NaN.

if ts == math.Inf(-1) {
return tree.MakeDTimestampTZ(pgdate.TimeNegativeInfinity, time.Microsecond)
}
strts := strings.Split(strconv.FormatFloat(ts, 'f', 6, 64), ".")
Copy link
Contributor

Choose a reason for hiding this comment

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

we should not be casting to string to do this.
return tree.MakeDTimestampTZ(timeutil.Unix(0, int64(ts * float64(time.Second)), time.Microsecond)` should do the trick!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using tree.MakeDTimestampTZ(timeutil.Unix(0, int64(ts * float64(time.Second)), time.Microsecond) instead of custing to string.

if math.IsNaN(ts) {
return nil, pgerror.New(pgcode.DatetimeFieldOverflow, "timestamp cannot be NaN")
}
if ts == math.Inf(0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

this should be Inf(1) - please add a test for pos/neg inf.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Inf(0) and Inf(1) are the same thing, but just fixed

@blathers-crl blathers-crl bot requested a review from otan June 8, 2022 07:50
fixes #77591

Previously, CockroachDB did not support to_timestamp(double precision)
In PostgreSQL, the function also handles INT, DECIMAL and text by casting,
so the commit also implements those for compatibility.

Release note (sql change): Add new function to_timestamp which
converts Unix epoch of FLOAT, INT, DECIMAL and text to Timestamp with time zone.
Copy link
Contributor

@otan otan left a comment

Choose a reason for hiding this comment

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

bors r+

@craig
Copy link
Contributor

craig bot commented Jun 9, 2022

Build succeeded:

@korpa
Copy link

korpa commented Jun 9, 2022

Will this be released in the next 22.1 version or do we have to wait till 22.2?

@otan
Copy link
Contributor

otan commented Jun 9, 2022

22.2 unless there's compelling reason. is there a use case you need it for?

@korpa
Copy link

korpa commented Jun 9, 2022

Yes, there is a reason: apache/superset#15825

return floatToTimestampTZ(ts)
},
Info: "Convert Unix epoch (seconds since 1970-01-01 00:00:00+00) to timestamp with time zone.",
Volatility: volatility.Immutable,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe this should be stable, not immutable. In Postgres:

marcus=# select proargtypes, prorettype::regtype, provolatile, proleakproof from pg_proc where proname = 'to_timestamp';
 proargtypes |        prorettype        | provolatile | proleakproof
-------------+--------------------------+-------------+--------------
 701         | timestamp with time zone | i           | f
 25 25       | timestamp with time zone | s           | f
(2 rows)

marcus=# select 701::oid::regtype, 25::oid::regtype;
     regtype      | regtype
------------------+---------
 double precision | text
(1 row)

Copy link
Contributor

Choose a reason for hiding this comment

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

The one arg version is immutable - so this is right right?

// postgres=# select to_timestamp('1646906263.123456');
// to_timestamp
// -------------------------------
// 2022-03-10 09:57:43.123456+00
Copy link
Collaborator

Choose a reason for hiding this comment

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

This PR adds overloads that do not exist in Postgres. The only two overloads in PG are to_timestamp(double_precision) and to_timestamp(text, text).

All of these other examples work because the argument type can be implicitly cast to a FLOAT8, or they are parsed as numeric types, as in to_timestamp('1646906263.123456').

Copy link
Contributor Author

@nnaka2992 nnaka2992 Jun 9, 2022

Choose a reason for hiding this comment

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

It is better if we can implicitly cast (or parse) text to numeric on function call. However at least on v22, CockroachDB
does not perform implicit casting, so I added the overload, to_timestamp(text) for compatibility.

Is it much suitable to fix overload.go (or any other files) to parse text as numeric?

"to_timestamp": makeBuiltin(
tree.FunctionProperties{Category: categoryDateAndTime},
tree.Overload{
Types: tree.ArgTypes{{"timestamp", types.String}},
Copy link
Collaborator

Choose a reason for hiding this comment

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

The string overload should take two string arguments. https://www.postgresql.org/docs/current/functions-formatting.html

Copy link
Collaborator

Choose a reason for hiding this comment

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

would this be the same as experimental_strptime?

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's similar, but experimental_strptime doesn't support the same formatting strings as to_timestamp. Here's an example from the Postgres docs:

defaultdb> select experimental_strptime('05 Dec 2000', 'DD Mon YYYY');
  experimental_strptime
--------------------------
  0001-01-01 00:00:00+00

The result should be 2000-12-05 00:00:00-05 (assuming the timezone is set to -05). It looks like experimental_strptime returns a default value when parsing fails, rather than erring.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-community Originated from the community
Projects
None yet
Development

Successfully merging this pull request may close these issues.

builtins: implement to_timestamp
6 participants