Skip to content

Commit

Permalink
builtins: implement parse_time, parse_timetz
Browse files Browse the repository at this point in the history
Note to_char_with_style is not needed as these types do not need date to
output.

Release note (sql change): Implement parse_time and parse_timetz
builtins, which parses a time or timetz with immutable volatility.
  • Loading branch information
otan committed Aug 4, 2021
1 parent cd04e35 commit ed97f6e
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 0 deletions.
8 changes: 8 additions & 0 deletions docs/generated/sql/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2534,10 +2534,18 @@ The output can be used to recreate a database.’</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>
<tr><td><a name="quote_ident"></a><code>quote_ident(val: <a href="string.html">string</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Return <code>val</code> suitably quoted to serve as identifier in a SQL statement.</p>
Expand Down
36 changes: 36 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/datetime
Original file line number Diff line number Diff line change
Expand Up @@ -1900,3 +1900,39 @@ SELECT
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
102 changes: 102 additions & 0 deletions pkg/sql/sem/builtins/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -3179,6 +3179,57 @@ may increase either contention or retry errors, or both.`,
},
),

"parse_time": makeBuiltin(
defProps(),
stringOverload1(
func(ctx *tree.EvalContext, s string) (tree.Datum, error) {
t, dependsOnContext, err := tree.ParseDTime(
tree.NewParseTimeContext(ctx.GetTxnTimestamp(time.Microsecond).Time),
s,
time.Microsecond,
)
if err != nil {
return nil, err
}
if dependsOnContext {
return nil, pgerror.Newf(
pgcode.InvalidParameterValue,
"relative times are not supported",
)
}
return t, nil
},
types.Time,
"Parses a time assuming the date (if any) is in MDY format.",
tree.VolatilityImmutable,
),
tree.Overload{
Types: tree.ArgTypes{{"string", types.String}, {"timestyle", types.String}},
ReturnType: tree.FixedReturnType(types.Time),
Fn: func(ctx *tree.EvalContext, args tree.Datums) (tree.Datum, error) {
arg := string(tree.MustBeDString(args[0]))
dateStyle := string(tree.MustBeDString(args[1]))
parseCtx, err := parseContextFromDateStyle(ctx, dateStyle)
if err != nil {
return nil, err
}
t, dependsOnContext, err := tree.ParseDTime(parseCtx, arg, time.Microsecond)
if err != nil {
return nil, err
}
if dependsOnContext {
return nil, pgerror.Newf(
pgcode.InvalidParameterValue,
"relative times are not supported",
)
}
return t, nil
},
Info: "Parses a time assuming the date (if any) is in format specified by DateStyle.",
Volatility: tree.VolatilityImmutable,
},
),

"parse_interval": makeBuiltin(
defProps(),
stringOverload1(
Expand Down Expand Up @@ -3210,6 +3261,57 @@ may increase either contention or retry errors, or both.`,
},
),

"parse_timetz": makeBuiltin(
defProps(),
stringOverload1(
func(ctx *tree.EvalContext, s string) (tree.Datum, error) {
t, dependsOnContext, err := tree.ParseDTimeTZ(
tree.NewParseTimeContext(ctx.GetTxnTimestamp(time.Microsecond).Time),
s,
time.Microsecond,
)
if err != nil {
return nil, err
}
if dependsOnContext {
return nil, pgerror.Newf(
pgcode.InvalidParameterValue,
"relative times are not supported",
)
}
return t, nil
},
types.TimeTZ,
"Parses a timetz assuming the date (if any) is in MDY format.",
tree.VolatilityImmutable,
),
tree.Overload{
Types: tree.ArgTypes{{"string", types.String}, {"timestyle", types.String}},
ReturnType: tree.FixedReturnType(types.TimeTZ),
Fn: func(ctx *tree.EvalContext, args tree.Datums) (tree.Datum, error) {
arg := string(tree.MustBeDString(args[0]))
dateStyle := string(tree.MustBeDString(args[1]))
parseCtx, err := parseContextFromDateStyle(ctx, dateStyle)
if err != nil {
return nil, err
}
t, dependsOnContext, err := tree.ParseDTimeTZ(parseCtx, arg, time.Microsecond)
if err != nil {
return nil, err
}
if dependsOnContext {
return nil, pgerror.Newf(
pgcode.InvalidParameterValue,
"relative times are not supported",
)
}
return t, nil
},
Info: "Parses a timetz assuming the date (if any) is in format specified by DateStyle.",
Volatility: tree.VolatilityImmutable,
},
),

// Array functions.

"string_to_array": makeBuiltin(arrayPropsNullableArgs(),
Expand Down

0 comments on commit ed97f6e

Please sign in to comment.