From c9eebc9612d1f1ac9a6ad882c07df0ed39d62a8f Mon Sep 17 00:00:00 2001 From: James Cor Date: Thu, 27 Mar 2025 16:18:49 -0700 Subject: [PATCH 1/5] more fixing for unix_timestmap --- enginetest/queries/script_queries.go | 8 ++++++++ sql/expression/convert.go | 5 +++-- sql/expression/function/date.go | 23 +++++++++++++---------- sql/types/datetime.go | 3 +++ 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/enginetest/queries/script_queries.go b/enginetest/queries/script_queries.go index 1956b88f35..14f53663f5 100644 --- a/enginetest/queries/script_queries.go +++ b/enginetest/queries/script_queries.go @@ -5133,6 +5133,8 @@ CREATE TABLE tab3 ( Name: "UNIX_TIMESTAMP function preserves trailing 0s", SetUpScript: []string{ "SET time_zone = '+07:00';", + "create table t (d0 datetime(0), d1 datetime(1), d2 datetime(2), d3 datetime(3), d4 datetime(4), d5 datetime(5), d6 datetime(6));", + "insert into t values ('2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456')", }, Assertions: []ScriptTestAssertion{ { @@ -5153,6 +5155,12 @@ CREATE TABLE tab3 ( {"981178496.123457"}, }, }, + { + Query: "select unix_timestamp(d0), unix_timestamp(d1), unix_timestamp(d2), unix_timestamp(d3), unix_timestamp(d4), unix_timestamp(d5), unix_timestamp(d6) from t;", + Expected: []sql.Row{ + {"1577943296", "1577943296.1", "1577943296.12", "1577943296.123", "1577943296.1235", "1577943296.12346", "1577943296.123456"}, + }, + }, }, }, diff --git a/sql/expression/convert.go b/sql/expression/convert.go index 9f1136dc96..7e49191075 100644 --- a/sql/expression/convert.go +++ b/sql/expression/convert.go @@ -17,7 +17,8 @@ package expression import ( "encoding/hex" "fmt" - "strconv" + "github.com/dolthub/vitess/go/sqltypes" +"strconv" "strings" "time" @@ -155,7 +156,7 @@ func (c *Convert) Type() sql.Type { case ConvertToDate: return types.Date case ConvertToDatetime: - return types.DatetimeMaxPrecision + return types.MustCreateDatetimeType(sqltypes.Datetime, c.typeLength) case ConvertToDecimal: if c.cachedDecimalType == nil { c.cachedDecimalType = createConvertedDecimalType(c.typeLength, c.typeScale, true) diff --git a/sql/expression/function/date.go b/sql/expression/function/date.go index e2568b54f2..be5582290c 100644 --- a/sql/expression/function/date.go +++ b/sql/expression/function/date.go @@ -406,18 +406,18 @@ var _ sql.CollationCoercible = (*UnixTimestamp)(nil) const MaxUnixTimeMicroSecs = 32536771199999999 // noEval returns true if the expression contains an expression that cannot be evaluated without sql.Context or sql.Row. -func noEval(expr sql.Expression) bool { - var hasBadExpr bool +func canEval(expr sql.Expression) bool { + // Convert Timezone is not evaluable + evaluable := true transform.InspectExpr(expr, func(e sql.Expression) bool { switch e.(type) { - case *expression.GetField: - hasBadExpr = true - case *ConvertTz: - hasBadExpr = true + case *expression.GetField, *ConvertTz: + evaluable = false + return true } - return hasBadExpr + return false }) - return hasBadExpr + return evaluable } func getNowExpr(expr sql.Expression) *Now { @@ -436,7 +436,7 @@ func evalNowType(now *Now) sql.Type { if now.prec == nil { return types.Int64 } - if noEval(now.prec) { + if !canEval(now.prec) { return types.MustCreateDecimalType(19, 6) } prec, pErr := now.prec.Eval(nil, nil) @@ -463,7 +463,10 @@ func NewUnixTimestamp(args ...sql.Expression) (sql.Expression, error) { } arg := args[0] - if noEval(arg) { + if dtType, isDtType := arg.Type().(sql.DatetimeType); isDtType { + return &UnixTimestamp{Date: arg, typ: types.MustCreateDecimalType(19, uint8(dtType.Precision()))}, nil + } + if !canEval(arg) { return &UnixTimestamp{Date: arg, typ: types.MustCreateDecimalType(19, 6)}, nil } if now := getNowExpr(arg); now != nil { diff --git a/sql/types/datetime.go b/sql/types/datetime.go index 01813d87b8..6d175cd36c 100644 --- a/sql/types/datetime.go +++ b/sql/types/datetime.go @@ -350,6 +350,9 @@ func (t datetimeType) MustConvert(v interface{}) interface{} { // Equals implements the Type interface. func (t datetimeType) Equals(otherType sql.Type) bool { + if dtType, isDtType := otherType.(sql.DatetimeType); isDtType { + return t.baseType == dtType.Type() && t.precision == dtType.Precision() + } return t.baseType == otherType.Type() } From 4d042bf5074b75d65c02e3f864265c5830ea5079 Mon Sep 17 00:00:00 2001 From: jycor Date: Thu, 27 Mar 2025 23:45:46 +0000 Subject: [PATCH 2/5] [ga-format-pr] Run ./format_repo.sh to fix formatting --- sql/expression/convert.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/expression/convert.go b/sql/expression/convert.go index 7e49191075..7bfb084974 100644 --- a/sql/expression/convert.go +++ b/sql/expression/convert.go @@ -17,11 +17,11 @@ package expression import ( "encoding/hex" "fmt" - "github.com/dolthub/vitess/go/sqltypes" -"strconv" + "strconv" "strings" "time" + "github.com/dolthub/vitess/go/sqltypes" "github.com/sirupsen/logrus" "gopkg.in/src-d/go-errors.v1" From d98280400befe9ea9a16f350055be1da68c34271 Mon Sep 17 00:00:00 2001 From: James Cor Date: Thu, 27 Mar 2025 17:05:12 -0700 Subject: [PATCH 3/5] test --- enginetest/queries/script_queries.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/enginetest/queries/script_queries.go b/enginetest/queries/script_queries.go index 14f53663f5..480ee7ac14 100644 --- a/enginetest/queries/script_queries.go +++ b/enginetest/queries/script_queries.go @@ -3068,7 +3068,7 @@ CREATE TABLE tab3 ( { Query: "SELECT unix_timestamp(timestamp_col), unix_timestamp(datetime_col) from datetime_table", Expected: []sql.Row{ - {"86400.000000", "57600.000000"}, + {"86400", "57600"}, }, }, }, @@ -5133,8 +5133,11 @@ CREATE TABLE tab3 ( Name: "UNIX_TIMESTAMP function preserves trailing 0s", SetUpScript: []string{ "SET time_zone = '+07:00';", - "create table t (d0 datetime(0), d1 datetime(1), d2 datetime(2), d3 datetime(3), d4 datetime(4), d5 datetime(5), d6 datetime(6));", - "insert into t values ('2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456')", + "create table dt (dt0 datetime(0), dt1 datetime(1), dt2 datetime(2), dt3 datetime(3), dt4 datetime(4), dt5 datetime(5), dt6 datetime(6));", + "insert into dt values ('2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456', '2020-01-02 12:34:56.123456')", + // TODO: time length not supported, so by default we have max precision + "create table t (d date, tt time);", + "insert into t values ('2020-01-02 12:34:56.123456', '12:34:56.123456');", }, Assertions: []ScriptTestAssertion{ { @@ -5156,11 +5159,17 @@ CREATE TABLE tab3 ( }, }, { - Query: "select unix_timestamp(d0), unix_timestamp(d1), unix_timestamp(d2), unix_timestamp(d3), unix_timestamp(d4), unix_timestamp(d5), unix_timestamp(d6) from t;", + Query: "select unix_timestamp(dt0), unix_timestamp(dt1), unix_timestamp(dt2), unix_timestamp(dt3), unix_timestamp(dt4), unix_timestamp(dt5), unix_timestamp(dt6) from dt;", Expected: []sql.Row{ {"1577943296", "1577943296.1", "1577943296.12", "1577943296.123", "1577943296.1235", "1577943296.12346", "1577943296.123456"}, }, }, + { + Query: "select unix_timestamp(d), unix_timestamp(tt) from t;", + Expected: []sql.Row{ + {"1577898000", "1743053696.123456"}, + }, + }, }, }, From f56cb2445a5b71d302ac8df1062c3fc27191a0a5 Mon Sep 17 00:00:00 2001 From: James Cor Date: Fri, 28 Mar 2025 10:50:49 -0700 Subject: [PATCH 4/5] fix --- enginetest/queries/script_queries.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enginetest/queries/script_queries.go b/enginetest/queries/script_queries.go index 480ee7ac14..afabb2c3d8 100644 --- a/enginetest/queries/script_queries.go +++ b/enginetest/queries/script_queries.go @@ -5167,7 +5167,7 @@ CREATE TABLE tab3 ( { Query: "select unix_timestamp(d), unix_timestamp(tt) from t;", Expected: []sql.Row{ - {"1577898000", "1743053696.123456"}, + {"1577898000", "1743140096.123456"}, }, }, }, From 0069627712c8d482eeb027a37dc8f7cdbd471e8c Mon Sep 17 00:00:00 2001 From: James Cor Date: Fri, 28 Mar 2025 11:28:15 -0700 Subject: [PATCH 5/5] feedback --- sql/expression/function/date.go | 3 +-- sql/types/datetime.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/sql/expression/function/date.go b/sql/expression/function/date.go index be5582290c..56dbf0f8ad 100644 --- a/sql/expression/function/date.go +++ b/sql/expression/function/date.go @@ -405,9 +405,8 @@ var _ sql.CollationCoercible = (*UnixTimestamp)(nil) const MaxUnixTimeMicroSecs = 32536771199999999 -// noEval returns true if the expression contains an expression that cannot be evaluated without sql.Context or sql.Row. +// canEval returns if the expression contains an expression that cannot be evaluated without sql.Context or sql.Row. func canEval(expr sql.Expression) bool { - // Convert Timezone is not evaluable evaluable := true transform.InspectExpr(expr, func(e sql.Expression) bool { switch e.(type) { diff --git a/sql/types/datetime.go b/sql/types/datetime.go index 6d175cd36c..8f7479bc79 100644 --- a/sql/types/datetime.go +++ b/sql/types/datetime.go @@ -353,7 +353,7 @@ func (t datetimeType) Equals(otherType sql.Type) bool { if dtType, isDtType := otherType.(sql.DatetimeType); isDtType { return t.baseType == dtType.Type() && t.precision == dtType.Precision() } - return t.baseType == otherType.Type() + return false } // MaxTextResponseByteLength implements the Type interface