diff --git a/pkg/sql/as_of_test.go b/pkg/sql/as_of_test.go index d162a644e072..be76490ab985 100644 --- a/pkg/sql/as_of_test.go +++ b/pkg/sql/as_of_test.go @@ -161,7 +161,7 @@ func TestAsOfTime(t *testing.T) { } // String values that are neither timestamps nor decimals are an error. - if _, err := db.Query("SELECT a FROM d.t AS OF SYSTEM TIME 'xxx'"); !testutils.IsError(err, "value is neither timestamp nor decimal") { + if _, err := db.Query("SELECT a FROM d.t AS OF SYSTEM TIME 'xxx'"); !testutils.IsError(err, "value is neither timestamp, decimal, nor interval") { t.Fatal(err) } diff --git a/pkg/sql/executor.go b/pkg/sql/executor.go index 96e8b5d8f5e6..5cee83db26ab 100644 --- a/pkg/sql/executor.go +++ b/pkg/sql/executor.go @@ -2480,20 +2480,24 @@ func EvalAsOfTimestamp( break } // Attempt to parse as a decimal. - if dec, _, err := apd.NewFromString(s); err != nil { - // Override the error. It would be misleading to fail with a - // DECIMAL conversion error if a user was attempting to use a - // timestamp string and the conversion above failed. - convErr = errors.Errorf("AS OF SYSTEM TIME: value is neither timestamp nor decimal") - } else { + if dec, _, err := apd.NewFromString(s); err == nil { ts, convErr = decimalToHLC(dec) + break + } + // Attempt to parse as an interval. + if iv, err := tree.ParseDInterval(s); err == nil { + ts.WallTime = duration.Add(evalCtx.GetStmtTimestamp(), iv.Duration).UnixNano() + break } + convErr = errors.Errorf("AS OF SYSTEM TIME: value is neither timestamp, decimal, nor interval") case *tree.DInt: ts.WallTime = int64(*d) case *tree.DDecimal: ts, convErr = decimalToHLC(&d.Decimal) + case *tree.DInterval: + ts.WallTime = duration.Add(evalCtx.GetStmtTimestamp(), d.Duration).UnixNano() default: - convErr = errors.Errorf("AS OF SYSTEM TIME: expected timestamp, got %s (%T)", d.ResolvedType(), d) + convErr = errors.Errorf("AS OF SYSTEM TIME: expected timestamp, decimal, or interval, got %s (%T)", d.ResolvedType(), d) } if convErr != nil { return ts, convErr diff --git a/pkg/sql/logictest/testdata/logic_test/as_of b/pkg/sql/logictest/testdata/logic_test/as_of new file mode 100644 index 000000000000..2c962dc1c6d5 --- /dev/null +++ b/pkg/sql/logictest/testdata/logic_test/as_of @@ -0,0 +1,30 @@ +# LogicTest: default + +statement ok +CREATE TABLE t (i INT) + +statement ok +INSERT INTO t VALUES (2) + +# Verify strings can be parsed as intervals. +query I +SELECT * FROM t AS OF SYSTEM TIME '-0ns' +---- +2 + +query I +SELECT * FROM t AS OF SYSTEM TIME '-1ns' +---- +2 + +# Verify a forced interval type works. +query I +SELECT * FROM t AS OF SYSTEM TIME INTERVAL '-1ns' +---- +2 + +statement error pq: relation "t" does not exist +SELECT * FROM t AS OF SYSTEM TIME '-1h' + +statement error cannot specify timestamp in the future +SELECT * FROM t AS OF SYSTEM TIME '10s'