Skip to content

Commit

Permalink
Merge #68351
Browse files Browse the repository at this point in the history
68351: builtins: add parse and to_char_with_style variants for date types r=rafiss a=otan

See individual commits for details.

Co-authored-by: Oliver Tan <[email protected]>
  • Loading branch information
craig[bot] and otan committed Aug 8, 2021
2 parents 049ed14 + ed97f6e commit 62ec88c
Show file tree
Hide file tree
Showing 7 changed files with 486 additions and 35 deletions.
32 changes: 29 additions & 3 deletions docs/generated/sql/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -512,8 +512,6 @@ and which stays constant throughout the transaction. This timestamp
has no relationship with the commit order of concurrent transactions.</p>
<p>This function is the preferred overload and will be evaluated by default.</p>
</span></td></tr>
<tr><td><a name="parse_interval"></a><code>parse_interval(string: <a href="string.html">string</a>, style: <a href="string.html">string</a>) &rarr; <a href="interval.html">interval</a></code></td><td><span class="funcdesc"><p>Convert a string to an interval using the given IntervalStyle.</p>
</span></td></tr>
<tr><td><a name="statement_timestamp"></a><code>statement_timestamp() &rarr; <a href="timestamp.html">timestamp</a></code></td><td><span class="funcdesc"><p>Returns the start time of the current statement.</p>
</span></td></tr>
<tr><td><a name="statement_timestamp"></a><code>statement_timestamp() &rarr; <a href="timestamp.html">timestamptz</a></code></td><td><span class="funcdesc"><p>Returns the start time of the current statement.</p>
Expand All @@ -530,6 +528,12 @@ has no relationship with the commit order of concurrent transactions.</p>
</span></td></tr>
<tr><td><a name="timezone"></a><code>timezone(timezone: <a href="string.html">string</a>, timetz: timetz) &rarr; timetz</code></td><td><span class="funcdesc"><p>Convert given time with time zone to the new time zone.</p>
</span></td></tr>
<tr><td><a name="to_char"></a><code>to_char(date: <a href="date.html">date</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Convert an date to a string assuming the ISO, MDY DateStyle.</p>
</span></td></tr>
<tr><td><a name="to_char"></a><code>to_char(interval: <a href="interval.html">interval</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Convert an interval to a string assuming the Postgres IntervalStyle.</p>
</span></td></tr>
<tr><td><a name="to_char"></a><code>to_char(timestamp: <a href="timestamp.html">timestamp</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Convert an timestamp to a string assuming the ISO, MDY DateStyle.</p>
</span></td></tr>
<tr><td><a name="transaction_timestamp"></a><code>transaction_timestamp() &rarr; <a href="date.html">date</a></code></td><td><span class="funcdesc"><p>Returns the time of the current transaction.</p>
<p>The value is based on a timestamp picked when the transaction starts
and which stays constant throughout the transaction. This timestamp
Expand Down Expand Up @@ -2534,7 +2538,25 @@ The output can be used to recreate a database.’</p>
</span></td></tr>
<tr><td><a name="overlay"></a><code>overlay(input: <a href="string.html">string</a>, overlay_val: <a href="string.html">string</a>, start_pos: <a href="int.html">int</a>, end_pos: <a href="int.html">int</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Deletes the characters in <code>input</code> between <code>start_pos</code> and <code>end_pos</code> (count starts at 1), and then insert <code>overlay_val</code> at <code>start_pos</code>.</p>
</span></td></tr>
<tr><td><a name="parse_timestamp"></a><code>parse_timestamp(string: <a href="string.html">string</a>) &rarr; <a href="timestamp.html">timestamp</a></code></td><td><span class="funcdesc"><p>Convert a string containing an absolute timestamp to the corresponding timestamp.</p>
<tr><td><a name="parse_date"></a><code>parse_date(string: <a href="string.html">string</a>, datestyle: <a href="string.html">string</a>) &rarr; <a href="date.html">date</a></code></td><td><span class="funcdesc"><p>Parses a date assuming it is in format specified by DateStyle.</p>
</span></td></tr>
<tr><td><a name="parse_date"></a><code>parse_date(val: <a href="string.html">string</a>) &rarr; <a href="date.html">date</a></code></td><td><span class="funcdesc"><p>Parses a date assuming it is in MDY format.</p>
</span></td></tr>
<tr><td><a name="parse_interval"></a><code>parse_interval(string: <a href="string.html">string</a>, style: <a href="string.html">string</a>) &rarr; <a href="interval.html">interval</a></code></td><td><span class="funcdesc"><p>Convert a string to an interval using the given IntervalStyle.</p>
</span></td></tr>
<tr><td><a name="parse_interval"></a><code>parse_interval(val: <a href="string.html">string</a>) &rarr; <a href="interval.html">interval</a></code></td><td><span class="funcdesc"><p>Convert a string to an interval assuming the Postgres IntervalStyle.</p>
</span></td></tr>
<tr><td><a name="parse_time"></a><code>parse_time(string: <a href="string.html">string</a>, timestyle: <a href="string.html">string</a>) &rarr; <a href="time.html">time</a></code></td><td><span class="funcdesc"><p>Parses a time assuming the date (if any) is in format specified by DateStyle.</p>
</span></td></tr>
<tr><td><a name="parse_time"></a><code>parse_time(val: <a href="string.html">string</a>) &rarr; <a href="time.html">time</a></code></td><td><span class="funcdesc"><p>Parses a time assuming the date (if any) is in MDY format.</p>
</span></td></tr>
<tr><td><a name="parse_timestamp"></a><code>parse_timestamp(string: <a href="string.html">string</a>, datestyle: <a href="string.html">string</a>) &rarr; <a href="timestamp.html">timestamp</a></code></td><td><span class="funcdesc"><p>Convert a string containing an absolute timestamp to the corresponding timestamp assuming dates formatted using the given DateStyle.</p>
</span></td></tr>
<tr><td><a name="parse_timestamp"></a><code>parse_timestamp(val: <a href="string.html">string</a>) &rarr; <a href="timestamp.html">timestamp</a></code></td><td><span class="funcdesc"><p>Convert a string containing an absolute timestamp to the corresponding timestamp assuming dates are in MDY format.</p>
</span></td></tr>
<tr><td><a name="parse_timetz"></a><code>parse_timetz(string: <a href="string.html">string</a>, timestyle: <a href="string.html">string</a>) &rarr; timetz</code></td><td><span class="funcdesc"><p>Parses a timetz assuming the date (if any) is in format specified by DateStyle.</p>
</span></td></tr>
<tr><td><a name="parse_timetz"></a><code>parse_timetz(val: <a href="string.html">string</a>) &rarr; timetz</code></td><td><span class="funcdesc"><p>Parses a timetz assuming the date (if any) is in MDY format.</p>
</span></td></tr>
<tr><td><a name="pg_collation_for"></a><code>pg_collation_for(str: anyelement) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Returns the collation of the argument</p>
</span></td></tr>
Expand Down Expand Up @@ -2724,8 +2746,12 @@ The output can be used to recreate a database.’</p>
</span></td></tr>
<tr><td><a name="substring"></a><code>substring(input: varbit, start_pos: <a href="int.html">int</a>, length: <a href="int.html">int</a>) &rarr; varbit</code></td><td><span class="funcdesc"><p>Returns a bit subarray of <code>input</code> starting at <code>start_pos</code> (count starts at 1) and including up to <code>length</code> characters.</p>
</span></td></tr>
<tr><td><a name="to_char_with_style"></a><code>to_char_with_style(date: <a href="date.html">date</a>, datestyle: <a href="string.html">string</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Convert an date to a string assuming the string is formatted using the given DateStyle.</p>
</span></td></tr>
<tr><td><a name="to_char_with_style"></a><code>to_char_with_style(interval: <a href="interval.html">interval</a>, style: <a href="string.html">string</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Convert an interval to a string using the given IntervalStyle.</p>
</span></td></tr>
<tr><td><a name="to_char_with_style"></a><code>to_char_with_style(timestamp: <a href="timestamp.html">timestamp</a>, datestyle: <a href="string.html">string</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Convert an timestamp to a string assuming the string is formatted using the given DateStyle.</p>
</span></td></tr>
<tr><td><a name="to_english"></a><code>to_english(val: <a href="int.html">int</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>This function enunciates the value of its argument using English cardinals.</p>
</span></td></tr>
<tr><td><a name="to_hex"></a><code>to_hex(val: <a href="bytes.html">bytes</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Converts <code>val</code> to its hexadecimal representation.</p>
Expand Down
124 changes: 110 additions & 14 deletions pkg/sql/logictest/testdata/logic_test/datetime
Original file line number Diff line number Diff line change
Expand Up @@ -1704,20 +1704,6 @@ SELECT 'infinity'::timestamp, '-infinity'::timestamptz
----
294276-12-31 23:59:59.999999 +0000 +0000 -4713-11-24 00:00:00 +0000 +0000

query T
SELECT parse_timestamp('2020-01-02 01:02:03')
----
2020-01-02 01:02:03 +0000 +0000

query error could not parse
SELECT parse_timestamp('foo')

query error parse_timestamp\(\): relative timestamps are not supported
SELECT parse_timestamp('now')

query error parse_timestamp\(\): relative timestamps are not supported
SELECT parse_timestamp('tomorrow')

# Verify that parse_timestamp can be used in computed column expressions.
statement ok
CREATE TABLE timestamps (s STRING, ts TIMESTAMP AS (parse_timestamp(s)) STORED)
Expand Down Expand Up @@ -1879,3 +1865,113 @@ FROM ( VALUES
2020-09-15 15:17:19.123 +0000 UTC 2020-09-15 15:17:19.123 +0000 +0000 0000-01-01 15:17:19.123 +0000 UTC 0000-01-01 15:17:19.123 +0000 UTC 2020-09-15 00:00:00 +0000 +0000
1995-03-04 15:16:19.123 +0000 UTC 1995-03-04 15:16:19.123 +0000 +0000 0000-01-01 15:16:19.123 +0000 UTC 0000-01-01 15:16:19.123 +0000 UTC 1995-03-04 00:00:00 +0000 +0000
2020-09-05 15:17:19.123 +0000 UTC 2020-09-05 15:17:19.123 +0000 +0000 0000-01-01 15:17:19.123 +0000 UTC 0000-01-01 15:17:19.123 +0000 UTC 2020-09-05 00:00:00 +0000 +0000

statement error only ISO style is supported
SELECT parse_timestamp('01-02-2020 01:02:03', 'postgres')

query error could not parse
SELECT parse_timestamp('foo')

query error parse_timestamp\(\): relative timestamps are not supported
SELECT parse_timestamp('now')

query error parse_timestamp\(\): relative timestamps are not supported
SELECT parse_timestamp('tomorrow')

query error parse_timestamp\(\): relative timestamps are not supported
SELECT parse_timestamp('now', 'mdy')

statement error only ISO style is supported
SELECT to_char_with_style(now()::timestamp, 'postgres')

query TT
SELECT
to_char('2020-01-02 01:02:03'::timestamp),
to_char_with_style('2020-01-02 01:02:03'::timestamp, 'DMY')
----
2020-01-02 01:02:03 2020-01-02 01:02:03

statement ok
CREATE TABLE timestamp_datestyle_parse(pk SERIAL PRIMARY KEY, s string);
INSERT INTO timestamp_datestyle_parse VALUES
(1, '07-09-12 11:30:45.123'),
(2, '07-09-12')

query TTTT
SELECT
parse_timestamp(s),
parse_timestamp(s, 'iso,mdy'),
parse_timestamp(s, 'iso,dmy'),
parse_timestamp(s, 'iso,ymd')
FROM timestamp_datestyle_parse
ORDER BY pk
----
2012-07-09 11:30:45.123 +0000 +0000 2012-07-09 11:30:45.123 +0000 +0000 2012-09-07 11:30:45.123 +0000 +0000 2007-09-12 11:30:45.123 +0000 +0000
2012-07-09 00:00:00 +0000 +0000 2012-07-09 00:00:00 +0000 +0000 2012-09-07 00:00:00 +0000 +0000 2007-09-12 00:00:00 +0000 +0000

statement error only ISO style is supported
SELECT parse_date('01-02-2020 01:02:03', 'postgres')

query error parse_date\(\): relative dates are not supported
SELECT parse_date('now')

query error parse_date\(\): relative dates are not supported
SELECT parse_date('tomorrow', 'iso,mdy')

query TTTT
SELECT
parse_date(s),
parse_date(s, 'iso,mdy'),
parse_date(s, 'iso,dmy'),
parse_date(s, 'iso,ymd')
FROM timestamp_datestyle_parse
ORDER BY pk
----
2012-07-09 00:00:00 +0000 +0000 2012-07-09 00:00:00 +0000 +0000 2012-09-07 00:00:00 +0000 +0000 2007-09-12 00:00:00 +0000 +0000
2012-07-09 00:00:00 +0000 +0000 2012-07-09 00:00:00 +0000 +0000 2012-09-07 00:00:00 +0000 +0000 2007-09-12 00:00:00 +0000 +0000

statement error only ISO style is supported
SELECT to_char_with_style(now()::date, 'postgres')

query TT
SELECT
to_char('2020-01-02 01:02:03'::date),
to_char_with_style('2020-01-02 01:02:03'::date, 'DMY')
----
2020-01-02 2020-01-02

statement ok
CREATE TABLE time_datestyle_parse(pk SERIAL PRIMARY KEY, s string);
INSERT INTO time_datestyle_parse VALUES
(1, '2007-09-12 11:30:45.123+06'),
(2, '2007-09-12 11:30:45.123+03')

statement error only ISO style is supported
SELECT parse_time('01-02-2020 01:02:03', 'postgres')

query TTTT
SELECT
parse_time(s),
parse_time(s, 'iso,mdy'),
parse_time(s, 'iso,dmy'),
parse_time(s, 'iso,ymd')
FROM time_datestyle_parse
ORDER BY pk
----
0000-01-01 11:30:45.123 +0000 UTC 0000-01-01 11:30:45.123 +0000 UTC 0000-01-01 11:30:45.123 +0000 UTC 0000-01-01 11:30:45.123 +0000 UTC
0000-01-01 11:30:45.123 +0000 UTC 0000-01-01 11:30:45.123 +0000 UTC 0000-01-01 11:30:45.123 +0000 UTC 0000-01-01 11:30:45.123 +0000 UTC

statement error only ISO style is supported
SELECT parse_timetz('01-02-2020 01:02:03', 'postgres')

query TTTT
SELECT
parse_timetz(s),
parse_timetz(s, 'iso,mdy'),
parse_timetz(s, 'iso,dmy'),
parse_timetz(s, 'iso,ymd')
FROM time_datestyle_parse
ORDER BY pk
----
0000-01-01 11:30:45.123 +0600 +0600 0000-01-01 11:30:45.123 +0600 +0600 0000-01-01 11:30:45.123 +0600 +0600 0000-01-01 11:30:45.123 +0600 +0600
0000-01-01 11:30:45.123 +0300 +0300 0000-01-01 11:30:45.123 +0300 +0300 0000-01-01 11:30:45.123 +0300 +0300 0000-01-01 11:30:45.123 +0300 +0300
21 changes: 12 additions & 9 deletions pkg/sql/logictest/testdata/logic_test/interval
Original file line number Diff line number Diff line change
Expand Up @@ -404,12 +404,12 @@ SET intervalstyle = 'sql_standard'
statement ok
SET intervalstyle_enabled = 'on'

statement error context-dependent operators are not allowed in computed column\nHINT: INTERVAL to STRING casts depends on IntervalStyle; consider using to_char_with_style\(interval, 'postgres'\)
statement error context-dependent operators are not allowed in computed column\nHINT: INTERVAL to STRING casts depends on IntervalStyle; consider using to_char\(interval\)
CREATE TABLE invalid_table (
invalid_col string AS ('1 hour'::interval::string) STORED
)

statement error string::interval: context-dependent operators are not allowed in computed column\nHINT: STRING to INTERVAL casts depend on session IntervalStyle; use parse_interval\(string, 'postgres'\) instead
statement error string::interval: context-dependent operators are not allowed in computed column\nHINT: STRING to INTERVAL casts depend on session IntervalStyle; use parse_interval\(string\) instead
CREATE TABLE invalid_table (
invalid_col interval AS ('1 hour'::string::interval) STORED
)
Expand Down Expand Up @@ -445,29 +445,32 @@ SELECT i FROM intervals ORDER BY pk
1 day 04:06:08.123
2 years 11 mons -2 days +03:25:45.678

query TTTBBB
WITH tbl(pk, i, pg, iso, sql_std) AS (
query TTTTBBBB
WITH tbl(pk, i, pg, iso, sql_std, default_style) AS (
SELECT
pk,
i,
to_char_with_style(i, 'postgres') AS pg,
to_char_with_style(i, 'iso_8601') AS iso,
to_char_with_style(i, 'sql_standard') AS sql_std
to_char_with_style(i, 'sql_standard') AS sql_std,
to_char(i) AS default_style
FROM intervals
)
SELECT
pg,
iso,
sql_std,
default_style,
i = parse_interval(pg, 'postgres'),
i = parse_interval(iso, 'iso_8601'),
i = parse_interval(sql_std, 'sql_standard')
i = parse_interval(sql_std, 'sql_standard'),
i = parse_interval(default_style) AND pg = default_style
FROM tbl
ORDER BY pk
----
-2 years -11 mons +1 day 04:05:06.123 P-2Y-11M1DT4H5M6.123S -2-11 +1 +4:05:06.123 true true true
1 day 04:06:08.123 P1DT4H6M8.123S 1 4:06:08.123 true true true
2 years 11 mons -2 days +03:25:45.678 P2Y11M-2DT3H25M45.678S +2-11 -2 +3:25:45.678 true true true
-2 years -11 mons +1 day 04:05:06.123 P-2Y-11M1DT4H5M6.123S -2-11 +1 +4:05:06.123 -2 years -11 mons +1 day 04:05:06.123 true true true true
1 day 04:06:08.123 P1DT4H6M8.123S 1 4:06:08.123 1 day 04:06:08.123 true true true true
2 years 11 mons -2 days +03:25:45.678 P2Y11M-2DT3H25M45.678S +2-11 -2 +3:25:45.678 2 years 11 mons -2 days +03:25:45.678 true true true true

query T
SELECT array_to_string(array_agg(i ORDER BY pk), ' ') FROM intervals
Expand Down
1 change: 1 addition & 0 deletions pkg/sql/sem/builtins/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ go_library(
"//pkg/util/timeofday",
"//pkg/util/timetz",
"//pkg/util/timeutil",
"//pkg/util/timeutil/pgdate",
"//pkg/util/tracing",
"//pkg/util/ulid",
"//pkg/util/unaccent",
Expand Down
Loading

0 comments on commit 62ec88c

Please sign in to comment.