Skip to content
2 changes: 1 addition & 1 deletion enginetest/queries/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ var QueryTests = []QueryTest{
{
// Assert that SYSDATE() returns different times on each call in a query (unlike NOW())
// Using the maximum precision for fractional seconds, lets us see a difference.
Query: "select now() = sysdate(), sleep(0.1), now(6) < sysdate(6);",
Query: "select now() = sysdate(), sleep(0.5), now(6) < sysdate(6);",
Expected: []sql.Row{{true, 0, true}},
},
{
Expand Down
28 changes: 28 additions & 0 deletions enginetest/queries/script_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -5128,6 +5128,34 @@ CREATE TABLE tab3 (
},
},
},
{
Dialect: "mysql",
Name: "UNIX_TIMESTAMP function preserves trailing 0s",
SetUpScript: []string{
"SET time_zone = '+07:00';",
},
Assertions: []ScriptTestAssertion{
{
Query: "select unix_timestamp('2001-02-03 12:34:56.10');",
Expected: []sql.Row{
{"981178496.10"},
},
},
{
Query: "select unix_timestamp('2001-02-03 12:34:56.000000');",
Expected: []sql.Row{
{"981178496.000000"},
},
},
{
Query: "select unix_timestamp('2001-02-03 12:34:56.1234567');",
Expected: []sql.Row{
{"981178496.123457"},
},
},
},
},

{
Name: "Querying existing view that references non-existing table",
SetUpScript: []string{
Expand Down
20 changes: 20 additions & 0 deletions sql/expression/function/date.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,26 @@ func NewUnixTimestamp(args ...sql.Expression) (sql.Expression, error) {
if err != nil || date == nil {
return &UnixTimestamp{Date: arg}, nil
}
// special case: text types with fractional seconds preserve scale
// e.g. '2000-01-02 12:34:56.000' -> scale 3
if types.IsText(arg.Type()) {
dateStr := date.(string)
idx := strings.Index(dateStr, ".")
if idx != -1 {
dateStr = strings.TrimSpace(dateStr[idx:])
scale := uint8(len(dateStr) - 1)
if scale > 0 {
if scale > 6 {
scale = 6
}
typ, tErr := types.CreateDecimalType(19, scale)
if tErr != nil {
return nil, tErr
}
return &UnixTimestamp{Date: arg, typ: typ}, nil
}
}
}
date, _, err = types.DatetimeMaxPrecision.Convert(date)
if err != nil {
return &UnixTimestamp{Date: arg}, nil
Expand Down
3 changes: 2 additions & 1 deletion sql/expression/function/time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package function

import (
"fmt"
"math"
"testing"
"time"

Expand Down Expand Up @@ -377,7 +378,7 @@ func TestTime_Microsecond(t *testing.T) {
{"null date", sql.NewRow(nil), nil, false},
{"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, true},
{"date as string", sql.NewRow(stringDate), uint64(0), false},
{"date as time", sql.NewRow(currTime), uint64(currTime.Nanosecond()) / uint64(time.Microsecond), false},
{"date as time", sql.NewRow(currTime), uint64(math.Round(float64(currTime.Nanosecond()) / float64(time.Microsecond))), false},
}

for _, tt := range testCases {
Expand Down
4 changes: 2 additions & 2 deletions sql/types/datetime.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,10 @@ func ConvertToTime(v interface{}, t datetimeType) (time.Time, error) {
return zeroTime, nil
}

// Truncate the date to the precision of this type
// Round the date to the precision of this type
truncationDuration := time.Second
truncationDuration /= time.Duration(precisionConversion[t.precision])
res = res.Truncate(truncationDuration)
res = res.Round(truncationDuration)

switch t.baseType {
case sqltypes.Date:
Expand Down
14 changes: 7 additions & 7 deletions sql/types/datetime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func TestDatetimeCompare(t *testing.T) {
{DatetimeMaxPrecision, "2010-06-03 06:03:11.123456111", "2010-06-03 06:03:11.123456333", 0},
{MustCreateDatetimeType(sqltypes.Datetime, 3), "2010-06-03 06:03:11.123", "2010-06-03 06:03:11", 1},
{MustCreateDatetimeType(sqltypes.Datetime, 3), "2010-06-03 06:03:11", "2010-06-03 06:03:11.123", -1},
{MustCreateDatetimeType(sqltypes.Datetime, 3), "2010-06-03 06:03:11.123456", "2010-06-03 06:03:11.123789", 0},
{MustCreateDatetimeType(sqltypes.Datetime, 3), "2010-06-03 06:03:11.123456", "2010-06-03 06:03:11.123789", -1},
{Timestamp, time.Date(2012, 12, 12, 12, 12, 12, 12, time.UTC),
time.Date(2012, 12, 12, 12, 24, 24, 24, time.UTC), -1},
{Timestamp, time.Date(2012, 12, 12, 12, 12, 12, 12, time.UTC),
Expand Down Expand Up @@ -219,9 +219,9 @@ func TestDatetimeConvert(t *testing.T) {
time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC), false},
{Datetime, "2010-06-03 12:12:12.123456", time.Date(2010, 6, 3, 12, 12, 12, 0, time.UTC), false},
{Datetime, "2010-06-03T12:12:12.123456Z", time.Date(2010, 6, 3, 12, 12, 12, 0, time.UTC), false},
{Datetime, "2010-06-03 12:34:56.7", time.Date(2010, 6, 3, 12, 34, 56, 0, time.UTC), false},
{Datetime, "2010-06-03 12:34:56.78", time.Date(2010, 6, 3, 12, 34, 56, 0, time.UTC), false},
{Datetime, "2010-06-03 12:34:56.789", time.Date(2010, 6, 3, 12, 34, 56, 0, time.UTC), false},
{Datetime, "2010-06-03 12:34:56.7", time.Date(2010, 6, 3, 12, 34, 57, 0, time.UTC), false},
{Datetime, "2010-06-03 12:34:56.78", time.Date(2010, 6, 3, 12, 34, 57, 0, time.UTC), false},
{Datetime, "2010-06-03 12:34:56.789", time.Date(2010, 6, 3, 12, 34, 57, 0, time.UTC), false},

{TimestampMaxPrecision, nil, nil, false},
{TimestampMaxPrecision, time.Date(2012, 12, 12, 12, 12, 12, 12, time.UTC),
Expand Down Expand Up @@ -258,9 +258,9 @@ func TestDatetimeConvert(t *testing.T) {
time.Date(2012, 12, 12, 12, 12, 12, 0, time.UTC), false},
{Timestamp, "2010-06-03 12:12:12.123456", time.Date(2010, 6, 3, 12, 12, 12, 0, time.UTC), false},
{Timestamp, "2010-06-03T12:12:12.123456Z", time.Date(2010, 6, 3, 12, 12, 12, 0, time.UTC), false},
{Timestamp, "2010-06-03 12:34:56.7", time.Date(2010, 6, 3, 12, 34, 56, 0, time.UTC), false},
{Timestamp, "2010-06-03 12:34:56.78", time.Date(2010, 6, 3, 12, 34, 56, 0, time.UTC), false},
{Timestamp, "2010-06-03 12:34:56.789", time.Date(2010, 6, 3, 12, 34, 56, 0, time.UTC), false},
{Timestamp, "2010-06-03 12:34:56.7", time.Date(2010, 6, 3, 12, 34, 57, 0, time.UTC), false},
{Timestamp, "2010-06-03 12:34:56.78", time.Date(2010, 6, 3, 12, 34, 57, 0, time.UTC), false},
{Timestamp, "2010-06-03 12:34:56.789", time.Date(2010, 6, 3, 12, 34, 57, 0, time.UTC), false},

{Date, "0000-01-01 00:00:00", time.Date(0, 1, 1, 0, 0, 0, 0, time.UTC), false},
{Date, "0500-01-01 00:00:00", time.Date(500, 1, 1, 0, 0, 0, 0, time.UTC), false},
Expand Down
Loading