Skip to content

Commit

Permalink
Merge #82703 #83196
Browse files Browse the repository at this point in the history
82703: builtins: remove certain overloads for to_timestamp r=mgartner a=otan

Paving the way for this to be backported - remove some overloads that
were added to remove ambiguity for the purpose of better backwards
compat.

Release note: None

83196: opt: clarify exception to conditional evaluation guarantee r=mgartner a=mgartner

See #20298 and #82498 for additional context.

Release note: None

Co-authored-by: Oliver Tan <[email protected]>
Co-authored-by: Marcus Gartner <[email protected]>
  • Loading branch information
3 people committed Jun 23, 2022
3 parents 0864006 + 3f33cb0 + d5b490b commit 826680e
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 122 deletions.
6 changes: 0 additions & 6 deletions docs/generated/sql/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -655,14 +655,8 @@ has no relationship with the commit order of concurrent transactions.</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="to_timestamp"></a><code>to_timestamp(timestamp: <a href="decimal.html">decimal</a>) &rarr; <a href="timestamp.html">timestamptz</a></code></td><td><span class="funcdesc"><p>Convert Unix epoch (seconds since 1970-01-01 00:00:00+00) to timestamp with time zone.</p>
</span></td></tr>
<tr><td><a name="to_timestamp"></a><code>to_timestamp(timestamp: <a href="float.html">float</a>) &rarr; <a href="timestamp.html">timestamptz</a></code></td><td><span class="funcdesc"><p>Convert Unix epoch (seconds since 1970-01-01 00:00:00+00) to timestamp with time zone.</p>
</span></td></tr>
<tr><td><a name="to_timestamp"></a><code>to_timestamp(timestamp: <a href="int.html">int</a>) &rarr; <a href="timestamp.html">timestamptz</a></code></td><td><span class="funcdesc"><p>Convert Unix epoch (seconds since 1970-01-01 00:00:00+00) to timestamp with time zone.</p>
</span></td></tr>
<tr><td><a name="to_timestamp"></a><code>to_timestamp(timestamp: <a href="string.html">string</a>) &rarr; <a href="timestamp.html">timestamptz</a></code></td><td><span class="funcdesc"><p>Convert Unix epoch (seconds since 1970-01-01 00:00:00+00) to timestamp with time zone.</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
72 changes: 6 additions & 66 deletions pkg/sql/logictest/testdata/logic_test/timestamp
Original file line number Diff line number Diff line change
Expand Up @@ -523,79 +523,19 @@ statement ok
SET TIME ZONE 'UTC'

## Test for to_timestamp without implicit type conversion
query T
SELECT to_timestamp(1646906263.123456)
----
2022-03-10 09:57:43.123456 +0000 UTC

query T
SELECT to_timestamp('1646906263.123456')
----
2022-03-10 09:57:43.123456 +0000 UTC

## Test for to_timestamp with implicit type conversion to int
query T
SELECT to_timestamp(1646906263.123456::INT)
----
2022-03-10 09:57:43 +0000 UTC

query T
SELECT to_timestamp(32767::INT2)
query TTT
SELECT to_timestamp(1646906263.123456), to_timestamp(1646906263), to_timestamp('1646906263.123456')
----
1970-01-01 09:06:07 +0000 UTC

query T
SELECT to_timestamp(1646906263.123456::INT4)
----
2022-03-10 09:57:43 +0000 UTC

query T
SELECT to_timestamp(1646906263.123456::INT8)
----
2022-03-10 09:57:43 +0000 UTC

## Test for to_timestamp with implicit type conversion to float
query T
SELECT to_timestamp(1646906263.123456::FLOAT)
----
2022-03-10 09:57:43.123456 +0000 UTC

query T
SELECT to_timestamp(1646906263.123456::REAL)
----
2022-03-10 09:57:43.123456 +0000 UTC

query T
SELECT to_timestamp(1646906263.123456::DOUBLE PRECISION)
----
2022-03-10 09:57:43.123456 +0000 UTC

## Test for to_timestamp with implicit type conversion to decimal
query T
SELECT to_timestamp(1646906263.123456::DECIMAL)
----
2022-03-10 09:57:43.123456 +0000 UTC
2022-03-10 09:57:43.123456 +0000 UTC 2022-03-10 09:57:43 +0000 UTC 2022-03-10 09:57:43.123456 +0000 UTC

## Test for to_timestamp with positive and negative infinities
query T
SELECT to_timestamp('infinity'::DECIMAL)
----
294276-12-31 23:59:59.999999 +0000 UTC

query T
SELECT to_timestamp('-infinity'::DECIMAL)
query TT
SELECT to_timestamp('infinity'), to_timestamp('-infinity')
----
-4713-11-24 00:00:00 +0000 UTC
294276-12-31 23:59:59.999999 +0000 UTC -4713-11-24 00:00:00 +0000 UTC

## Test for to_timestamp with NULL
query T
SELECT to_timestamp(NULL)
----
NULL

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

statement error unknown signature: to_timestamp\(\)
SELECT to_timestamp()
6 changes: 6 additions & 0 deletions pkg/sql/opt/props/volatility.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ import "github.com/cockroachdb/cockroach/pkg/sql/sem/volatility"
// expression in the usual way, since that would trigger premature
// evaluation.
//
// However, there is a notable exception to this guarantee. When a branch
// is an uncorrelated subquery, it will be evaluated if a previous
// conditional does not evaluate to true at optimization-time. This is due
// to the fact that subqueries are eagerly evaluated when query execution
// begins. See #20298.
//
// 2. Volatile expressions are never treated as constant expressions, even
// though they do not depend on other columns in the query:
//
Expand Down
59 changes: 9 additions & 50 deletions pkg/sql/sem/builtins/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -2653,49 +2653,21 @@ var builtins = map[string]builtinDefinition{
//
"to_timestamp": makeBuiltin(
tree.FunctionProperties{Category: categoryDateAndTime},
tree.Overload{
Types: tree.ArgTypes{{"timestamp", types.String}},
ReturnType: tree.FixedReturnType(types.TimestampTZ),
Fn: func(ctx *eval.Context, args tree.Datums) (tree.Datum, error) {
ts, err := strconv.ParseFloat(string(tree.MustBeDString(args[0])), 64)
if err != nil {
return nil, pgerror.New(pgcode.AmbiguousFunction, "invalid input for type text")
}
return floatToTimestampTZ(ts)
},
Info: "Convert Unix epoch (seconds since 1970-01-01 00:00:00+00) to timestamp with time zone.",
Volatility: volatility.Immutable,
},
tree.Overload{
Types: tree.ArgTypes{{"timestamp", types.Int}},
ReturnType: tree.FixedReturnType(types.TimestampTZ),
Fn: func(ctx *eval.Context, args tree.Datums) (tree.Datum, error) {
ts := float64(tree.MustBeDInt(args[0]))
return floatToTimestampTZ(ts)
},
Info: "Convert Unix epoch (seconds since 1970-01-01 00:00:00+00) to timestamp with time zone.",
Volatility: volatility.Immutable,
},
tree.Overload{
Types: tree.ArgTypes{{"timestamp", types.Float}},
ReturnType: tree.FixedReturnType(types.TimestampTZ),
Fn: func(ctx *eval.Context, args tree.Datums) (tree.Datum, error) {
ts := float64(tree.MustBeDFloat(args[0]))
return floatToTimestampTZ(ts)
},
Info: "Convert Unix epoch (seconds since 1970-01-01 00:00:00+00) to timestamp with time zone.",
Volatility: volatility.Immutable,
},
tree.Overload{
Types: tree.ArgTypes{{"timestamp", types.Decimal}},
ReturnType: tree.FixedReturnType(types.TimestampTZ),
Fn: func(ctx *eval.Context, args tree.Datums) (tree.Datum, error) {
decimal := tree.MustBeDDecimal(args[0]).Decimal
ts, err := decimal.Float64()
if err != nil {
return nil, err
if math.IsNaN(ts) {
return nil, pgerror.New(pgcode.DatetimeFieldOverflow, "timestamp cannot be NaN")
}
if ts == math.Inf(1) {
return tree.MakeDTimestampTZ(pgdate.TimeInfinity, time.Microsecond)
}
return floatToTimestampTZ(ts)
if ts == math.Inf(-1) {
return tree.MakeDTimestampTZ(pgdate.TimeNegativeInfinity, time.Microsecond)
}
return tree.MakeDTimestampTZ(timeutil.Unix(0, int64(ts*float64(time.Second))), time.Microsecond)
},
Info: "Convert Unix epoch (seconds since 1970-01-01 00:00:00+00) to timestamp with time zone.",
Volatility: volatility.Immutable,
Expand Down Expand Up @@ -9648,16 +9620,3 @@ func prettyStatement(p tree.PrettyCfg, stmt string) (string, error) {
}
return formattedStmt.String(), nil
}

func floatToTimestampTZ(ts float64) (tree.Datum, error) {
if math.IsNaN(ts) {
return nil, pgerror.New(pgcode.DatetimeFieldOverflow, "timestamp cannot be NaN")
}
if ts == math.Inf(1) {
return tree.MakeDTimestampTZ(pgdate.TimeInfinity, time.Microsecond)
}
if ts == math.Inf(-1) {
return tree.MakeDTimestampTZ(pgdate.TimeNegativeInfinity, time.Microsecond)
}
return tree.MakeDTimestampTZ(timeutil.Unix(0, int64(ts*float64(time.Second))), time.Microsecond)
}

0 comments on commit 826680e

Please sign in to comment.