github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_time_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package memex
    15  
    16  import (
    17  	"math"
    18  	"strings"
    19  	"time"
    20  
    21  	. "github.com/whtcorpsinc/check"
    22  	"github.com/whtcorpsinc/errors"
    23  	"github.com/whtcorpsinc/BerolinaSQL/ast"
    24  	"github.com/whtcorpsinc/BerolinaSQL/charset"
    25  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    26  	"github.com/whtcorpsinc/BerolinaSQL/terror"
    27  	"github.com/whtcorpsinc/milevadb/stochastikctx"
    28  	"github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx"
    29  	"github.com/whtcorpsinc/milevadb/stochastikctx/variable"
    30  	"github.com/whtcorpsinc/milevadb/types"
    31  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    32  	"github.com/whtcorpsinc/milevadb/soliton/mock"
    33  	"github.com/whtcorpsinc/milevadb/soliton/solitonutil"
    34  	"github.com/whtcorpsinc/milevadb/soliton/timeutil"
    35  )
    36  
    37  func init() {
    38  	// Some test depends on the values of timeutil.SystemLocation()
    39  	// If we don't SetSystemTZ() here, the value would change unpredicblock.
    40  	// Affectd by the order whether a testsuite runs before or after integration test.
    41  	// Note, SetSystemTZ() is a sync.Once operation.
    42  	timeutil.SetSystemTZ("system")
    43  }
    44  
    45  func (s *testEvaluatorSuite) TestDate(c *C) {
    46  	tblDate := []struct {
    47  		Input  interface{}
    48  		Expect interface{}
    49  	}{
    50  		{nil, nil},
    51  		// standard format
    52  		{"2011-12-13", "2011-12-13"},
    53  		{"2011-12-13 10:10:10", "2011-12-13"},
    54  		// alternative delimiters, any ASCII punctuation character is a valid delimiter,
    55  		// punctuation character is defined by C++ std::ispunct: any graphical character
    56  		// that is not alphanumeric.
    57  		{"2011\"12\"13", "2011-12-13"},
    58  		{"2011#12#13", "2011-12-13"},
    59  		{"2011$12$13", "2011-12-13"},
    60  		{"2011%12%13", "2011-12-13"},
    61  		{"2011&12&13", "2011-12-13"},
    62  		{"2011'12'13", "2011-12-13"},
    63  		{"2011(12(13", "2011-12-13"},
    64  		{"2011)12)13", "2011-12-13"},
    65  		{"2011*12*13", "2011-12-13"},
    66  		{"2011+12+13", "2011-12-13"},
    67  		{"2011,12,13", "2011-12-13"},
    68  		{"2011.12.13", "2011-12-13"},
    69  		{"2011/12/13", "2011-12-13"},
    70  		{"2011:12:13", "2011-12-13"},
    71  		{"2011;12;13", "2011-12-13"},
    72  		{"2011<12<13", "2011-12-13"},
    73  		{"2011=12=13", "2011-12-13"},
    74  		{"2011>12>13", "2011-12-13"},
    75  		{"2011?12?13", "2011-12-13"},
    76  		{"2011@12@13", "2011-12-13"},
    77  		{"2011[12[13", "2011-12-13"},
    78  		{"2011\\12\\13", "2011-12-13"},
    79  		{"2011]12]13", "2011-12-13"},
    80  		{"2011^12^13", "2011-12-13"},
    81  		{"2011_12_13", "2011-12-13"},
    82  		{"2011`12`13", "2011-12-13"},
    83  		{"2011{12{13", "2011-12-13"},
    84  		{"2011|12|13", "2011-12-13"},
    85  		{"2011}12}13", "2011-12-13"},
    86  		{"2011~12~13", "2011-12-13"},
    87  		// internal format (YYYYMMDD, YYYYYMMDDHHMMSS)
    88  		{"20111213", "2011-12-13"},
    89  		{"111213", "2011-12-13"},
    90  		// leading and trailing space
    91  		{" 2011-12-13", "2011-12-13"},
    92  		{"2011-12-13 ", "2011-12-13"},
    93  		{"   2011-12-13    ", "2011-12-13"},
    94  		// extra dashes
    95  		{"2011-12--13", "2011-12-13"},
    96  		{"2011--12-13", "2011-12-13"},
    97  		{"2011----12----13", "2011-12-13"},
    98  		// combinations
    99  		{"   2011----12----13    ", "2011-12-13"},
   100  		// errors
   101  		{"2011 12 13", nil},
   102  		{"2011A12A13", nil},
   103  		{"2011T12T13", nil},
   104  	}
   105  	dtblDate := tblToDtbl(tblDate)
   106  	for _, t := range dtblDate {
   107  		fc := funcs[ast.Date]
   108  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   109  		c.Assert(err, IsNil)
   110  		v, err := evalBuiltinFunc(f, chunk.Event{})
   111  		c.Assert(err, IsNil)
   112  		c.Assert(v, solitonutil.CausetEquals, t["Expect"][0])
   113  	}
   114  
   115  	// test year, month and day
   116  	tbl := []struct {
   117  		Input      string
   118  		Year       int64
   119  		Month      int64
   120  		MonthName  string
   121  		DayOfMonth int64
   122  		DayOfWeek  int64
   123  		DayOfYear  int64
   124  		WeekDay    int64
   125  		DayName    string
   126  		Week       int64
   127  		WeekOfYear int64
   128  		YearWeek   int64
   129  	}{
   130  		{"2000-01-01", 2000, 1, "January", 1, 7, 1, 5, "Saturday", 0, 52, 199952},
   131  		{"2011-11-11", 2011, 11, "November", 11, 6, 315, 4, "Friday", 45, 45, 201145},
   132  		{"0000-01-01", int64(0), 1, "January", 1, 7, 1, 5, "Saturday", 1, 52, 1},
   133  	}
   134  
   135  	dtbl := tblToDtbl(tbl)
   136  	for ith, t := range dtbl {
   137  		fc := funcs[ast.Year]
   138  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   139  		c.Assert(err, IsNil)
   140  		v, err := evalBuiltinFunc(f, chunk.Event{})
   141  		c.Assert(err, IsNil)
   142  		c.Assert(v, solitonutil.CausetEquals, t["Year"][0])
   143  
   144  		fc = funcs[ast.Month]
   145  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   146  		c.Assert(err, IsNil)
   147  		v, err = evalBuiltinFunc(f, chunk.Event{})
   148  		c.Assert(err, IsNil)
   149  		c.Assert(v, solitonutil.CausetEquals, t["Month"][0])
   150  
   151  		fc = funcs[ast.MonthName]
   152  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   153  		c.Assert(err, IsNil)
   154  		v, err = evalBuiltinFunc(f, chunk.Event{})
   155  		c.Assert(err, IsNil)
   156  		c.Assert(v, solitonutil.CausetEquals, t["MonthName"][0])
   157  
   158  		fc = funcs[ast.DayOfMonth]
   159  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   160  		c.Assert(err, IsNil)
   161  		v, err = evalBuiltinFunc(f, chunk.Event{})
   162  		c.Assert(err, IsNil)
   163  		c.Assert(v, solitonutil.CausetEquals, t["DayOfMonth"][0])
   164  
   165  		fc = funcs[ast.DayOfWeek]
   166  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   167  		c.Assert(err, IsNil)
   168  		v, err = evalBuiltinFunc(f, chunk.Event{})
   169  		c.Assert(err, IsNil)
   170  		c.Assert(v, solitonutil.CausetEquals, t["DayOfWeek"][0])
   171  
   172  		fc = funcs[ast.DayOfYear]
   173  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   174  		c.Assert(err, IsNil)
   175  		v, err = evalBuiltinFunc(f, chunk.Event{})
   176  		c.Assert(err, IsNil)
   177  		c.Assert(v, solitonutil.CausetEquals, t["DayOfYear"][0])
   178  
   179  		fc = funcs[ast.Weekday]
   180  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   181  		c.Assert(err, IsNil)
   182  		c.Assert(f, NotNil)
   183  		v, err = evalBuiltinFunc(f, chunk.Event{})
   184  		c.Assert(err, IsNil)
   185  		c.Assert(v, solitonutil.CausetEquals, t["WeekDay"][0])
   186  
   187  		fc = funcs[ast.DayName]
   188  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   189  		c.Assert(err, IsNil)
   190  		v, err = evalBuiltinFunc(f, chunk.Event{})
   191  		c.Assert(err, IsNil)
   192  		c.Assert(v, solitonutil.CausetEquals, t["DayName"][0])
   193  
   194  		fc = funcs[ast.Week]
   195  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   196  		c.Assert(err, IsNil)
   197  		v, err = evalBuiltinFunc(f, chunk.Event{})
   198  		c.Assert(err, IsNil)
   199  		c.Assert(v, solitonutil.CausetEquals, t["Week"][0], Commentf("no.%d", ith))
   200  
   201  		fc = funcs[ast.WeekOfYear]
   202  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   203  		c.Assert(err, IsNil)
   204  		v, err = evalBuiltinFunc(f, chunk.Event{})
   205  		c.Assert(err, IsNil)
   206  		c.Assert(v, solitonutil.CausetEquals, t["WeekOfYear"][0])
   207  
   208  		fc = funcs[ast.YearWeek]
   209  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   210  		c.Assert(err, IsNil)
   211  		v, err = evalBuiltinFunc(f, chunk.Event{})
   212  		c.Assert(err, IsNil)
   213  		c.Assert(v, solitonutil.CausetEquals, t["YearWeek"][0], Commentf("no.%d", ith))
   214  	}
   215  
   216  	// test nil
   217  	tblNil := []struct {
   218  		Input      interface{}
   219  		Year       interface{}
   220  		Month      interface{}
   221  		MonthName  interface{}
   222  		DayOfMonth interface{}
   223  		DayOfWeek  interface{}
   224  		DayOfYear  interface{}
   225  		WeekDay    interface{}
   226  		DayName    interface{}
   227  		Week       interface{}
   228  		WeekOfYear interface{}
   229  		YearWeek   interface{}
   230  	}{
   231  		{nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil},
   232  		{"0000-00-00 00:00:00", 0, 0, nil, 0, nil, nil, nil, nil, nil, nil, nil},
   233  		{"0000-00-00", 0, 0, nil, 0, nil, nil, nil, nil, nil, nil, nil},
   234  	}
   235  
   236  	dtblNil := tblToDtbl(tblNil)
   237  	for _, t := range dtblNil {
   238  		fc := funcs[ast.Year]
   239  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   240  		c.Assert(err, IsNil)
   241  		v, err := evalBuiltinFunc(f, chunk.Event{})
   242  		c.Assert(err, IsNil)
   243  		c.Assert(v, solitonutil.CausetEquals, t["Year"][0])
   244  
   245  		fc = funcs[ast.Month]
   246  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   247  		c.Assert(err, IsNil)
   248  		v, err = evalBuiltinFunc(f, chunk.Event{})
   249  		c.Assert(err, IsNil)
   250  		c.Assert(v, solitonutil.CausetEquals, t["Month"][0])
   251  
   252  		fc = funcs[ast.MonthName]
   253  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   254  		c.Assert(err, IsNil)
   255  		v, err = evalBuiltinFunc(f, chunk.Event{})
   256  		c.Assert(err, IsNil)
   257  		c.Assert(v, solitonutil.CausetEquals, t["MonthName"][0])
   258  
   259  		fc = funcs[ast.DayOfMonth]
   260  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   261  		c.Assert(err, IsNil)
   262  		v, err = evalBuiltinFunc(f, chunk.Event{})
   263  		c.Assert(err, IsNil)
   264  		c.Assert(v, solitonutil.CausetEquals, t["DayOfMonth"][0])
   265  
   266  		fc = funcs[ast.DayOfWeek]
   267  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   268  		c.Assert(err, IsNil)
   269  		v, err = evalBuiltinFunc(f, chunk.Event{})
   270  		c.Assert(err, IsNil)
   271  		c.Assert(v, solitonutil.CausetEquals, t["DayOfWeek"][0])
   272  
   273  		fc = funcs[ast.DayOfYear]
   274  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   275  		c.Assert(err, IsNil)
   276  		v, err = evalBuiltinFunc(f, chunk.Event{})
   277  		c.Assert(err, IsNil)
   278  		c.Assert(v, solitonutil.CausetEquals, t["DayOfYear"][0])
   279  
   280  		fc = funcs[ast.Weekday]
   281  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   282  		c.Assert(err, IsNil)
   283  		c.Assert(f, NotNil)
   284  		v, err = evalBuiltinFunc(f, chunk.Event{})
   285  		c.Assert(err, IsNil)
   286  		c.Assert(v, solitonutil.CausetEquals, t["WeekDay"][0])
   287  
   288  		fc = funcs[ast.DayName]
   289  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   290  		c.Assert(err, IsNil)
   291  		v, err = evalBuiltinFunc(f, chunk.Event{})
   292  		c.Assert(err, IsNil)
   293  		c.Assert(v, solitonutil.CausetEquals, t["DayName"][0])
   294  
   295  		fc = funcs[ast.Week]
   296  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   297  		c.Assert(err, IsNil)
   298  		v, err = evalBuiltinFunc(f, chunk.Event{})
   299  		c.Assert(err, IsNil)
   300  		c.Assert(v, solitonutil.CausetEquals, t["Week"][0])
   301  
   302  		fc = funcs[ast.WeekOfYear]
   303  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   304  		c.Assert(err, IsNil)
   305  		v, err = evalBuiltinFunc(f, chunk.Event{})
   306  		c.Assert(err, IsNil)
   307  		c.Assert(v, solitonutil.CausetEquals, t["WeekOfYear"][0])
   308  
   309  		fc = funcs[ast.YearWeek]
   310  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   311  		c.Assert(err, IsNil)
   312  		v, err = evalBuiltinFunc(f, chunk.Event{})
   313  		c.Assert(err, IsNil)
   314  		c.Assert(v, solitonutil.CausetEquals, t["YearWeek"][0])
   315  	}
   316  
   317  	// test nil with 'NO_ZERO_DATE' set in sql_mode
   318  	tblNil = []struct {
   319  		Input      interface{}
   320  		Year       interface{}
   321  		Month      interface{}
   322  		MonthName  interface{}
   323  		DayOfMonth interface{}
   324  		DayOfWeek  interface{}
   325  		DayOfYear  interface{}
   326  		WeekDay    interface{}
   327  		DayName    interface{}
   328  		Week       interface{}
   329  		WeekOfYear interface{}
   330  		YearWeek   interface{}
   331  	}{
   332  		{nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil},
   333  		{"0000-00-00 00:00:00", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil},
   334  		{"0000-00-00", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil},
   335  	}
   336  
   337  	dtblNil = tblToDtbl(tblNil)
   338  	s.ctx.GetStochastikVars().SetSystemVar("sql_mode", "NO_ZERO_DATE")
   339  	for _, t := range dtblNil {
   340  		fc := funcs[ast.Year]
   341  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   342  		c.Assert(err, IsNil)
   343  		v, err := evalBuiltinFunc(f, chunk.Event{})
   344  		c.Assert(err, IsNil)
   345  		c.Assert(v, solitonutil.CausetEquals, t["Year"][0])
   346  
   347  		fc = funcs[ast.Month]
   348  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   349  		c.Assert(err, IsNil)
   350  		v, err = evalBuiltinFunc(f, chunk.Event{})
   351  		c.Assert(err, IsNil)
   352  		c.Assert(v, solitonutil.CausetEquals, t["Month"][0])
   353  
   354  		fc = funcs[ast.MonthName]
   355  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   356  		c.Assert(err, IsNil)
   357  		v, err = evalBuiltinFunc(f, chunk.Event{})
   358  		c.Assert(err, IsNil)
   359  		c.Assert(v, solitonutil.CausetEquals, t["MonthName"][0])
   360  
   361  		fc = funcs[ast.DayOfMonth]
   362  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   363  		c.Assert(err, IsNil)
   364  		v, err = evalBuiltinFunc(f, chunk.Event{})
   365  		c.Assert(err, IsNil)
   366  		c.Assert(v, solitonutil.CausetEquals, t["DayOfMonth"][0])
   367  
   368  		fc = funcs[ast.DayOfWeek]
   369  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   370  		c.Assert(err, IsNil)
   371  		v, err = evalBuiltinFunc(f, chunk.Event{})
   372  		c.Assert(err, IsNil)
   373  		c.Assert(v, solitonutil.CausetEquals, t["DayOfWeek"][0])
   374  
   375  		fc = funcs[ast.DayOfYear]
   376  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   377  		c.Assert(err, IsNil)
   378  		v, err = evalBuiltinFunc(f, chunk.Event{})
   379  		c.Assert(err, IsNil)
   380  		c.Assert(v, solitonutil.CausetEquals, t["DayOfYear"][0])
   381  
   382  		fc = funcs[ast.Weekday]
   383  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   384  		c.Assert(err, IsNil)
   385  		c.Assert(f, NotNil)
   386  		v, err = evalBuiltinFunc(f, chunk.Event{})
   387  		c.Assert(err, IsNil)
   388  		c.Assert(v, solitonutil.CausetEquals, t["WeekDay"][0])
   389  
   390  		fc = funcs[ast.DayName]
   391  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   392  		c.Assert(err, IsNil)
   393  		v, err = evalBuiltinFunc(f, chunk.Event{})
   394  		c.Assert(err, IsNil)
   395  		c.Assert(v, solitonutil.CausetEquals, t["DayName"][0])
   396  
   397  		fc = funcs[ast.Week]
   398  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   399  		c.Assert(err, IsNil)
   400  		v, err = evalBuiltinFunc(f, chunk.Event{})
   401  		c.Assert(err, IsNil)
   402  		c.Assert(v, solitonutil.CausetEquals, t["Week"][0])
   403  
   404  		fc = funcs[ast.WeekOfYear]
   405  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   406  		c.Assert(err, IsNil)
   407  		v, err = evalBuiltinFunc(f, chunk.Event{})
   408  		c.Assert(err, IsNil)
   409  		c.Assert(v, solitonutil.CausetEquals, t["WeekOfYear"][0])
   410  
   411  		fc = funcs[ast.YearWeek]
   412  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   413  		c.Assert(err, IsNil)
   414  		v, err = evalBuiltinFunc(f, chunk.Event{})
   415  		c.Assert(err, IsNil)
   416  		c.Assert(v, solitonutil.CausetEquals, t["YearWeek"][0])
   417  	}
   418  }
   419  
   420  func (s *testEvaluatorSuite) TestMonthName(c *C) {
   421  	sc := s.ctx.GetStochastikVars().StmtCtx
   422  	sc.IgnoreZeroInDate = true
   423  	cases := []struct {
   424  		args     interface{}
   425  		expected string
   426  		isNil    bool
   427  		getErr   bool
   428  	}{
   429  		{"2020-12-01", "December", false, false},
   430  		{"2020-00-01", "", true, false},
   431  		{"0000-00-00", "", true, false},
   432  		{"0000-00-00 00:00:00.000000", "", true, false},
   433  		{"0000-00-00 00:00:11.000000", "", true, false},
   434  	}
   435  	for _, t := range cases {
   436  		f, err := newFunctionForTest(s.ctx, ast.MonthName, s.primitiveValsToConstants([]interface{}{t.args})...)
   437  		c.Assert(err, IsNil)
   438  		d, err := f.Eval(chunk.Event{})
   439  		if t.getErr {
   440  			c.Assert(err, NotNil)
   441  		} else {
   442  			c.Assert(err, IsNil)
   443  			if t.isNil {
   444  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   445  			} else {
   446  				c.Assert(d.GetString(), Equals, t.expected)
   447  			}
   448  		}
   449  	}
   450  
   451  	_, err := funcs[ast.MonthName].getFunction(s.ctx, []Expression{NewZero()})
   452  	c.Assert(err, IsNil)
   453  }
   454  
   455  func (s *testEvaluatorSuite) TestDayName(c *C) {
   456  	sc := s.ctx.GetStochastikVars().StmtCtx
   457  	sc.IgnoreZeroInDate = true
   458  	cases := []struct {
   459  		args     interface{}
   460  		expected string
   461  		isNil    bool
   462  		getErr   bool
   463  	}{
   464  		{"2020-12-01", "Friday", false, false},
   465  		{"0000-12-01", "Friday", false, false},
   466  		{"2020-00-01", "", true, false},
   467  		{"2020-01-00", "", true, false},
   468  		{"0000-00-00", "", true, false},
   469  		{"0000-00-00 00:00:00.000000", "", true, false},
   470  		{"0000-00-00 00:00:11.000000", "", true, false},
   471  	}
   472  	for _, t := range cases {
   473  		f, err := newFunctionForTest(s.ctx, ast.DayName, s.primitiveValsToConstants([]interface{}{t.args})...)
   474  		c.Assert(err, IsNil)
   475  		d, err := f.Eval(chunk.Event{})
   476  		if t.getErr {
   477  			c.Assert(err, NotNil)
   478  		} else {
   479  			c.Assert(err, IsNil)
   480  			if t.isNil {
   481  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   482  			} else {
   483  				c.Assert(d.GetString(), Equals, t.expected)
   484  			}
   485  		}
   486  	}
   487  
   488  	_, err := funcs[ast.DayName].getFunction(s.ctx, []Expression{NewZero()})
   489  	c.Assert(err, IsNil)
   490  }
   491  
   492  func (s *testEvaluatorSuite) TestDayOfWeek(c *C) {
   493  	sc := s.ctx.GetStochastikVars().StmtCtx
   494  	sc.IgnoreZeroInDate = true
   495  	cases := []struct {
   496  		args     interface{}
   497  		expected int64
   498  		isNil    bool
   499  		getErr   bool
   500  	}{
   501  		{"2020-12-01", 6, false, false},
   502  		{"0000-00-00", 1, true, false},
   503  		{"2020-00-00", 1, true, false},
   504  		{"2020-00-00 12:12:12", 1, true, false},
   505  		{"0000-00-00 12:12:12", 1, true, false},
   506  	}
   507  	for _, t := range cases {
   508  		f, err := newFunctionForTest(s.ctx, ast.DayOfWeek, s.primitiveValsToConstants([]interface{}{t.args})...)
   509  		c.Assert(err, IsNil)
   510  		d, err := f.Eval(chunk.Event{})
   511  		if t.getErr {
   512  			c.Assert(err, NotNil)
   513  		} else {
   514  			c.Assert(err, IsNil)
   515  			if t.isNil {
   516  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   517  			} else {
   518  				c.Assert(d.GetInt64(), Equals, t.expected)
   519  			}
   520  		}
   521  	}
   522  
   523  	_, err := funcs[ast.DayOfWeek].getFunction(s.ctx, []Expression{NewZero()})
   524  	c.Assert(err, IsNil)
   525  }
   526  
   527  func (s *testEvaluatorSuite) TestDayOfMonth(c *C) {
   528  	sc := s.ctx.GetStochastikVars().StmtCtx
   529  	sc.IgnoreZeroInDate = true
   530  	cases := []struct {
   531  		args     interface{}
   532  		expected int64
   533  		isNil    bool
   534  		getErr   bool
   535  	}{
   536  		{"2020-12-01", 1, false, false},
   537  		{"0000-00-00", 0, false, false},
   538  		{"2020-00-00", 0, false, false},
   539  		{"2020-00-00 12:12:12", 0, false, false},
   540  		{"0000-00-00 12:12:12", 0, false, false},
   541  	}
   542  	for _, t := range cases {
   543  		f, err := newFunctionForTest(s.ctx, ast.DayOfMonth, s.primitiveValsToConstants([]interface{}{t.args})...)
   544  		c.Assert(err, IsNil)
   545  		d, err := f.Eval(chunk.Event{})
   546  		if t.getErr {
   547  			c.Assert(err, NotNil)
   548  		} else {
   549  			c.Assert(err, IsNil)
   550  			if t.isNil {
   551  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   552  			} else {
   553  				c.Assert(d.GetInt64(), Equals, t.expected)
   554  			}
   555  		}
   556  	}
   557  
   558  	_, err := funcs[ast.DayOfMonth].getFunction(s.ctx, []Expression{NewZero()})
   559  	c.Assert(err, IsNil)
   560  }
   561  
   562  func (s *testEvaluatorSuite) TestDayOfYear(c *C) {
   563  	sc := s.ctx.GetStochastikVars().StmtCtx
   564  	sc.IgnoreZeroInDate = true
   565  	cases := []struct {
   566  		args     interface{}
   567  		expected int64
   568  		isNil    bool
   569  		getErr   bool
   570  	}{
   571  		{"2020-12-01", 335, false, false},
   572  		{"0000-00-00", 1, true, false},
   573  		{"2020-00-00", 0, true, false},
   574  		{"2020-00-00 12:12:12", 0, true, false},
   575  		{"0000-00-00 12:12:12", 0, true, false},
   576  	}
   577  	for _, t := range cases {
   578  		f, err := newFunctionForTest(s.ctx, ast.DayOfYear, s.primitiveValsToConstants([]interface{}{t.args})...)
   579  		c.Assert(err, IsNil)
   580  		d, err := f.Eval(chunk.Event{})
   581  		if t.getErr {
   582  			c.Assert(err, NotNil)
   583  		} else {
   584  			c.Assert(err, IsNil)
   585  			if t.isNil {
   586  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   587  			} else {
   588  				c.Assert(d.GetInt64(), Equals, t.expected)
   589  			}
   590  		}
   591  	}
   592  
   593  	_, err := funcs[ast.DayOfYear].getFunction(s.ctx, []Expression{NewZero()})
   594  	c.Assert(err, IsNil)
   595  }
   596  
   597  func (s *testEvaluatorSuite) TestDateFormat(c *C) {
   598  	// Test case for https://github.com/whtcorpsinc/milevadb/issues/2908
   599  	// SELECT DATE_FORMAT(null,'%Y-%M-%D')
   600  	args := []types.Causet{types.NewCauset(nil), types.NewStringCauset("%Y-%M-%D")}
   601  	fc := funcs[ast.DateFormat]
   602  	f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
   603  	c.Assert(err, IsNil)
   604  	v, err := evalBuiltinFunc(f, chunk.Event{})
   605  	c.Assert(err, IsNil)
   606  	c.Assert(v.IsNull(), Equals, true)
   607  
   608  	tblDate := []struct {
   609  		Input  []string
   610  		Expect interface{}
   611  	}{
   612  		{[]string{"2010-01-07 23:12:34.12345",
   613  			`%b %M %m %c %D %d %e %j %k %h %i %p %r %T %s %f %U %u %V %v %a %W %w %X %x %Y %y %%`},
   614  			`Jan January 01 1 7th 07 7 007 23 11 12 PM 11:12:34 PM 23:12:34 34 123450 01 01 01 01 Thu Thursday 4 2010 2010 2010 10 %`},
   615  		{[]string{"2012-12-21 23:12:34.123456",
   616  			`%b %M %m %c %D %d %e %j %k %h %i %p %r %T %s %f %U %u %V %v %a %W %w %X %x %Y %y %%`},
   617  			"Dec December 12 12 21st 21 21 356 23 11 12 PM 11:12:34 PM 23:12:34 34 123456 51 51 51 51 Fri Friday 5 2012 2012 2012 12 %"},
   618  		{[]string{"0000-01-01 00:00:00.123456",
   619  			// Functions week() and yearweek() don't support multi mode,
   620  			// so the result of "%U %u %V %Y" is different from MyALLEGROSQL.
   621  			`%b %M %m %c %D %d %e %j %k %h %i %p %r %T %s %f %v %x %Y %y %%`},
   622  			`Jan January 01 1 1st 01 1 001 0 12 00 AM 12:00:00 AM 00:00:00 00 123456 52 4294967295 0000 00 %`},
   623  		{[]string{"2020-09-3 00:59:59.123456",
   624  			`abc%b %M %m %c %D %d %e %j %k %h %i %p %r %T %s %f %U %u %V %v %a %W %w %X %x %Y %y!123 %%xyz %z`},
   625  			`abcSep September 09 9 3rd 03 3 247 0 12 59 AM 12:59:59 AM 00:59:59 59 123456 35 35 35 35 Sat Saturday 6 2020 2020 2020 16!123 %xyz z`},
   626  		{[]string{"2012-10-01 00:00:00",
   627  			`%b %M %m %c %D %d %e %j %k %H %i %p %r %T %s %f %v %x %Y %y %%`},
   628  			`Oct October 10 10 1st 01 1 275 0 00 00 AM 12:00:00 AM 00:00:00 00 000000 40 2012 2012 12 %`},
   629  	}
   630  	dtblDate := tblToDtbl(tblDate)
   631  	for i, t := range dtblDate {
   632  		fc := funcs[ast.DateFormat]
   633  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   634  		c.Assert(err, IsNil)
   635  		v, err := evalBuiltinFunc(f, chunk.Event{})
   636  		c.Assert(err, IsNil)
   637  		c.Assert(v, solitonutil.CausetEquals, t["Expect"][0], Commentf(`no.%d \nobtain:%v \nexpect:%v\n`, i,
   638  			v.GetValue(), t["Expect"][0].GetValue()))
   639  	}
   640  }
   641  
   642  func (s *testEvaluatorSuite) TestClock(c *C) {
   643  	// test hour, minute, second, micro second
   644  
   645  	tbl := []struct {
   646  		Input       string
   647  		Hour        int64
   648  		Minute      int64
   649  		Second      int64
   650  		MicroSecond int64
   651  		Time        string
   652  	}{
   653  		{"10:10:10.123456", 10, 10, 10, 123456, "10:10:10.123456"},
   654  		{"11:11:11.11", 11, 11, 11, 110000, "11:11:11.11"},
   655  		{"2010-10-10 11:11:11.11", 11, 11, 11, 110000, "11:11:11.11"},
   656  	}
   657  
   658  	dtbl := tblToDtbl(tbl)
   659  	for _, t := range dtbl {
   660  		fc := funcs[ast.Hour]
   661  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   662  		c.Assert(err, IsNil)
   663  		v, err := evalBuiltinFunc(f, chunk.Event{})
   664  		c.Assert(err, IsNil)
   665  		c.Assert(v, solitonutil.CausetEquals, t["Hour"][0])
   666  
   667  		fc = funcs[ast.Minute]
   668  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   669  		c.Assert(err, IsNil)
   670  		v, err = evalBuiltinFunc(f, chunk.Event{})
   671  		c.Assert(err, IsNil)
   672  		c.Assert(v, solitonutil.CausetEquals, t["Minute"][0])
   673  
   674  		fc = funcs[ast.Second]
   675  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   676  		c.Assert(err, IsNil)
   677  		v, err = evalBuiltinFunc(f, chunk.Event{})
   678  		c.Assert(err, IsNil)
   679  		c.Assert(v, solitonutil.CausetEquals, t["Second"][0])
   680  
   681  		fc = funcs[ast.MicroSecond]
   682  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   683  		c.Assert(err, IsNil)
   684  		v, err = evalBuiltinFunc(f, chunk.Event{})
   685  		c.Assert(err, IsNil)
   686  		c.Assert(v, solitonutil.CausetEquals, t["MicroSecond"][0])
   687  
   688  		fc = funcs[ast.Time]
   689  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   690  		c.Assert(err, IsNil)
   691  		v, err = evalBuiltinFunc(f, chunk.Event{})
   692  		c.Assert(err, IsNil)
   693  		c.Assert(v, solitonutil.CausetEquals, t["Time"][0])
   694  	}
   695  
   696  	// nil
   697  	fc := funcs[ast.Hour]
   698  	f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(nil)))
   699  	c.Assert(err, IsNil)
   700  	v, err := evalBuiltinFunc(f, chunk.Event{})
   701  	c.Assert(err, IsNil)
   702  	c.Assert(v.HoTT(), Equals, types.HoTTNull)
   703  
   704  	fc = funcs[ast.Minute]
   705  	f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(nil)))
   706  	c.Assert(err, IsNil)
   707  	v, err = evalBuiltinFunc(f, chunk.Event{})
   708  	c.Assert(err, IsNil)
   709  	c.Assert(v.HoTT(), Equals, types.HoTTNull)
   710  
   711  	fc = funcs[ast.Second]
   712  	f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(nil)))
   713  	c.Assert(err, IsNil)
   714  	v, err = evalBuiltinFunc(f, chunk.Event{})
   715  	c.Assert(err, IsNil)
   716  	c.Assert(v.HoTT(), Equals, types.HoTTNull)
   717  
   718  	fc = funcs[ast.MicroSecond]
   719  	f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(nil)))
   720  	c.Assert(err, IsNil)
   721  	v, err = evalBuiltinFunc(f, chunk.Event{})
   722  	c.Assert(err, IsNil)
   723  	c.Assert(v.HoTT(), Equals, types.HoTTNull)
   724  
   725  	fc = funcs[ast.Time]
   726  	f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(nil)))
   727  	c.Assert(err, IsNil)
   728  	v, err = evalBuiltinFunc(f, chunk.Event{})
   729  	c.Assert(err, IsNil)
   730  	c.Assert(v.HoTT(), Equals, types.HoTTNull)
   731  
   732  	// test error
   733  	errTbl := []string{
   734  		"2011-11-11 10:10:10.11.12",
   735  	}
   736  
   737  	for _, t := range errTbl {
   738  		td := types.MakeCausets(t)
   739  		fc := funcs[ast.Hour]
   740  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(td))
   741  		c.Assert(err, IsNil)
   742  		_, err = evalBuiltinFunc(f, chunk.Event{})
   743  		c.Assert(err, IsNil)
   744  
   745  		fc = funcs[ast.Minute]
   746  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(td))
   747  		c.Assert(err, IsNil)
   748  		_, err = evalBuiltinFunc(f, chunk.Event{})
   749  		c.Assert(err, IsNil)
   750  
   751  		fc = funcs[ast.Second]
   752  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(td))
   753  		c.Assert(err, IsNil)
   754  		_, err = evalBuiltinFunc(f, chunk.Event{})
   755  		c.Assert(err, IsNil)
   756  
   757  		fc = funcs[ast.MicroSecond]
   758  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(td))
   759  		c.Assert(err, IsNil)
   760  		_, err = evalBuiltinFunc(f, chunk.Event{})
   761  		c.Assert(err, IsNil)
   762  
   763  		fc = funcs[ast.Time]
   764  		preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount()
   765  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(td))
   766  		c.Assert(err, IsNil)
   767  		_, err = evalBuiltinFunc(f, chunk.Event{})
   768  		c.Assert(err, IsNil)
   769  		c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1)
   770  	}
   771  }
   772  
   773  func (s *testEvaluatorSuite) TestTime(c *C) {
   774  	cases := []struct {
   775  		args     interface{}
   776  		expected string
   777  		isNil    bool
   778  		getErr   bool
   779  	}{
   780  		{"2003-12-31 01:02:03", "01:02:03", false, false},
   781  		{"2003-12-31 01:02:03.000123", "01:02:03.000123", false, false},
   782  		{"01:02:03.000123", "01:02:03.000123", false, false},
   783  		{"01:02:03", "01:02:03", false, false},
   784  		{"-838:59:59.000000", "-838:59:59.000000", false, false},
   785  	}
   786  
   787  	for _, t := range cases {
   788  		f, err := newFunctionForTest(s.ctx, ast.Time, s.primitiveValsToConstants([]interface{}{t.args})...)
   789  		c.Assert(err, IsNil)
   790  		tp := f.GetType()
   791  		c.Assert(tp.Tp, Equals, allegrosql.TypeDuration)
   792  		c.Assert(tp.Charset, Equals, charset.CharsetBin)
   793  		c.Assert(tp.DefCauslate, Equals, charset.DefCauslationBin)
   794  		c.Assert(tp.Flag&allegrosql.BinaryFlag, Equals, allegrosql.BinaryFlag)
   795  		c.Assert(tp.Flen, Equals, allegrosql.MaxDurationWidthWithFsp)
   796  		d, err := f.Eval(chunk.Event{})
   797  		if t.getErr {
   798  			c.Assert(err, NotNil)
   799  		} else {
   800  			c.Assert(err, IsNil)
   801  			if t.isNil {
   802  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   803  			} else {
   804  				c.Assert(d.GetMysqlDuration().String(), Equals, t.expected)
   805  			}
   806  		}
   807  	}
   808  
   809  	_, err := funcs[ast.Time].getFunction(s.ctx, []Expression{NewZero()})
   810  	c.Assert(err, IsNil)
   811  }
   812  
   813  func resetStmtContext(ctx stochastikctx.Context) {
   814  	ctx.GetStochastikVars().StmtCtx.ResetNowTs()
   815  }
   816  
   817  func (s *testEvaluatorSuite) TestNowAndUTCTimestamp(c *C) {
   818  	gotime := func(t types.Time, l *time.Location) time.Time {
   819  		tt, err := t.GoTime(l)
   820  		c.Assert(err, IsNil)
   821  		return tt
   822  	}
   823  
   824  	for _, x := range []struct {
   825  		fc  functionClass
   826  		now func() time.Time
   827  	}{
   828  		{funcs[ast.Now], func() time.Time { return time.Now() }},
   829  		{funcs[ast.UTCTimestamp], func() time.Time { return time.Now().UTC() }},
   830  	} {
   831  		f, err := x.fc.getFunction(s.ctx, s.datumsToConstants(nil))
   832  		c.Assert(err, IsNil)
   833  		resetStmtContext(s.ctx)
   834  		v, err := evalBuiltinFunc(f, chunk.Event{})
   835  		ts := x.now()
   836  		c.Assert(err, IsNil)
   837  		t := v.GetMysqlTime()
   838  		// we canot use a constant value to check timestamp funcs, so here
   839  		// just to check the fractional seconds part and the time delta.
   840  		c.Assert(strings.Contains(t.String(), "."), IsFalse)
   841  		c.Assert(ts.Sub(gotime(t, ts.Location())), LessEqual, time.Second)
   842  
   843  		f, err = x.fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(6)))
   844  		c.Assert(err, IsNil)
   845  		resetStmtContext(s.ctx)
   846  		v, err = evalBuiltinFunc(f, chunk.Event{})
   847  		ts = x.now()
   848  		c.Assert(err, IsNil)
   849  		t = v.GetMysqlTime()
   850  		c.Assert(strings.Contains(t.String(), "."), IsTrue)
   851  		c.Assert(ts.Sub(gotime(t, ts.Location())), LessEqual, time.Second)
   852  
   853  		resetStmtContext(s.ctx)
   854  		f, err = x.fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(8)))
   855  		c.Assert(err, IsNil)
   856  		_, err = evalBuiltinFunc(f, chunk.Event{})
   857  		c.Assert(err, NotNil)
   858  
   859  		resetStmtContext(s.ctx)
   860  		f, err = x.fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(-2)))
   861  		c.Assert(err, IsNil)
   862  		_, err = evalBuiltinFunc(f, chunk.Event{})
   863  		c.Assert(err, NotNil)
   864  	}
   865  
   866  	// Test that "timestamp" and "time_zone" variable may affect the result of Now() builtin function.
   867  	variable.SetStochastikSystemVar(s.ctx.GetStochastikVars(), "time_zone", types.NewCauset("+00:00"))
   868  	variable.SetStochastikSystemVar(s.ctx.GetStochastikVars(), "timestamp", types.NewCauset(1234))
   869  	fc := funcs[ast.Now]
   870  	resetStmtContext(s.ctx)
   871  	f, err := fc.getFunction(s.ctx, s.datumsToConstants(nil))
   872  	c.Assert(err, IsNil)
   873  	v, err := evalBuiltinFunc(f, chunk.Event{})
   874  	c.Assert(err, IsNil)
   875  	result, err := v.ToString()
   876  	c.Assert(err, IsNil)
   877  	c.Assert(result, Equals, "1970-01-01 00:20:34")
   878  	variable.SetStochastikSystemVar(s.ctx.GetStochastikVars(), "timestamp", types.NewCauset(0))
   879  	variable.SetStochastikSystemVar(s.ctx.GetStochastikVars(), "time_zone", types.NewCauset("system"))
   880  }
   881  
   882  func (s *testEvaluatorSuite) TestIsDuration(c *C) {
   883  	tbl := []struct {
   884  		Input  string
   885  		expect bool
   886  	}{
   887  		{"110:00:00", true},
   888  		{"aa:bb:cc", false},
   889  		{"1 01:00:00", true},
   890  		{"01:00:00.999999", true},
   891  		{"071231235959.999999", false},
   892  		{"20171231235959.999999", false},
   893  		{"2020-01-01 01:01:01.11", false},
   894  		{"07-12-31 23:59:59.999999", false},
   895  		{"2007-12-31 23:59:59.999999", false},
   896  	}
   897  	for _, t := range tbl {
   898  		result := isDuration(t.Input)
   899  		c.Assert(result, Equals, t.expect)
   900  	}
   901  }
   902  
   903  func (s *testEvaluatorSuite) TestAddTimeSig(c *C) {
   904  	tbl := []struct {
   905  		Input         string
   906  		InputDuration string
   907  		expect        string
   908  	}{
   909  		{"01:00:00.999999", "02:00:00.999998", "03:00:01.999997"},
   910  		{"110:00:00", "1 02:00:00", "136:00:00"},
   911  		{"2020-01-01 01:01:01.11", "01:01:01.11111", "2020-01-01 02:02:02.221110"},
   912  		{"2007-12-31 23:59:59.999999", "1 1:1:1.000002", "2008-01-02 01:01:01.000001"},
   913  		{"2020-12-01 01:01:01.000001", "1 1:1:1.000002", "2020-12-02 02:02:02.000003"},
   914  		{"2020-12-31 23:59:59", "00:00:01", "2020-01-01 00:00:00"},
   915  		{"2020-12-31 23:59:59", "1", "2020-01-01 00:00:00"},
   916  		{"2007-12-31 23:59:59.999999", "2 1:1:1.000002", "2008-01-03 01:01:01.000001"},
   917  		{"2020-08-16 20:21:01", "00:00:00.000001", "2020-08-16 20:21:01.000001"},
   918  	}
   919  	fc := funcs[ast.AddTime]
   920  	for _, t := range tbl {
   921  		tmpInput := types.NewStringCauset(t.Input)
   922  		tmpInputDuration := types.NewStringCauset(t.InputDuration)
   923  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{tmpInput, tmpInputDuration}))
   924  		c.Assert(err, IsNil)
   925  		d, err := evalBuiltinFunc(f, chunk.Event{})
   926  		c.Assert(err, IsNil)
   927  		result, _ := d.ToString()
   928  		c.Assert(result, Equals, t.expect)
   929  	}
   930  
   931  	// This is a test for issue 7334
   932  	du := newDateArighmeticalUtil()
   933  	resetStmtContext(s.ctx)
   934  	now, _, err := evalNowWithFsp(s.ctx, 0)
   935  	c.Assert(err, IsNil)
   936  	res, _, err := du.add(s.ctx, now, "1", "MICROSECOND")
   937  	c.Assert(err, IsNil)
   938  	c.Assert(res.Fsp(), Equals, int8(6))
   939  
   940  	tbl = []struct {
   941  		Input         string
   942  		InputDuration string
   943  		expect        string
   944  	}{
   945  		{"01:00:00.999999", "02:00:00.999998", "03:00:01.999997"},
   946  		{"23:59:59", "00:00:01", "24:00:00"},
   947  		{"235959", "00:00:01", "24:00:00"},
   948  		{"110:00:00", "1 02:00:00", "136:00:00"},
   949  		{"-110:00:00", "1 02:00:00", "-84:00:00"},
   950  	}
   951  	for _, t := range tbl {
   952  		dur, err := types.ParseDuration(s.ctx.GetStochastikVars().StmtCtx, t.Input, types.GetFsp(t.Input))
   953  		c.Assert(err, IsNil)
   954  		tmpInput := types.NewDurationCauset(dur)
   955  		tmpInputDuration := types.NewStringCauset(t.InputDuration)
   956  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{tmpInput, tmpInputDuration}))
   957  		c.Assert(err, IsNil)
   958  		d, err := evalBuiltinFunc(f, chunk.Event{})
   959  		c.Assert(err, IsNil)
   960  		result, _ := d.ToString()
   961  		c.Assert(result, Equals, t.expect)
   962  	}
   963  
   964  	tbll := []struct {
   965  		Input         int64
   966  		InputDuration int64
   967  		expect        string
   968  	}{
   969  		{20171010123456, 1, "2020-10-10 12:34:57"},
   970  		{123456, 1, "12:34:57"},
   971  	}
   972  	for _, t := range tbll {
   973  		tmpInput := types.NewIntCauset(t.Input)
   974  		tmpInputDuration := types.NewIntCauset(t.InputDuration)
   975  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{tmpInput, tmpInputDuration}))
   976  		c.Assert(err, IsNil)
   977  		d, err := evalBuiltinFunc(f, chunk.Event{})
   978  		c.Assert(err, IsNil)
   979  		result, _ := d.ToString()
   980  		c.Assert(result, Equals, t.expect)
   981  	}
   982  
   983  	tblWarning := []struct {
   984  		Input         interface{}
   985  		InputDuration interface{}
   986  		warning       *terror.Error
   987  	}{
   988  		{"0", "-32073", types.ErrTruncatedWrongVal},
   989  		{"-32073", "0", types.ErrTruncatedWrongVal},
   990  		{types.ZeroDuration, "-32073", types.ErrTruncatedWrongVal},
   991  		{"-32073", types.ZeroDuration, types.ErrTruncatedWrongVal},
   992  		{types.CurrentTime(allegrosql.TypeTimestamp), "-32073", types.ErrTruncatedWrongVal},
   993  		{types.CurrentTime(allegrosql.TypeDate), "-32073", types.ErrTruncatedWrongVal},
   994  		{types.CurrentTime(allegrosql.TypeDatetime), "-32073", types.ErrTruncatedWrongVal},
   995  	}
   996  	for i, t := range tblWarning {
   997  		tmpInput := types.NewCauset(t.Input)
   998  		tmpInputDuration := types.NewCauset(t.InputDuration)
   999  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{tmpInput, tmpInputDuration}))
  1000  		c.Assert(err, IsNil)
  1001  		d, err := evalBuiltinFunc(f, chunk.Event{})
  1002  		c.Assert(err, IsNil)
  1003  		result, _ := d.ToString()
  1004  		c.Assert(result, Equals, "")
  1005  		c.Assert(d.IsNull(), Equals, true)
  1006  		warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings()
  1007  		c.Assert(len(warnings), Equals, i+1)
  1008  		c.Assert(terror.ErrorEqual(t.warning, warnings[i].Err), IsTrue, Commentf("err %v", warnings[i].Err))
  1009  	}
  1010  }
  1011  
  1012  func (s *testEvaluatorSuite) TestSubTimeSig(c *C) {
  1013  	tbl := []struct {
  1014  		Input         string
  1015  		InputDuration string
  1016  		expect        string
  1017  	}{
  1018  		{"01:00:00.999999", "02:00:00.999998", "-00:59:59.999999"},
  1019  		{"110:00:00", "1 02:00:00", "84:00:00"},
  1020  		{"2020-01-01 01:01:01.11", "01:01:01.11111", "2020-12-31 23:59:59.998890"},
  1021  		{"2007-12-31 23:59:59.999999", "1 1:1:1.000002", "2007-12-30 22:58:58.999997"},
  1022  	}
  1023  	fc := funcs[ast.SubTime]
  1024  	for _, t := range tbl {
  1025  		tmpInput := types.NewStringCauset(t.Input)
  1026  		tmpInputDuration := types.NewStringCauset(t.InputDuration)
  1027  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{tmpInput, tmpInputDuration}))
  1028  		c.Assert(err, IsNil)
  1029  		d, err := evalBuiltinFunc(f, chunk.Event{})
  1030  		c.Assert(err, IsNil)
  1031  		result, _ := d.ToString()
  1032  		c.Assert(result, Equals, t.expect)
  1033  	}
  1034  
  1035  	tbl = []struct {
  1036  		Input         string
  1037  		InputDuration string
  1038  		expect        string
  1039  	}{
  1040  		{"03:00:00.999999", "02:00:00.999998", "01:00:00.000001"},
  1041  		{"23:59:59", "00:00:01", "23:59:58"},
  1042  		{"235959", "00:00:01", "23:59:58"},
  1043  	}
  1044  	for _, t := range tbl {
  1045  		dur, err := types.ParseDuration(s.ctx.GetStochastikVars().StmtCtx, t.Input, types.GetFsp(t.Input))
  1046  		c.Assert(err, IsNil)
  1047  		tmpInput := types.NewDurationCauset(dur)
  1048  		tmpInputDuration := types.NewStringCauset(t.InputDuration)
  1049  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{tmpInput, tmpInputDuration}))
  1050  		c.Assert(err, IsNil)
  1051  		d, err := evalBuiltinFunc(f, chunk.Event{})
  1052  		c.Assert(err, IsNil)
  1053  		result, _ := d.ToString()
  1054  		c.Assert(result, Equals, t.expect)
  1055  	}
  1056  	tbll := []struct {
  1057  		Input         int64
  1058  		InputDuration int64
  1059  		expect        string
  1060  	}{
  1061  		{20171010123456, 1, "2020-10-10 12:34:55"},
  1062  		{123456, 1, "12:34:55"},
  1063  	}
  1064  	for _, t := range tbll {
  1065  		tmpInput := types.NewIntCauset(t.Input)
  1066  		tmpInputDuration := types.NewIntCauset(t.InputDuration)
  1067  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{tmpInput, tmpInputDuration}))
  1068  		c.Assert(err, IsNil)
  1069  		d, err := evalBuiltinFunc(f, chunk.Event{})
  1070  		c.Assert(err, IsNil)
  1071  		result, _ := d.ToString()
  1072  		c.Assert(result, Equals, t.expect)
  1073  	}
  1074  
  1075  	tblWarning := []struct {
  1076  		Input         interface{}
  1077  		InputDuration interface{}
  1078  		warning       *terror.Error
  1079  	}{
  1080  		{"0", "-32073", types.ErrTruncatedWrongVal},
  1081  		{"-32073", "0", types.ErrTruncatedWrongVal},
  1082  		{types.ZeroDuration, "-32073", types.ErrTruncatedWrongVal},
  1083  		{"-32073", types.ZeroDuration, types.ErrTruncatedWrongVal},
  1084  		{types.CurrentTime(allegrosql.TypeTimestamp), "-32073", types.ErrTruncatedWrongVal},
  1085  		{types.CurrentTime(allegrosql.TypeDate), "-32073", types.ErrTruncatedWrongVal},
  1086  		{types.CurrentTime(allegrosql.TypeDatetime), "-32073", types.ErrTruncatedWrongVal},
  1087  	}
  1088  	for i, t := range tblWarning {
  1089  		tmpInput := types.NewCauset(t.Input)
  1090  		tmpInputDuration := types.NewCauset(t.InputDuration)
  1091  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{tmpInput, tmpInputDuration}))
  1092  		c.Assert(err, IsNil)
  1093  		d, err := evalBuiltinFunc(f, chunk.Event{})
  1094  		c.Assert(err, IsNil)
  1095  		result, _ := d.ToString()
  1096  		c.Assert(result, Equals, "")
  1097  		c.Assert(d.IsNull(), Equals, true)
  1098  		warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings()
  1099  		c.Assert(len(warnings), Equals, i+1)
  1100  		c.Assert(terror.ErrorEqual(t.warning, warnings[i].Err), IsTrue, Commentf("err %v", warnings[i].Err))
  1101  	}
  1102  }
  1103  
  1104  func (s *testEvaluatorSuite) TestSysDate(c *C) {
  1105  	fc := funcs[ast.Sysdate]
  1106  
  1107  	ctx := mock.NewContext()
  1108  	ctx.GetStochastikVars().StmtCtx.TimeZone = timeutil.SystemLocation()
  1109  	timezones := []types.Causet{types.NewCauset(1234), types.NewCauset(0)}
  1110  	for _, timezone := range timezones {
  1111  		// sysdate() result is not affected by "timestamp" stochastik variable.
  1112  		variable.SetStochastikSystemVar(ctx.GetStochastikVars(), "timestamp", timezone)
  1113  		f, err := fc.getFunction(ctx, s.datumsToConstants(nil))
  1114  		c.Assert(err, IsNil)
  1115  		resetStmtContext(s.ctx)
  1116  		v, err := evalBuiltinFunc(f, chunk.Event{})
  1117  		last := time.Now()
  1118  		c.Assert(err, IsNil)
  1119  		n := v.GetMysqlTime()
  1120  		c.Assert(n.String(), GreaterEqual, last.Format(types.TimeFormat))
  1121  
  1122  		baseFunc, _, input, output := genVecBuiltinFuncBenchCase(ctx, ast.Sysdate, vecExprBenchCase{retEvalType: types.ETDatetime})
  1123  		resetStmtContext(s.ctx)
  1124  		err = baseFunc.vecEvalTime(input, output)
  1125  		c.Assert(err, IsNil)
  1126  		last = time.Now()
  1127  		times := output.Times()
  1128  		for i := 0; i < 1024; i++ {
  1129  			c.Assert(times[i].String(), GreaterEqual, last.Format(types.TimeFormat))
  1130  		}
  1131  
  1132  		baseFunc, _, input, output = genVecBuiltinFuncBenchCase(ctx, ast.Sysdate,
  1133  			vecExprBenchCase{
  1134  				retEvalType:   types.ETDatetime,
  1135  				childrenTypes: []types.EvalType{types.ETInt},
  1136  				geners:        []dataGenerator{newRangeInt64Gener(0, 7)},
  1137  			})
  1138  		resetStmtContext(s.ctx)
  1139  		loc := ctx.GetStochastikVars().Location()
  1140  		startTm := time.Now().In(loc)
  1141  		err = baseFunc.vecEvalTime(input, output)
  1142  		c.Assert(err, IsNil)
  1143  		for i := 0; i < 1024; i++ {
  1144  			c.Assert(times[i].String(), GreaterEqual, startTm.Format(types.TimeFormat))
  1145  		}
  1146  	}
  1147  
  1148  	last := time.Now()
  1149  	f, err := fc.getFunction(ctx, s.datumsToConstants(types.MakeCausets(6)))
  1150  	c.Assert(err, IsNil)
  1151  	resetStmtContext(s.ctx)
  1152  	v, err := evalBuiltinFunc(f, chunk.Event{})
  1153  	c.Assert(err, IsNil)
  1154  	n := v.GetMysqlTime()
  1155  	c.Assert(n.String(), GreaterEqual, last.Format(types.TimeFormat))
  1156  
  1157  	f, err = fc.getFunction(ctx, s.datumsToConstants(types.MakeCausets(-2)))
  1158  	c.Assert(err, IsNil)
  1159  	_, err = evalBuiltinFunc(f, chunk.Event{})
  1160  	c.Assert(err, NotNil)
  1161  }
  1162  
  1163  func convertToTimeWithFsp(sc *stmtctx.StatementContext, arg types.Causet, tp byte, fsp int8) (d types.Causet, err error) {
  1164  	if fsp > types.MaxFsp {
  1165  		fsp = types.MaxFsp
  1166  	}
  1167  
  1168  	f := types.NewFieldType(tp)
  1169  	f.Decimal = int(fsp)
  1170  
  1171  	d, err = arg.ConvertTo(sc, f)
  1172  	if err != nil {
  1173  		d.SetNull()
  1174  		return d, err
  1175  	}
  1176  
  1177  	if d.IsNull() {
  1178  		return
  1179  	}
  1180  
  1181  	if d.HoTT() != types.HoTTMysqlTime {
  1182  		d.SetNull()
  1183  		return d, errors.Errorf("need time type, but got %T", d.GetValue())
  1184  	}
  1185  	return
  1186  }
  1187  
  1188  func convertToTime(sc *stmtctx.StatementContext, arg types.Causet, tp byte) (d types.Causet, err error) {
  1189  	return convertToTimeWithFsp(sc, arg, tp, types.MaxFsp)
  1190  }
  1191  
  1192  func builtinDateFormat(ctx stochastikctx.Context, args []types.Causet) (d types.Causet, err error) {
  1193  	date, err := convertToTime(ctx.GetStochastikVars().StmtCtx, args[0], allegrosql.TypeDatetime)
  1194  	if err != nil {
  1195  		return d, err
  1196  	}
  1197  
  1198  	if date.IsNull() {
  1199  		return
  1200  	}
  1201  	t := date.GetMysqlTime()
  1202  	str, err := t.DateFormat(args[1].GetString())
  1203  	if err != nil {
  1204  		return d, err
  1205  	}
  1206  	d.SetString(str, allegrosql.DefaultDefCauslationName)
  1207  	return
  1208  }
  1209  
  1210  func (s *testEvaluatorSuite) TestFromUnixTime(c *C) {
  1211  	tbl := []struct {
  1212  		isDecimal      bool
  1213  		integralPart   int64
  1214  		fractionalPart int64
  1215  		decimal        float64
  1216  		format         string
  1217  		expect         string
  1218  	}{
  1219  		{false, 1451606400, 0, 0, "", "2020-01-01 00:00:00"},
  1220  		{true, 1451606400, 123456000, 1451606400.123456, "", "2020-01-01 00:00:00.123456"},
  1221  		{true, 1451606400, 999999000, 1451606400.999999, "", "2020-01-01 00:00:00.999999"},
  1222  		{true, 1451606400, 999999900, 1451606400.9999999, "", "2020-01-01 00:00:01.000000"},
  1223  		{false, 1451606400, 0, 0, `%Y %D %M %h:%i:%s %x`, "2020-01-01 00:00:00"},
  1224  		{true, 1451606400, 123456000, 1451606400.123456, `%Y %D %M %h:%i:%s %x`, "2020-01-01 00:00:00.123456"},
  1225  		{true, 1451606400, 999999000, 1451606400.999999, `%Y %D %M %h:%i:%s %x`, "2020-01-01 00:00:00.999999"},
  1226  		{true, 1451606400, 999999900, 1451606400.9999999, `%Y %D %M %h:%i:%s %x`, "2020-01-01 00:00:01.000000"},
  1227  	}
  1228  	sc := s.ctx.GetStochastikVars().StmtCtx
  1229  	originTZ := sc.TimeZone
  1230  	sc.TimeZone = time.UTC
  1231  	defer func() {
  1232  		sc.TimeZone = originTZ
  1233  	}()
  1234  	fc := funcs[ast.FromUnixTime]
  1235  	for _, t := range tbl {
  1236  		var timestamp types.Causet
  1237  		if !t.isDecimal {
  1238  			timestamp.SetInt64(t.integralPart)
  1239  		} else {
  1240  			timestamp.SetFloat64(t.decimal)
  1241  		}
  1242  		// result of from_unixtime() is dependent on specific time zone.
  1243  		if len(t.format) == 0 {
  1244  			constants := s.datumsToConstants([]types.Causet{timestamp})
  1245  			if !t.isDecimal {
  1246  				constants[0].GetType().Decimal = 0
  1247  			}
  1248  
  1249  			f, err := fc.getFunction(s.ctx, constants)
  1250  			c.Assert(err, IsNil)
  1251  
  1252  			v, err := evalBuiltinFunc(f, chunk.Event{})
  1253  			c.Assert(err, IsNil)
  1254  			ans := v.GetMysqlTime()
  1255  			c.Assert(ans.String(), Equals, t.expect, Commentf("%+v", t))
  1256  		} else {
  1257  			format := types.NewStringCauset(t.format)
  1258  			constants := s.datumsToConstants([]types.Causet{timestamp, format})
  1259  			if !t.isDecimal {
  1260  				constants[0].GetType().Decimal = 0
  1261  			}
  1262  			f, err := fc.getFunction(s.ctx, constants)
  1263  			c.Assert(err, IsNil)
  1264  			v, err := evalBuiltinFunc(f, chunk.Event{})
  1265  			c.Assert(err, IsNil)
  1266  			result, err := builtinDateFormat(s.ctx, []types.Causet{types.NewStringCauset(t.expect), format})
  1267  			c.Assert(err, IsNil)
  1268  			c.Assert(v.GetString(), Equals, result.GetString(), Commentf("%+v", t))
  1269  		}
  1270  	}
  1271  
  1272  	f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(-12345)))
  1273  	c.Assert(err, IsNil)
  1274  	v, err := evalBuiltinFunc(f, chunk.Event{})
  1275  	c.Assert(err, IsNil)
  1276  	c.Assert(v.HoTT(), Equals, types.HoTTNull)
  1277  
  1278  	f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(math.MaxInt32+1)))
  1279  	c.Assert(err, IsNil)
  1280  	_, err = evalBuiltinFunc(f, chunk.Event{})
  1281  	c.Assert(err, IsNil)
  1282  	c.Assert(v.HoTT(), Equals, types.HoTTNull)
  1283  }
  1284  
  1285  func (s *testEvaluatorSuite) TestCurrentDate(c *C) {
  1286  	last := time.Now()
  1287  	fc := funcs[ast.CurrentDate]
  1288  	f, err := fc.getFunction(mock.NewContext(), s.datumsToConstants(nil))
  1289  	c.Assert(err, IsNil)
  1290  	resetStmtContext(s.ctx)
  1291  	v, err := evalBuiltinFunc(f, chunk.Event{})
  1292  	c.Assert(err, IsNil)
  1293  	n := v.GetMysqlTime()
  1294  	c.Assert(n.String(), GreaterEqual, last.Format(types.DateFormat))
  1295  }
  1296  
  1297  func (s *testEvaluatorSuite) TestCurrentTime(c *C) {
  1298  	tfStr := "15:04:05"
  1299  
  1300  	last := time.Now()
  1301  	fc := funcs[ast.CurrentTime]
  1302  	f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(nil)))
  1303  	c.Assert(err, IsNil)
  1304  	resetStmtContext(s.ctx)
  1305  	v, err := evalBuiltinFunc(f, chunk.Event{})
  1306  	c.Assert(err, IsNil)
  1307  	n := v.GetMysqlDuration()
  1308  	c.Assert(n.String(), HasLen, 8)
  1309  	c.Assert(n.String(), GreaterEqual, last.Format(tfStr))
  1310  
  1311  	f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(3)))
  1312  	c.Assert(err, IsNil)
  1313  	resetStmtContext(s.ctx)
  1314  	v, err = evalBuiltinFunc(f, chunk.Event{})
  1315  	c.Assert(err, IsNil)
  1316  	n = v.GetMysqlDuration()
  1317  	c.Assert(n.String(), HasLen, 12)
  1318  	c.Assert(n.String(), GreaterEqual, last.Format(tfStr))
  1319  
  1320  	f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(6)))
  1321  	c.Assert(err, IsNil)
  1322  	resetStmtContext(s.ctx)
  1323  	v, err = evalBuiltinFunc(f, chunk.Event{})
  1324  	c.Assert(err, IsNil)
  1325  	n = v.GetMysqlDuration()
  1326  	c.Assert(n.String(), HasLen, 15)
  1327  	c.Assert(n.String(), GreaterEqual, last.Format(tfStr))
  1328  
  1329  	_, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(-1)))
  1330  	c.Assert(err, NotNil)
  1331  
  1332  	_, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(7)))
  1333  	c.Assert(err, NotNil)
  1334  }
  1335  
  1336  func (s *testEvaluatorSuite) TestUTCTime(c *C) {
  1337  	last := time.Now().UTC()
  1338  	tfStr := "00:00:00"
  1339  	fc := funcs[ast.UTCTime]
  1340  
  1341  	tests := []struct {
  1342  		param  interface{}
  1343  		expect int
  1344  	}{{0, 8}, {3, 12}, {6, 15}, {-1, 0}, {7, 0}}
  1345  
  1346  	for _, test := range tests {
  1347  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(test.param)))
  1348  		c.Assert(err, IsNil)
  1349  		resetStmtContext(s.ctx)
  1350  		v, err := evalBuiltinFunc(f, chunk.Event{})
  1351  		if test.expect > 0 {
  1352  			c.Assert(err, IsNil)
  1353  			n := v.GetMysqlDuration()
  1354  			c.Assert(n.String(), HasLen, test.expect)
  1355  			c.Assert(n.String(), GreaterEqual, last.Format(tfStr))
  1356  		} else {
  1357  			c.Assert(err, NotNil)
  1358  		}
  1359  	}
  1360  
  1361  	f, err := fc.getFunction(s.ctx, make([]Expression, 0))
  1362  	c.Assert(err, IsNil)
  1363  	resetStmtContext(s.ctx)
  1364  	v, err := evalBuiltinFunc(f, chunk.Event{})
  1365  	c.Assert(err, IsNil)
  1366  	n := v.GetMysqlDuration()
  1367  	c.Assert(n.String(), HasLen, 8)
  1368  	c.Assert(n.String(), GreaterEqual, last.Format(tfStr))
  1369  }
  1370  
  1371  func (s *testEvaluatorSuite) TestUTCDate(c *C) {
  1372  	last := time.Now().UTC()
  1373  	fc := funcs[ast.UTCDate]
  1374  	f, err := fc.getFunction(mock.NewContext(), s.datumsToConstants(nil))
  1375  	c.Assert(err, IsNil)
  1376  	resetStmtContext(mock.NewContext())
  1377  	v, err := evalBuiltinFunc(f, chunk.Event{})
  1378  	c.Assert(err, IsNil)
  1379  	n := v.GetMysqlTime()
  1380  	c.Assert(n.String(), GreaterEqual, last.Format(types.DateFormat))
  1381  }
  1382  
  1383  func (s *testEvaluatorSuite) TestStrToDate(c *C) {
  1384  	tests := []struct {
  1385  		Date    string
  1386  		Format  string
  1387  		Success bool
  1388  		Expect  time.Time
  1389  	}{
  1390  		{"10/28/2011 9:46:29 pm", "%m/%d/%Y %l:%i:%s %p", true, time.Date(2011, 10, 28, 21, 46, 29, 0, time.Local)},
  1391  		{"10/28/2011 9:46:29 Pm", "%m/%d/%Y %l:%i:%s %p", true, time.Date(2011, 10, 28, 21, 46, 29, 0, time.Local)},
  1392  		{"2011/10/28 9:46:29 am", "%Y/%m/%d %l:%i:%s %p", true, time.Date(2011, 10, 28, 9, 46, 29, 0, time.Local)},
  1393  		{"20161122165022", `%Y%m%d%H%i%s`, true, time.Date(2020, 11, 22, 16, 50, 22, 0, time.Local)},
  1394  		{"2020 11 22 16 50 22", `%Y%m%d%H%i%s`, true, time.Date(2020, 11, 22, 16, 50, 22, 0, time.Local)},
  1395  		{"16-50-22 2020 11 22", `%H-%i-%s%Y%m%d`, true, time.Date(2020, 11, 22, 16, 50, 22, 0, time.Local)},
  1396  		{"16-50 2020 11 22", `%H-%i-%s%Y%m%d`, false, time.Time{}},
  1397  		{"15-01-2001 1:59:58.999", "%d-%m-%Y %I:%i:%s.%f", true, time.Date(2001, 1, 15, 1, 59, 58, 999000000, time.Local)},
  1398  		{"15-01-2001 1:59:58.1", "%d-%m-%Y %H:%i:%s.%f", true, time.Date(2001, 1, 15, 1, 59, 58, 100000000, time.Local)},
  1399  		{"15-01-2001 1:59:58.", "%d-%m-%Y %H:%i:%s.%f", true, time.Date(2001, 1, 15, 1, 59, 58, 000000000, time.Local)},
  1400  		{"15-01-2001 1:9:8.999", "%d-%m-%Y %H:%i:%s.%f", true, time.Date(2001, 1, 15, 1, 9, 8, 999000000, time.Local)},
  1401  		{"15-01-2001 1:9:8.999", "%d-%m-%Y %H:%i:%S.%f", true, time.Date(2001, 1, 15, 1, 9, 8, 999000000, time.Local)},
  1402  		{"2003-01-02 10:11:12 PM", "%Y-%m-%d %H:%i:%S %p", false, time.Time{}},
  1403  		{"10:20:10AM", "%H:%i:%S%p", false, time.Time{}},
  1404  	}
  1405  
  1406  	fc := funcs[ast.StrToDate]
  1407  	for _, test := range tests {
  1408  		date := types.NewStringCauset(test.Date)
  1409  		format := types.NewStringCauset(test.Format)
  1410  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{date, format}))
  1411  		c.Assert(err, IsNil)
  1412  		result, err := evalBuiltinFunc(f, chunk.Event{})
  1413  		c.Assert(err, IsNil)
  1414  		if !test.Success {
  1415  			c.Assert(err, IsNil)
  1416  			c.Assert(result.IsNull(), IsTrue)
  1417  			continue
  1418  		}
  1419  		c.Assert(result.HoTT(), Equals, types.HoTTMysqlTime)
  1420  		value := result.GetMysqlTime()
  1421  		t1, _ := value.GoTime(time.Local)
  1422  		c.Assert(t1, Equals, test.Expect)
  1423  	}
  1424  }
  1425  
  1426  func (s *testEvaluatorSuite) TestFromDays(c *C) {
  1427  	stmtCtx := s.ctx.GetStochastikVars().StmtCtx
  1428  	origin := stmtCtx.IgnoreTruncate
  1429  	stmtCtx.IgnoreTruncate = true
  1430  	defer func() {
  1431  		stmtCtx.IgnoreTruncate = origin
  1432  	}()
  1433  	tests := []struct {
  1434  		day    int64
  1435  		expect string
  1436  	}{
  1437  		{-140, "0000-00-00"},   // allegrosql FROM_DAYS returns 0000-00-00 for any day <= 365.
  1438  		{140, "0000-00-00"},    // allegrosql FROM_DAYS returns 0000-00-00 for any day <= 365.
  1439  		{735000, "2012-05-12"}, // Leap year.
  1440  		{735030, "2012-06-11"},
  1441  		{735130, "2012-09-19"},
  1442  		{734909, "2012-02-11"},
  1443  		{734878, "2012-01-11"},
  1444  		{734927, "2012-02-29"},
  1445  		{734634, "2011-05-12"}, // Non Leap year.
  1446  		{734664, "2011-06-11"},
  1447  		{734764, "2011-09-19"},
  1448  		{734544, "2011-02-11"},
  1449  		{734513, "2011-01-11"},
  1450  	}
  1451  
  1452  	fc := funcs[ast.FromDays]
  1453  	for _, test := range tests {
  1454  		t1 := types.NewIntCauset(test.day)
  1455  
  1456  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{t1}))
  1457  		c.Assert(err, IsNil)
  1458  		c.Assert(f, NotNil)
  1459  		result, err := evalBuiltinFunc(f, chunk.Event{})
  1460  
  1461  		c.Assert(err, IsNil)
  1462  		c.Assert(result.GetMysqlTime().String(), Equals, test.expect)
  1463  	}
  1464  
  1465  	stringTests := []struct {
  1466  		day    string
  1467  		expect string
  1468  	}{
  1469  		{"z550z", "0000-00-00"},
  1470  		{"6500z", "0017-10-18"},
  1471  		{"440", "0001-03-16"},
  1472  	}
  1473  
  1474  	for _, test := range stringTests {
  1475  		t1 := types.NewStringCauset(test.day)
  1476  
  1477  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{t1}))
  1478  		c.Assert(err, IsNil)
  1479  		result, err := evalBuiltinFunc(f, chunk.Event{})
  1480  
  1481  		c.Assert(err, IsNil)
  1482  		c.Assert(result.GetMysqlTime().String(), Equals, test.expect)
  1483  	}
  1484  }
  1485  
  1486  func (s *testEvaluatorSuite) TestDateDiff(c *C) {
  1487  	// Test cases from https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_datediff
  1488  	tests := []struct {
  1489  		t1     string
  1490  		t2     string
  1491  		expect int64
  1492  	}{
  1493  		{"2004-05-21", "2004:01:02", 140},
  1494  		{"2004-04-21", "2000:01:02", 1571},
  1495  		{"2008-12-31 23:59:59.000001", "2008-12-30 01:01:01.000002", 1},
  1496  		{"1010-11-30 23:59:59", "2010-12-31", -365274},
  1497  		{"1010-11-30", "2210-11-01", -438262},
  1498  	}
  1499  
  1500  	fc := funcs[ast.DateDiff]
  1501  	for _, test := range tests {
  1502  		t1 := types.NewStringCauset(test.t1)
  1503  		t2 := types.NewStringCauset(test.t2)
  1504  
  1505  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{t1, t2}))
  1506  		c.Assert(err, IsNil)
  1507  		result, err := evalBuiltinFunc(f, chunk.Event{})
  1508  
  1509  		c.Assert(err, IsNil)
  1510  		c.Assert(result.GetInt64(), Equals, test.expect)
  1511  	}
  1512  
  1513  	// Test invalid time format.
  1514  	tests2 := []struct {
  1515  		t1 string
  1516  		t2 string
  1517  	}{
  1518  		{"2004-05-21", "abcdefg"},
  1519  		{"2007-12-31 23:59:59", "23:59:59"},
  1520  		{"2007-00-31 23:59:59", "2020-01-13"},
  1521  		{"2007-10-31 23:59:59", "2020-01-00"},
  1522  		{"2007-10-31 23:59:59", "99999999-01-00"},
  1523  	}
  1524  
  1525  	fc = funcs[ast.DateDiff]
  1526  	for _, test := range tests2 {
  1527  		t1 := types.NewStringCauset(test.t1)
  1528  		t2 := types.NewStringCauset(test.t2)
  1529  
  1530  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{t1, t2}))
  1531  		c.Assert(err, IsNil)
  1532  		d, err := evalBuiltinFunc(f, chunk.Event{})
  1533  		c.Assert(err, IsNil)
  1534  		c.Assert(d.IsNull(), IsTrue)
  1535  	}
  1536  }
  1537  
  1538  func (s *testEvaluatorSuite) TestTimeDiff(c *C) {
  1539  	sc := s.ctx.GetStochastikVars().StmtCtx
  1540  	sc.IgnoreZeroInDate = true
  1541  	// Test cases from https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timediff
  1542  	tests := []struct {
  1543  		args       []interface{}
  1544  		expectStr  string
  1545  		isNil      bool
  1546  		fsp        int8
  1547  		getWarning bool
  1548  	}{
  1549  		{[]interface{}{"2000:01:01 00:00:00", "2000:01:01 00:00:00.000001"}, "-00:00:00.000001", false, 6, false},
  1550  		{[]interface{}{"2008-12-31 23:59:59.000001", "2008-12-30 01:01:01.000002"}, "46:58:57.999999", false, 6, false},
  1551  		{[]interface{}{"2020-12-00 12:00:00", "2020-12-01 12:00:00"}, "-24:00:00", false, 0, false},
  1552  		{[]interface{}{"10:10:10", "10:9:0"}, "00:01:10", false, 0, false},
  1553  		{[]interface{}{"2020-12-00 12:00:00", "10:9:0"}, "", true, 0, false},
  1554  		{[]interface{}{"2020-12-00 12:00:00", ""}, "", true, 0, true},
  1555  	}
  1556  
  1557  	for _, t := range tests {
  1558  		preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount()
  1559  		f, err := newFunctionForTest(s.ctx, ast.TimeDiff, s.primitiveValsToConstants(t.args)...)
  1560  		c.Assert(err, IsNil)
  1561  		tp := f.GetType()
  1562  		c.Assert(tp.Tp, Equals, allegrosql.TypeDuration)
  1563  		c.Assert(tp.Charset, Equals, charset.CharsetBin)
  1564  		c.Assert(tp.DefCauslate, Equals, charset.DefCauslationBin)
  1565  		c.Assert(tp.Flag, Equals, allegrosql.BinaryFlag)
  1566  		c.Assert(tp.Flen, Equals, allegrosql.MaxDurationWidthWithFsp)
  1567  		d, err := f.Eval(chunk.Event{})
  1568  		if t.getWarning {
  1569  			c.Assert(err, IsNil)
  1570  			c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1)
  1571  		} else {
  1572  			c.Assert(err, IsNil)
  1573  			if t.isNil {
  1574  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
  1575  			} else {
  1576  				c.Assert(d.GetMysqlDuration().String(), Equals, t.expectStr)
  1577  				c.Assert(d.GetMysqlDuration().Fsp, Equals, t.fsp)
  1578  			}
  1579  		}
  1580  	}
  1581  	_, err := funcs[ast.TimeDiff].getFunction(s.ctx, []Expression{NewZero(), NewZero()})
  1582  	c.Assert(err, IsNil)
  1583  }
  1584  
  1585  func (s *testEvaluatorSuite) TestWeek(c *C) {
  1586  	// Test cases from https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_week
  1587  	tests := []struct {
  1588  		t      string
  1589  		mode   int64
  1590  		expect int64
  1591  	}{
  1592  		{"2008-02-20", 0, 7},
  1593  		{"2008-02-20", 1, 8},
  1594  		{"2008-12-31", 1, 53},
  1595  	}
  1596  	fc := funcs[ast.Week]
  1597  	for _, test := range tests {
  1598  		arg1 := types.NewStringCauset(test.t)
  1599  		arg2 := types.NewIntCauset(test.mode)
  1600  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{arg1, arg2}))
  1601  		c.Assert(err, IsNil)
  1602  		result, err := evalBuiltinFunc(f, chunk.Event{})
  1603  		c.Assert(err, IsNil)
  1604  		c.Assert(result.GetInt64(), Equals, test.expect)
  1605  	}
  1606  }
  1607  
  1608  func (s *testEvaluatorSuite) TestWeekWithoutModeSig(c *C) {
  1609  	tests := []struct {
  1610  		t      string
  1611  		expect int64
  1612  	}{
  1613  		{"2008-02-20", 7},
  1614  		{"2000-12-31", 53},
  1615  		{"2000-12-31", 1}, //set default week mode
  1616  		{"2005-12-3", 48}, //set default week mode
  1617  		{"2008-02-20", 7},
  1618  	}
  1619  
  1620  	fc := funcs[ast.Week]
  1621  	for i, test := range tests {
  1622  		arg1 := types.NewStringCauset(test.t)
  1623  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{arg1}))
  1624  		c.Assert(err, IsNil)
  1625  		result, err := evalBuiltinFunc(f, chunk.Event{})
  1626  		c.Assert(err, IsNil)
  1627  		c.Assert(result.GetInt64(), Equals, test.expect)
  1628  		if i == 1 {
  1629  			s.ctx.GetStochastikVars().SetSystemVar("default_week_format", "6")
  1630  		} else if i == 3 {
  1631  			s.ctx.GetStochastikVars().SetSystemVar("default_week_format", "")
  1632  		}
  1633  	}
  1634  }
  1635  func (s *testEvaluatorSuite) TestYearWeek(c *C) {
  1636  	sc := s.ctx.GetStochastikVars().StmtCtx
  1637  	sc.IgnoreZeroInDate = true
  1638  	// Test cases from https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_yearweek
  1639  	tests := []struct {
  1640  		t      string
  1641  		mode   int64
  1642  		expect int64
  1643  	}{
  1644  		{"1987-01-01", 0, 198652},
  1645  		{"2000-01-01", 0, 199952},
  1646  	}
  1647  	fc := funcs[ast.YearWeek]
  1648  	for _, test := range tests {
  1649  		arg1 := types.NewStringCauset(test.t)
  1650  		arg2 := types.NewIntCauset(test.mode)
  1651  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{arg1, arg2}))
  1652  		c.Assert(err, IsNil)
  1653  		result, err := evalBuiltinFunc(f, chunk.Event{})
  1654  		c.Assert(err, IsNil)
  1655  		c.Assert(result.GetInt64(), Equals, test.expect)
  1656  	}
  1657  
  1658  	f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets("2020-00-05")))
  1659  	c.Assert(err, IsNil)
  1660  	result, err := evalBuiltinFunc(f, chunk.Event{})
  1661  	c.Assert(err, IsNil)
  1662  	c.Assert(result.IsNull(), IsTrue)
  1663  }
  1664  
  1665  func (s *testEvaluatorSuite) TestTimestamFIDeliff(c *C) {
  1666  	tests := []struct {
  1667  		unit   string
  1668  		t1     string
  1669  		t2     string
  1670  		expect int64
  1671  	}{
  1672  		{"MONTH", "2003-02-01", "2003-05-01", 3},
  1673  		{"YEAR", "2002-05-01", "2001-01-01", -1},
  1674  		{"MINUTE", "2003-02-01", "2003-05-01 12:05:55", 128885},
  1675  	}
  1676  
  1677  	fc := funcs[ast.TimestamFIDeliff]
  1678  	for _, test := range tests {
  1679  		args := []types.Causet{
  1680  			types.NewStringCauset(test.unit),
  1681  			types.NewStringCauset(test.t1),
  1682  			types.NewStringCauset(test.t2),
  1683  		}
  1684  		resetStmtContext(s.ctx)
  1685  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
  1686  		c.Assert(err, IsNil)
  1687  		d, err := evalBuiltinFunc(f, chunk.Event{})
  1688  		c.Assert(err, IsNil)
  1689  		c.Assert(d.GetInt64(), Equals, test.expect)
  1690  	}
  1691  	sc := s.ctx.GetStochastikVars().StmtCtx
  1692  	sc.IgnoreTruncate = true
  1693  	sc.IgnoreZeroInDate = true
  1694  	resetStmtContext(s.ctx)
  1695  	f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{types.NewStringCauset("DAY"),
  1696  		types.NewStringCauset("2020-01-00"),
  1697  		types.NewStringCauset("2020-01-01")}))
  1698  	c.Assert(err, IsNil)
  1699  	d, err := evalBuiltinFunc(f, chunk.Event{})
  1700  	c.Assert(err, IsNil)
  1701  	c.Assert(d.HoTT(), Equals, types.HoTTNull)
  1702  
  1703  	resetStmtContext(s.ctx)
  1704  	f, err = fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{types.NewStringCauset("DAY"),
  1705  		{}, types.NewStringCauset("2020-01-01")}))
  1706  	c.Assert(err, IsNil)
  1707  	d, err = evalBuiltinFunc(f, chunk.Event{})
  1708  	c.Assert(err, IsNil)
  1709  	c.Assert(d.IsNull(), IsTrue)
  1710  }
  1711  
  1712  func (s *testEvaluatorSuite) TestUnixTimestamp(c *C) {
  1713  	// Test UNIX_TIMESTAMP().
  1714  	fc := funcs[ast.UnixTimestamp]
  1715  	f, err := fc.getFunction(s.ctx, nil)
  1716  	c.Assert(err, IsNil)
  1717  	resetStmtContext(s.ctx)
  1718  	d, err := evalBuiltinFunc(f, chunk.Event{})
  1719  	c.Assert(err, IsNil)
  1720  	c.Assert(d.GetInt64()-time.Now().Unix(), GreaterEqual, int64(-1))
  1721  	c.Assert(d.GetInt64()-time.Now().Unix(), LessEqual, int64(1))
  1722  
  1723  	// https://github.com/whtcorpsinc/milevadb/issues/2496
  1724  	// Test UNIX_TIMESTAMP(NOW()).
  1725  	resetStmtContext(s.ctx)
  1726  	now, isNull, err := evalNowWithFsp(s.ctx, 0)
  1727  	c.Assert(err, IsNil)
  1728  	c.Assert(isNull, IsFalse)
  1729  	n := types.Causet{}
  1730  	n.SetMysqlTime(now)
  1731  	args := []types.Causet{n}
  1732  	f, err = fc.getFunction(s.ctx, s.datumsToConstants(args))
  1733  	c.Assert(err, IsNil)
  1734  	resetStmtContext(s.ctx)
  1735  	d, err = evalBuiltinFunc(f, chunk.Event{})
  1736  	c.Assert(err, IsNil)
  1737  	val, _ := d.GetMysqlDecimal().ToInt()
  1738  	c.Assert(val-time.Now().Unix(), GreaterEqual, int64(-1))
  1739  	c.Assert(val-time.Now().Unix(), LessEqual, int64(1))
  1740  
  1741  	// https://github.com/whtcorpsinc/milevadb/issues/2852
  1742  	// Test UNIX_TIMESTAMP(NULL).
  1743  	args = []types.Causet{types.NewCauset(nil)}
  1744  	resetStmtContext(s.ctx)
  1745  	f, err = fc.getFunction(s.ctx, s.datumsToConstants(args))
  1746  	c.Assert(err, IsNil)
  1747  	d, err = evalBuiltinFunc(f, chunk.Event{})
  1748  	c.Assert(err, IsNil)
  1749  	c.Assert(d.IsNull(), Equals, true)
  1750  
  1751  	// Set the time_zone variable, because UnixTimestamp() result depends on it.
  1752  	s.ctx.GetStochastikVars().TimeZone = time.UTC
  1753  	s.ctx.GetStochastikVars().StmtCtx.IgnoreZeroInDate = true
  1754  	tests := []struct {
  1755  		inputDecimal int
  1756  		input        types.Causet
  1757  		expectHoTT   byte
  1758  		expect       string
  1759  	}{
  1760  		{0, types.NewIntCauset(151113), types.HoTTInt64, "1447372800"}, // YYMMDD
  1761  		// TODO: Uncomment the line below after fixing #4232
  1762  		// {5, types.NewFloat64Causet(151113.12345), types.HoTTMysqlDecimal, "1447372800.00000"},                                           // YYMMDD
  1763  		{0, types.NewIntCauset(20151113), types.HoTTInt64, "1447372800"}, // YYYYMMDD
  1764  		// TODO: Uncomment the line below after fixing #4232
  1765  		// {5, types.NewFloat64Causet(20151113.12345), types.HoTTMysqlDecimal, "1447372800.00000"},                                         // YYYYMMDD
  1766  		{0, types.NewIntCauset(151113102019), types.HoTTInt64, "1447410019"},                                                            // YYMMDDHHMMSS
  1767  		{0, types.NewFloat64Causet(151113102019), types.HoTTInt64, "1447410019"},                                                        // YYMMDDHHMMSS
  1768  		{2, types.NewFloat64Causet(151113102019.12), types.HoTTMysqlDecimal, "1447410019.12"},                                           // YYMMDDHHMMSS
  1769  		{0, types.NewDecimalCauset(types.NewDecFromStringForTest("151113102019")), types.HoTTInt64, "1447410019"},                       // YYMMDDHHMMSS
  1770  		{2, types.NewDecimalCauset(types.NewDecFromStringForTest("151113102019.12")), types.HoTTMysqlDecimal, "1447410019.12"},          // YYMMDDHHMMSS
  1771  		{7, types.NewDecimalCauset(types.NewDecFromStringForTest("151113102019.1234567")), types.HoTTMysqlDecimal, "1447410019.123457"}, // YYMMDDHHMMSS
  1772  		{0, types.NewIntCauset(20151113102019), types.HoTTInt64, "1447410019"},                                                          // YYYYMMDDHHMMSS
  1773  		{0, types.NewStringCauset("2020-11-13 10:20:19"), types.HoTTInt64, "1447410019"},
  1774  		{0, types.NewStringCauset("2020-11-13 10:20:19.012"), types.HoTTMysqlDecimal, "1447410019.012"},
  1775  		{0, types.NewStringCauset("1970-01-01 00:00:00"), types.HoTTInt64, "0"},                               // Min timestamp
  1776  		{0, types.NewStringCauset("2038-01-19 03:14:07.999999"), types.HoTTMysqlDecimal, "2147483647.999999"}, // Max timestamp
  1777  		{0, types.NewStringCauset("2020-00-02"), types.HoTTInt64, "0"},                                        // Invalid date
  1778  		{0, types.NewStringCauset("1969-12-31 23:59:59.999999"), types.HoTTMysqlDecimal, "0"},                 // Invalid timestamp
  1779  		{0, types.NewStringCauset("2038-01-19 03:14:08"), types.HoTTInt64, "0"},                               // Invalid timestamp
  1780  		// Below tests irregular inputs.
  1781  		//{0, types.NewIntCauset(0), types.HoTTInt64, "0"},
  1782  		//{0, types.NewIntCauset(-1), types.HoTTInt64, "0"},
  1783  		//{0, types.NewIntCauset(12345), types.HoTTInt64, "0"},
  1784  	}
  1785  
  1786  	for _, test := range tests {
  1787  		expr := s.datumsToConstants([]types.Causet{test.input})
  1788  		expr[0].GetType().Decimal = test.inputDecimal
  1789  		resetStmtContext(s.ctx)
  1790  		f, err := fc.getFunction(s.ctx, expr)
  1791  		c.Assert(err, IsNil, Commentf("%+v", test))
  1792  		d, err := evalBuiltinFunc(f, chunk.Event{})
  1793  		c.Assert(err, IsNil, Commentf("%+v", test))
  1794  		c.Assert(d.HoTT(), Equals, test.expectHoTT, Commentf("%+v", test))
  1795  		str, err := d.ToString()
  1796  		c.Assert(err, IsNil, Commentf("%+v", test))
  1797  		c.Assert(str, Equals, test.expect, Commentf("%+v", test))
  1798  	}
  1799  }
  1800  
  1801  func (s *testEvaluatorSuite) TestDateArithFuncs(c *C) {
  1802  	date := []string{"2020-12-31", "2020-01-01"}
  1803  	fcAdd := funcs[ast.DateAdd]
  1804  	fcSub := funcs[ast.DateSub]
  1805  
  1806  	tests := []struct {
  1807  		inputDate    string
  1808  		fc           functionClass
  1809  		inputDecimal float64
  1810  		expect       string
  1811  	}{
  1812  		{date[0], fcAdd, 1, date[1]},
  1813  		{date[1], fcAdd, -1, date[0]},
  1814  		{date[1], fcAdd, -0.5, date[0]},
  1815  		{date[1], fcAdd, -1.4, date[0]},
  1816  
  1817  		{date[1], fcSub, 1, date[0]},
  1818  		{date[0], fcSub, -1, date[1]},
  1819  		{date[0], fcSub, -0.5, date[1]},
  1820  		{date[0], fcSub, -1.4, date[1]},
  1821  	}
  1822  	for _, test := range tests {
  1823  		args := types.MakeCausets(test.inputDate, test.inputDecimal, "DAY")
  1824  		f, err := test.fc.getFunction(s.ctx, s.datumsToConstants(args))
  1825  		c.Assert(err, IsNil)
  1826  		c.Assert(f, NotNil)
  1827  		v, err := evalBuiltinFunc(f, chunk.Event{})
  1828  		c.Assert(err, IsNil)
  1829  		c.Assert(v.GetMysqlTime().String(), Equals, test.expect)
  1830  	}
  1831  
  1832  	args := types.MakeCausets(date[0], nil, "DAY")
  1833  	f, err := fcAdd.getFunction(s.ctx, s.datumsToConstants(args))
  1834  	c.Assert(err, IsNil)
  1835  	c.Assert(f, NotNil)
  1836  	v, err := evalBuiltinFunc(f, chunk.Event{})
  1837  	c.Assert(err, IsNil)
  1838  	c.Assert(v.IsNull(), IsTrue)
  1839  
  1840  	args = types.MakeCausets(date[1], nil, "DAY")
  1841  	f, err = fcSub.getFunction(s.ctx, s.datumsToConstants(args))
  1842  	c.Assert(err, IsNil)
  1843  	c.Assert(f, NotNil)
  1844  	v, err = evalBuiltinFunc(f, chunk.Event{})
  1845  	c.Assert(err, IsNil)
  1846  	c.Assert(v.IsNull(), IsTrue)
  1847  
  1848  	testMonths := []struct {
  1849  		input    string
  1850  		months   int
  1851  		expected string
  1852  	}{
  1853  		{"1900-01-31", 1, "1900-02-28"},
  1854  		{"2000-01-31", 1, "2000-02-29"},
  1855  		{"2020-01-31", 1, "2020-02-29"},
  1856  		{"2020-07-31", 1, "2020-08-31"},
  1857  		{"2020-08-31", 1, "2020-09-30"},
  1858  		{"2020-07-31", 2, "2020-09-30"},
  1859  		{"2020-01-31", 27, "2020-04-30"},
  1860  		{"2000-02-29", 12, "2001-02-28"},
  1861  		{"2000-11-30", 1, "2000-12-30"},
  1862  	}
  1863  
  1864  	for _, test := range testMonths {
  1865  		args = types.MakeCausets(test.input, test.months, "MONTH")
  1866  		f, err = fcAdd.getFunction(s.ctx, s.datumsToConstants(args))
  1867  		c.Assert(err, IsNil)
  1868  		c.Assert(f, NotNil)
  1869  		v, err = evalBuiltinFunc(f, chunk.Event{})
  1870  		c.Assert(err, IsNil)
  1871  		c.Assert(v.GetMysqlTime().String(), Equals, test.expected)
  1872  	}
  1873  
  1874  	testYears := []struct {
  1875  		input    string
  1876  		year     int
  1877  		expected string
  1878  	}{
  1879  		{"1899-02-28", 1, "1900-02-28"},
  1880  		{"1901-02-28", -1, "1900-02-28"},
  1881  		{"2000-02-29", 1, "2001-02-28"},
  1882  		{"2001-02-28", -1, "2000-02-28"},
  1883  		{"2004-02-29", 1, "2005-02-28"},
  1884  		{"2005-02-28", -1, "2004-02-28"},
  1885  	}
  1886  
  1887  	for _, test := range testYears {
  1888  		args = types.MakeCausets(test.input, test.year, "YEAR")
  1889  		f, err = fcAdd.getFunction(s.ctx, s.datumsToConstants(args))
  1890  		c.Assert(err, IsNil)
  1891  		c.Assert(f, NotNil)
  1892  		v, err = evalBuiltinFunc(f, chunk.Event{})
  1893  		c.Assert(err, IsNil)
  1894  		c.Assert(v.GetMysqlTime().String(), Equals, test.expected)
  1895  	}
  1896  
  1897  	testOverflowYears := []struct {
  1898  		input string
  1899  		year  int
  1900  	}{
  1901  		{"2008-11-23", -1465647104},
  1902  		{"2008-11-23", 1465647104},
  1903  	}
  1904  
  1905  	for _, test := range testOverflowYears {
  1906  		args = types.MakeCausets(test.input, test.year, "YEAR")
  1907  		f, err = fcAdd.getFunction(s.ctx, s.datumsToConstants(args))
  1908  		c.Assert(err, IsNil)
  1909  		c.Assert(f, NotNil)
  1910  		v, err = evalBuiltinFunc(f, chunk.Event{})
  1911  		c.Assert(err, IsNil)
  1912  		c.Assert(v.IsNull(), IsTrue)
  1913  	}
  1914  
  1915  	for _, test := range testOverflowYears {
  1916  		args = types.MakeCausets(test.input, test.year, "YEAR")
  1917  		f, err = fcSub.getFunction(s.ctx, s.datumsToConstants(args))
  1918  		c.Assert(err, IsNil)
  1919  		c.Assert(f, NotNil)
  1920  		v, err = evalBuiltinFunc(f, chunk.Event{})
  1921  		c.Assert(err, IsNil)
  1922  		c.Assert(v.IsNull(), IsTrue)
  1923  	}
  1924  
  1925  	testDurations := []struct {
  1926  		fc       functionClass
  1927  		dur      string
  1928  		fsp      int8
  1929  		unit     string
  1930  		format   interface{}
  1931  		expected string
  1932  	}{
  1933  		{
  1934  			fc:       fcAdd,
  1935  			dur:      "00:00:00",
  1936  			fsp:      0,
  1937  			unit:     "MICROSECOND",
  1938  			format:   "100",
  1939  			expected: "00:00:00.000100",
  1940  		},
  1941  		{
  1942  			fc:       fcAdd,
  1943  			dur:      "00:00:00",
  1944  			fsp:      0,
  1945  			unit:     "MICROSECOND",
  1946  			format:   100.0,
  1947  			expected: "00:00:00.000100",
  1948  		},
  1949  		{
  1950  			fc:       fcSub,
  1951  			dur:      "00:00:01",
  1952  			fsp:      0,
  1953  			unit:     "MICROSECOND",
  1954  			format:   "100",
  1955  			expected: "00:00:00.999900",
  1956  		},
  1957  		{
  1958  			fc:       fcAdd,
  1959  			dur:      "00:00:00",
  1960  			fsp:      0,
  1961  			unit:     "DAY",
  1962  			format:   "1",
  1963  			expected: "24:00:00",
  1964  		},
  1965  		{
  1966  			fc:       fcAdd,
  1967  			dur:      "00:00:00",
  1968  			fsp:      0,
  1969  			unit:     "SECOND",
  1970  			format:   1,
  1971  			expected: "00:00:01",
  1972  		},
  1973  		{
  1974  			fc:       fcAdd,
  1975  			dur:      "00:00:00",
  1976  			fsp:      0,
  1977  			unit:     "DAY",
  1978  			format:   types.NewDecFromInt(1),
  1979  			expected: "24:00:00",
  1980  		},
  1981  		{
  1982  			fc:       fcAdd,
  1983  			dur:      "00:00:00",
  1984  			fsp:      0,
  1985  			unit:     "DAY",
  1986  			format:   1.0,
  1987  			expected: "24:00:00",
  1988  		},
  1989  		{
  1990  			fc:       fcSub,
  1991  			dur:      "26:00:00",
  1992  			fsp:      0,
  1993  			unit:     "DAY",
  1994  			format:   "1",
  1995  			expected: "02:00:00",
  1996  		},
  1997  		{
  1998  			fc:       fcSub,
  1999  			dur:      "26:00:00",
  2000  			fsp:      0,
  2001  			unit:     "DAY",
  2002  			format:   1,
  2003  			expected: "02:00:00",
  2004  		},
  2005  		{
  2006  			fc:       fcSub,
  2007  			dur:      "26:00:00",
  2008  			fsp:      0,
  2009  			unit:     "SECOND",
  2010  			format:   types.NewDecFromInt(1),
  2011  			expected: "25:59:59",
  2012  		},
  2013  		{
  2014  			fc:       fcSub,
  2015  			dur:      "27:00:00",
  2016  			fsp:      0,
  2017  			unit:     "DAY",
  2018  			format:   1.0,
  2019  			expected: "03:00:00",
  2020  		},
  2021  	}
  2022  	for _, tt := range testDurations {
  2023  		dur, _, ok, err := types.StrToDuration(nil, tt.dur, tt.fsp)
  2024  		c.Assert(err, IsNil)
  2025  		c.Assert(ok, IsTrue)
  2026  		args = types.MakeCausets(dur, tt.format, tt.unit)
  2027  		f, err = tt.fc.getFunction(s.ctx, s.datumsToConstants(args))
  2028  		c.Assert(err, IsNil)
  2029  		c.Assert(f, NotNil)
  2030  		v, err = evalBuiltinFunc(f, chunk.Event{})
  2031  		c.Assert(err, IsNil)
  2032  		c.Assert(v.GetMysqlDuration().String(), Equals, tt.expected)
  2033  	}
  2034  }
  2035  
  2036  func (s *testEvaluatorSuite) TestTimestamp(c *C) {
  2037  	tests := []struct {
  2038  		t      []types.Causet
  2039  		expect string
  2040  	}{
  2041  		// one argument
  2042  		{[]types.Causet{types.NewStringCauset("2020-01-18")}, "2020-01-18 00:00:00"},
  2043  		{[]types.Causet{types.NewStringCauset("20170118")}, "2020-01-18 00:00:00"},
  2044  		{[]types.Causet{types.NewStringCauset("170118")}, "2020-01-18 00:00:00"},
  2045  		{[]types.Causet{types.NewStringCauset("20170118123056")}, "2020-01-18 12:30:56"},
  2046  		{[]types.Causet{types.NewStringCauset("2020-01-18 12:30:56")}, "2020-01-18 12:30:56"},
  2047  		{[]types.Causet{types.NewIntCauset(170118)}, "2020-01-18 00:00:00"},
  2048  		{[]types.Causet{types.NewFloat64Causet(20170118)}, "2020-01-18 00:00:00"},
  2049  		{[]types.Causet{types.NewStringCauset("20170118123050.999")}, "2020-01-18 12:30:50.999"},
  2050  		{[]types.Causet{types.NewStringCauset("20170118123050.1234567")}, "2020-01-18 12:30:50.123457"},
  2051  		// TODO: Parse int should use ParseTimeFromNum, rather than convert int to string for parsing.
  2052  		// {[]types.Causet{types.NewIntCauset(11111111111)}, "2001-11-11 11:11:11"},
  2053  		{[]types.Causet{types.NewStringCauset("11111111111")}, "2011-11-11 11:11:01"},
  2054  		{[]types.Causet{types.NewFloat64Causet(20170118.999)}, "2020-01-18 00:00:00.000"},
  2055  
  2056  		// two arguments
  2057  		{[]types.Causet{types.NewStringCauset("2020-01-18"), types.NewStringCauset("12:30:59")}, "2020-01-18 12:30:59"},
  2058  		{[]types.Causet{types.NewStringCauset("2020-01-18"), types.NewStringCauset("12:30:59")}, "2020-01-18 12:30:59"},
  2059  		{[]types.Causet{types.NewStringCauset("2020-01-18 01:01:01"), types.NewStringCauset("12:30:50")}, "2020-01-18 13:31:51"},
  2060  		{[]types.Causet{types.NewStringCauset("2020-01-18 01:01:01"), types.NewStringCauset("838:59:59")}, "2020-02-22 00:01:00"},
  2061  
  2062  		{[]types.Causet{types.NewDecimalCauset(types.NewDecFromStringForTest("20170118123950.123"))}, "2020-01-18 12:39:50.123"},
  2063  		{[]types.Causet{types.NewDecimalCauset(types.NewDecFromStringForTest("20170118123950.999"))}, "2020-01-18 12:39:50.999"},
  2064  		{[]types.Causet{types.NewDecimalCauset(types.NewDecFromStringForTest("20170118123950.999"))}, "2020-01-18 12:39:50.999"},
  2065  	}
  2066  	fc := funcs[ast.Timestamp]
  2067  	for _, test := range tests {
  2068  		resetStmtContext(s.ctx)
  2069  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(test.t))
  2070  		c.Assert(err, IsNil)
  2071  		d, err := evalBuiltinFunc(f, chunk.Event{})
  2072  		c.Assert(err, IsNil)
  2073  		result, _ := d.ToString()
  2074  		c.Assert(result, Equals, test.expect)
  2075  	}
  2076  
  2077  	nilCauset := types.NewCauset(nil)
  2078  	resetStmtContext(s.ctx)
  2079  	f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{nilCauset}))
  2080  	c.Assert(err, IsNil)
  2081  	d, err := evalBuiltinFunc(f, chunk.Event{})
  2082  	c.Assert(err, IsNil)
  2083  	c.Assert(d.HoTT(), Equals, types.HoTTNull)
  2084  }
  2085  
  2086  func (s *testEvaluatorSuite) TestMakeDate(c *C) {
  2087  	cases := []struct {
  2088  		args     []interface{}
  2089  		expected string
  2090  		isNil    bool
  2091  		getErr   bool
  2092  	}{
  2093  		{[]interface{}{71, 1}, "1971-01-01", false, false},
  2094  		{[]interface{}{71.1, 1.89}, "1971-01-02", false, false},
  2095  		{[]interface{}{99, 1}, "1999-01-01", false, false},
  2096  		{[]interface{}{100, 1}, "0100-01-01", false, false},
  2097  		{[]interface{}{69, 1}, "2069-01-01", false, false},
  2098  		{[]interface{}{70, 1}, "1970-01-01", false, false},
  2099  		{[]interface{}{1000, 1}, "1000-01-01", false, false},
  2100  		{[]interface{}{-1, 3660}, "", true, false},
  2101  		{[]interface{}{10000, 3660}, "", true, false},
  2102  		{[]interface{}{2060, 2900025}, "9999-12-31", false, false},
  2103  		{[]interface{}{2060, 2900026}, "", true, false},
  2104  		{[]interface{}{"71", 1}, "1971-01-01", false, false},
  2105  		{[]interface{}{71, "1"}, "1971-01-01", false, false},
  2106  		{[]interface{}{"71", "1"}, "1971-01-01", false, false},
  2107  		{[]interface{}{nil, 2900025}, "", true, false},
  2108  		{[]interface{}{2060, nil}, "", true, false},
  2109  		{[]interface{}{nil, nil}, "", true, false},
  2110  		{[]interface{}{errors.New("must error"), errors.New("must error")}, "", false, true},
  2111  	}
  2112  
  2113  	for _, t := range cases {
  2114  		f, err := newFunctionForTest(s.ctx, ast.MakeDate, s.primitiveValsToConstants(t.args)...)
  2115  		c.Assert(err, IsNil)
  2116  		tp := f.GetType()
  2117  		c.Assert(tp.Tp, Equals, allegrosql.TypeDate)
  2118  		c.Assert(tp.Charset, Equals, charset.CharsetBin)
  2119  		c.Assert(tp.DefCauslate, Equals, charset.DefCauslationBin)
  2120  		c.Assert(tp.Flag, Equals, allegrosql.BinaryFlag)
  2121  		c.Assert(tp.Flen, Equals, allegrosql.MaxDateWidth)
  2122  		d, err := f.Eval(chunk.Event{})
  2123  		if t.getErr {
  2124  			c.Assert(err, NotNil)
  2125  		} else {
  2126  			c.Assert(err, IsNil)
  2127  			if t.isNil {
  2128  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
  2129  			} else {
  2130  				c.Assert(d.GetMysqlTime().String(), Equals, t.expected)
  2131  			}
  2132  		}
  2133  	}
  2134  
  2135  	_, err := funcs[ast.MakeDate].getFunction(s.ctx, []Expression{NewZero(), NewZero()})
  2136  	c.Assert(err, IsNil)
  2137  }
  2138  
  2139  func (s *testEvaluatorSuite) TestMakeTime(c *C) {
  2140  	tbl := []struct {
  2141  		Args []interface{}
  2142  		Want interface{}
  2143  	}{
  2144  		{[]interface{}{12, 15, 30}, "12:15:30"},
  2145  		{[]interface{}{25, 15, 30}, "25:15:30"},
  2146  		{[]interface{}{-25, 15, 30}, "-25:15:30"},
  2147  		{[]interface{}{12, -15, 30}, nil},
  2148  		{[]interface{}{12, 15, -30}, nil},
  2149  
  2150  		{[]interface{}{12, 15, "30.10"}, "12:15:30.100000"},
  2151  		{[]interface{}{12, 15, "30.20"}, "12:15:30.200000"},
  2152  		{[]interface{}{12, 15, 30.3000001}, "12:15:30.300000"},
  2153  		{[]interface{}{12, 15, 30.0000005}, "12:15:30.000001"},
  2154  		{[]interface{}{"12", "15", 30.1}, "12:15:30.100000"},
  2155  
  2156  		{[]interface{}{0, 58.4, 0}, "00:58:00"},
  2157  		{[]interface{}{0, "58.4", 0}, "00:58:00"},
  2158  		{[]interface{}{0, 58.5, 1}, "00:59:01"},
  2159  		{[]interface{}{0, "58.5", 1}, "00:58:01"},
  2160  		{[]interface{}{0, 59.5, 1}, nil},
  2161  		{[]interface{}{0, "59.5", 1}, "00:59:01"},
  2162  		{[]interface{}{0, 1, 59.1}, "00:01:59.100000"},
  2163  		{[]interface{}{0, 1, "59.1"}, "00:01:59.100000"},
  2164  		{[]interface{}{0, 1, 59.5}, "00:01:59.500000"},
  2165  		{[]interface{}{0, 1, "59.5"}, "00:01:59.500000"},
  2166  		{[]interface{}{23.5, 1, 10}, "24:01:10"},
  2167  		{[]interface{}{"23.5", 1, 10}, "23:01:10"},
  2168  
  2169  		{[]interface{}{0, 0, 0}, "00:00:00"},
  2170  
  2171  		{[]interface{}{837, 59, 59.1}, "837:59:59.100000"},
  2172  		{[]interface{}{838, 59, 59.1}, "838:59:59.000000"},
  2173  		{[]interface{}{-838, 59, 59.1}, "-838:59:59.000000"},
  2174  		{[]interface{}{1000, 1, 1}, "838:59:59"},
  2175  		{[]interface{}{-1000, 1, 1.23}, "-838:59:59.000000"},
  2176  		{[]interface{}{1000, 59.1, 1}, "838:59:59"},
  2177  		{[]interface{}{1000, 59.5, 1}, nil},
  2178  		{[]interface{}{1000, 1, 59.1}, "838:59:59.000000"},
  2179  		{[]interface{}{1000, 1, 59.5}, "838:59:59.000000"},
  2180  
  2181  		{[]interface{}{12, 15, 60}, nil},
  2182  		{[]interface{}{12, 15, "60"}, nil},
  2183  		{[]interface{}{12, 60, 0}, nil},
  2184  		{[]interface{}{12, "60", 0}, nil},
  2185  
  2186  		{[]interface{}{12, 15, nil}, nil},
  2187  		{[]interface{}{12, nil, 0}, nil},
  2188  		{[]interface{}{nil, 15, 0}, nil},
  2189  		{[]interface{}{nil, nil, nil}, nil},
  2190  	}
  2191  
  2192  	Dtbl := tblToDtbl(tbl)
  2193  	maketime := funcs[ast.MakeTime]
  2194  	for idx, t := range Dtbl {
  2195  		f, err := maketime.getFunction(s.ctx, s.datumsToConstants(t["Args"]))
  2196  		c.Assert(err, IsNil)
  2197  		got, err := evalBuiltinFunc(f, chunk.Event{})
  2198  		c.Assert(err, IsNil)
  2199  		if t["Want"][0].HoTT() == types.HoTTNull {
  2200  			c.Assert(got.HoTT(), Equals, types.HoTTNull, Commentf("[%v] - args:%v", idx, t["Args"]))
  2201  		} else {
  2202  			want, err := t["Want"][0].ToString()
  2203  			c.Assert(err, IsNil)
  2204  			c.Assert(got.GetMysqlDuration().String(), Equals, want, Commentf("[%v] - args:%v", idx, t["Args"]))
  2205  		}
  2206  	}
  2207  
  2208  	// MAKETIME(CAST(-1 AS UNSIGNED),0,0);
  2209  	tp1 := &types.FieldType{
  2210  		Tp:      allegrosql.TypeLonglong,
  2211  		Flag:    allegrosql.UnsignedFlag,
  2212  		Charset: charset.CharsetBin,
  2213  		DefCauslate: charset.DefCauslationBin,
  2214  		Flen:    allegrosql.MaxIntWidth,
  2215  	}
  2216  	f := BuildCastFunction(s.ctx, &Constant{Value: types.NewCauset("-1"), RetType: types.NewFieldType(allegrosql.TypeString)}, tp1)
  2217  	res, err := f.Eval(chunk.Event{})
  2218  	c.Assert(err, IsNil)
  2219  	f1, err := maketime.getFunction(s.ctx, s.datumsToConstants([]types.Causet{res, makeCausets(0)[0], makeCausets(0)[0]}))
  2220  	c.Assert(err, IsNil)
  2221  	got, err := evalBuiltinFunc(f1, chunk.Event{})
  2222  	c.Assert(err, IsNil)
  2223  	c.Assert(got.GetMysqlDuration().String(), Equals, "838:59:59")
  2224  
  2225  	tbl = []struct {
  2226  		Args []interface{}
  2227  		Want interface{}
  2228  	}{
  2229  		{[]interface{}{"", "", ""}, "00:00:00.000000"},
  2230  		{[]interface{}{"h", "m", "s"}, "00:00:00.000000"},
  2231  	}
  2232  	Dtbl = tblToDtbl(tbl)
  2233  	maketime = funcs[ast.MakeTime]
  2234  	for idx, t := range Dtbl {
  2235  		f, err := maketime.getFunction(s.ctx, s.datumsToConstants(t["Args"]))
  2236  		c.Assert(err, IsNil)
  2237  		got, err := evalBuiltinFunc(f, chunk.Event{})
  2238  		c.Assert(err, IsNil)
  2239  		want, err := t["Want"][0].ToString()
  2240  		c.Assert(err, IsNil)
  2241  		c.Assert(got.GetMysqlDuration().String(), Equals, want, Commentf("[%v] - args:%v", idx, t["Args"]))
  2242  	}
  2243  }
  2244  
  2245  func (s *testEvaluatorSuite) TestQuarter(c *C) {
  2246  	sc := s.ctx.GetStochastikVars().StmtCtx
  2247  	sc.IgnoreZeroInDate = true
  2248  	tests := []struct {
  2249  		t      string
  2250  		expect int64
  2251  	}{
  2252  		// Test case from https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_quarter
  2253  		{"2008-04-01", 2},
  2254  		// Test case for boundary values
  2255  		{"2008-01-01", 1},
  2256  		{"2008-03-31", 1},
  2257  		{"2008-06-30", 2},
  2258  		{"2008-07-01", 3},
  2259  		{"2008-09-30", 3},
  2260  		{"2008-10-01", 4},
  2261  		{"2008-12-31", 4},
  2262  		// Test case for month 0
  2263  		{"2008-00-01", 0},
  2264  	}
  2265  	fc := funcs["quarter"]
  2266  	for _, test := range tests {
  2267  		arg := types.NewStringCauset(test.t)
  2268  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{arg}))
  2269  		c.Assert(err, IsNil)
  2270  		c.Assert(f, NotNil)
  2271  		result, err := evalBuiltinFunc(f, chunk.Event{})
  2272  		c.Assert(err, IsNil)
  2273  		c.Assert(result.GetInt64(), Equals, test.expect)
  2274  	}
  2275  
  2276  	// test invalid input
  2277  	argInvalid := types.NewStringCauset("2008-13-01")
  2278  	f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{argInvalid}))
  2279  	c.Assert(err, IsNil)
  2280  	result, err := evalBuiltinFunc(f, chunk.Event{})
  2281  	c.Assert(err, IsNil)
  2282  	c.Assert(result.IsNull(), IsTrue)
  2283  }
  2284  
  2285  func (s *testEvaluatorSuite) TestGetFormat(c *C) {
  2286  	tests := []struct {
  2287  		unit     string
  2288  		location string
  2289  		expect   string
  2290  	}{
  2291  		{"DATE", "USA", `%m.%d.%Y`},
  2292  		{"DATE", "JIS", `%Y-%m-%d`},
  2293  		{"DATE", "ISO", `%Y-%m-%d`},
  2294  		{"DATE", "EUR", `%d.%m.%Y`},
  2295  		{"DATE", "INTERNAL", `%Y%m%d`},
  2296  
  2297  		{"DATETIME", "USA", `%Y-%m-%d %H.%i.%s`},
  2298  		{"DATETIME", "JIS", `%Y-%m-%d %H:%i:%s`},
  2299  		{"DATETIME", "ISO", `%Y-%m-%d %H:%i:%s`},
  2300  		{"DATETIME", "EUR", `%Y-%m-%d %H.%i.%s`},
  2301  		{"DATETIME", "INTERNAL", `%Y%m%d%H%i%s`},
  2302  
  2303  		{"TIME", "USA", `%h:%i:%s %p`},
  2304  		{"TIME", "JIS", `%H:%i:%s`},
  2305  		{"TIME", "ISO", `%H:%i:%s`},
  2306  		{"TIME", "EUR", `%H.%i.%s`},
  2307  		{"TIME", "INTERNAL", `%H%i%s`},
  2308  	}
  2309  
  2310  	fc := funcs[ast.GetFormat]
  2311  	for _, test := range tests {
  2312  		t := []types.Causet{types.NewStringCauset(test.unit), types.NewStringCauset(test.location)}
  2313  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t))
  2314  		c.Assert(err, IsNil)
  2315  		d, err := evalBuiltinFunc(f, chunk.Event{})
  2316  		c.Assert(err, IsNil)
  2317  		result, _ := d.ToString()
  2318  		c.Assert(result, Equals, test.expect)
  2319  	}
  2320  }
  2321  
  2322  func (s *testEvaluatorSuite) TestToSeconds(c *C) {
  2323  	sc := s.ctx.GetStochastikVars().StmtCtx
  2324  	sc.IgnoreZeroInDate = true
  2325  	tests := []struct {
  2326  		param  interface{}
  2327  		expect int64
  2328  	}{
  2329  		{950501, 62966505600},
  2330  		{"2009-11-29", 63426672000},
  2331  		{"2009-11-29 13:43:32", 63426721412},
  2332  		{"09-11-29 13:43:32", 63426721412},
  2333  		{"99-11-29 13:43:32", 63111102212},
  2334  	}
  2335  
  2336  	fc := funcs[ast.ToSeconds]
  2337  	for _, test := range tests {
  2338  		t := []types.Causet{types.NewCauset(test.param)}
  2339  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t))
  2340  		c.Assert(err, IsNil)
  2341  		d, err := evalBuiltinFunc(f, chunk.Event{})
  2342  		c.Assert(err, IsNil)
  2343  		c.Assert(d.GetInt64(), Equals, test.expect)
  2344  	}
  2345  
  2346  	testsNull := []interface{}{
  2347  		"0000-00-00",
  2348  		"1992-13-00",
  2349  		"2007-10-07 23:59:61",
  2350  		123456789}
  2351  
  2352  	for _, i := range testsNull {
  2353  		t := []types.Causet{types.NewCauset(i)}
  2354  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t))
  2355  		c.Assert(err, IsNil)
  2356  		d, err := evalBuiltinFunc(f, chunk.Event{})
  2357  		c.Assert(err, IsNil)
  2358  		c.Assert(d.IsNull(), IsTrue)
  2359  	}
  2360  }
  2361  
  2362  func (s *testEvaluatorSuite) TestToDays(c *C) {
  2363  	sc := s.ctx.GetStochastikVars().StmtCtx
  2364  	sc.IgnoreZeroInDate = true
  2365  	tests := []struct {
  2366  		param  interface{}
  2367  		expect int64
  2368  	}{
  2369  		{950501, 728779},
  2370  		{"2007-10-07", 733321},
  2371  		{"2008-10-07", 733687},
  2372  		{"08-10-07", 733687},
  2373  		{"0000-01-01", 1},
  2374  		{"2007-10-07 00:00:59", 733321},
  2375  	}
  2376  
  2377  	fc := funcs[ast.ToDays]
  2378  	for _, test := range tests {
  2379  		t := []types.Causet{types.NewCauset(test.param)}
  2380  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t))
  2381  		c.Assert(err, IsNil)
  2382  		d, err := evalBuiltinFunc(f, chunk.Event{})
  2383  		c.Assert(err, IsNil)
  2384  		c.Assert(d.GetInt64(), Equals, test.expect)
  2385  	}
  2386  
  2387  	testsNull := []interface{}{
  2388  		"0000-00-00",
  2389  		"1992-13-00",
  2390  		"2007-10-07 23:59:61",
  2391  		123456789}
  2392  
  2393  	for _, i := range testsNull {
  2394  		t := []types.Causet{types.NewCauset(i)}
  2395  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t))
  2396  		c.Assert(err, IsNil)
  2397  		d, err := evalBuiltinFunc(f, chunk.Event{})
  2398  		c.Assert(err, IsNil)
  2399  		c.Assert(d.IsNull(), IsTrue)
  2400  	}
  2401  }
  2402  
  2403  func (s *testEvaluatorSuite) TestTimestampAdd(c *C) {
  2404  	tests := []struct {
  2405  		unit     string
  2406  		interval int64
  2407  		date     interface{}
  2408  		expect   string
  2409  	}{
  2410  		{"MINUTE", 1, "2003-01-02", "2003-01-02 00:01:00"},
  2411  		{"WEEK", 1, "2003-01-02 23:59:59", "2003-01-09 23:59:59"},
  2412  		{"MICROSECOND", 1, 950501, "1995-05-01 00:00:00.000001"},
  2413  	}
  2414  
  2415  	fc := funcs[ast.TimestampAdd]
  2416  	for _, test := range tests {
  2417  		t := []types.Causet{types.NewStringCauset(test.unit), types.NewIntCauset(test.interval), types.NewCauset(test.date)}
  2418  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t))
  2419  		c.Assert(err, IsNil)
  2420  		d, err := evalBuiltinFunc(f, chunk.Event{})
  2421  		c.Assert(err, IsNil)
  2422  		result, _ := d.ToString()
  2423  		c.Assert(result, Equals, test.expect)
  2424  	}
  2425  }
  2426  
  2427  func (s *testEvaluatorSuite) TestPeriodAdd(c *C) {
  2428  	tests := []struct {
  2429  		Period  int64
  2430  		Months  int64
  2431  		Success bool
  2432  		Expect  int64
  2433  	}{
  2434  		{201611, 2, true, 201701},
  2435  		{201611, 3, true, 201702},
  2436  		{201611, -13, true, 201510},
  2437  		{1611, 3, true, 201702},
  2438  		{7011, 3, true, 197102},
  2439  		{12323, 10, false, 0},
  2440  		{0, 3, false, 0},
  2441  	}
  2442  
  2443  	fc := funcs[ast.PeriodAdd]
  2444  	for _, test := range tests {
  2445  		period := types.NewIntCauset(test.Period)
  2446  		months := types.NewIntCauset(test.Months)
  2447  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{period, months}))
  2448  		c.Assert(err, IsNil)
  2449  		c.Assert(f, NotNil)
  2450  		result, err := evalBuiltinFunc(f, chunk.Event{})
  2451  		if !test.Success {
  2452  			c.Assert(result.IsNull(), IsTrue)
  2453  			continue
  2454  		}
  2455  		c.Assert(err, IsNil)
  2456  		c.Assert(result.HoTT(), Equals, types.HoTTInt64)
  2457  		value := result.GetInt64()
  2458  		c.Assert(value, Equals, test.Expect)
  2459  	}
  2460  }
  2461  
  2462  func (s *testEvaluatorSuite) TestTimeFormat(c *C) {
  2463  	// SELECT TIME_FORMAT(null,'%H %k %h %I %l')
  2464  	args := []types.Causet{types.NewCauset(nil), types.NewStringCauset(`%H %k %h %I %l`)}
  2465  	fc := funcs[ast.TimeFormat]
  2466  	f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
  2467  	c.Assert(err, IsNil)
  2468  	v, err := evalBuiltinFunc(f, chunk.Event{})
  2469  	c.Assert(err, IsNil)
  2470  	c.Assert(v.IsNull(), Equals, true)
  2471  
  2472  	tblDate := []struct {
  2473  		Input  []string
  2474  		Expect interface{}
  2475  	}{
  2476  		{[]string{"23:00:00", `%H %k %h %I %l`},
  2477  			"23 23 11 11 11"},
  2478  		{[]string{"11:00:00", `%H %k %h %I %l`},
  2479  			"11 11 11 11 11"},
  2480  		{[]string{"17:42:03.000001", `%r %T %h:%i%p %h:%i:%s %p %H %i %s`},
  2481  			"05:42:03 PM 17:42:03 05:42PM 05:42:03 PM 17 42 03"},
  2482  		{[]string{"07:42:03.000001", `%f`},
  2483  			"000001"},
  2484  		{[]string{"1990-05-07 19:30:10", `%H %i %s`},
  2485  			"19 30 10"},
  2486  	}
  2487  	dtblDate := tblToDtbl(tblDate)
  2488  	for i, t := range dtblDate {
  2489  		fc := funcs[ast.TimeFormat]
  2490  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
  2491  		c.Assert(err, IsNil)
  2492  		v, err := evalBuiltinFunc(f, chunk.Event{})
  2493  		c.Assert(err, IsNil)
  2494  		c.Assert(v, solitonutil.CausetEquals, t["Expect"][0], Commentf(`no.%d \nobtain:%v \nexpect:%v\n`, i,
  2495  			v.GetValue(), t["Expect"][0].GetValue()))
  2496  	}
  2497  }
  2498  
  2499  func (s *testEvaluatorSuite) TestTimeToSec(c *C) {
  2500  	fc := funcs[ast.TimeToSec]
  2501  
  2502  	// test nil
  2503  	nilCauset := types.NewCauset(nil)
  2504  	f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{nilCauset}))
  2505  	c.Assert(err, IsNil)
  2506  	d, err := evalBuiltinFunc(f, chunk.Event{})
  2507  	c.Assert(err, IsNil)
  2508  	c.Assert(d.HoTT(), Equals, types.HoTTNull)
  2509  
  2510  	// TODO: Some test cases are commented out due to #4340, #4341.
  2511  	tests := []struct {
  2512  		input  types.Causet
  2513  		expect int64
  2514  	}{
  2515  		{types.NewStringCauset("22:23:00"), 80580},
  2516  		{types.NewStringCauset("00:39:38"), 2378},
  2517  		{types.NewStringCauset("23:00"), 82800},
  2518  		{types.NewStringCauset("00:00"), 0},
  2519  		{types.NewStringCauset("00:00:00"), 0},
  2520  		{types.NewStringCauset("23:59:59"), 86399},
  2521  		{types.NewStringCauset("1:0"), 3600},
  2522  		{types.NewStringCauset("1:00"), 3600},
  2523  		{types.NewStringCauset("1:0:0"), 3600},
  2524  		{types.NewStringCauset("-02:00"), -7200},
  2525  		{types.NewStringCauset("-02:00:05"), -7205},
  2526  		{types.NewStringCauset("020005"), 7205},
  2527  		// {types.NewStringCauset("20171222020005"), 7205},
  2528  		// {types.NewIntCauset(020005), 7205},
  2529  		// {types.NewIntCauset(20171222020005), 7205},
  2530  		// {types.NewIntCauset(171222020005), 7205},
  2531  	}
  2532  	for _, test := range tests {
  2533  		expr := s.datumsToConstants([]types.Causet{test.input})
  2534  		f, err := fc.getFunction(s.ctx, expr)
  2535  		c.Assert(err, IsNil, Commentf("%+v", test))
  2536  		result, err := evalBuiltinFunc(f, chunk.Event{})
  2537  		c.Assert(err, IsNil, Commentf("%+v", test))
  2538  		c.Assert(result.GetInt64(), Equals, test.expect, Commentf("%+v", test))
  2539  	}
  2540  }
  2541  
  2542  func (s *testEvaluatorSuite) TestSecToTime(c *C) {
  2543  	stmtCtx := s.ctx.GetStochastikVars().StmtCtx
  2544  	origin := stmtCtx.IgnoreTruncate
  2545  	stmtCtx.IgnoreTruncate = true
  2546  	defer func() {
  2547  		stmtCtx.IgnoreTruncate = origin
  2548  	}()
  2549  
  2550  	fc := funcs[ast.SecToTime]
  2551  
  2552  	// test nil
  2553  	nilCauset := types.NewCauset(nil)
  2554  	f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{nilCauset}))
  2555  	c.Assert(err, IsNil)
  2556  	d, err := evalBuiltinFunc(f, chunk.Event{})
  2557  	c.Assert(err, IsNil)
  2558  	c.Assert(d.HoTT(), Equals, types.HoTTNull)
  2559  
  2560  	tests := []struct {
  2561  		inputDecimal int
  2562  		input        types.Causet
  2563  		expect       string
  2564  	}{
  2565  		{0, types.NewIntCauset(2378), "00:39:38"},
  2566  		{0, types.NewIntCauset(3864000), "838:59:59"},
  2567  		{0, types.NewIntCauset(-3864000), "-838:59:59"},
  2568  		{1, types.NewFloat64Causet(86401.4), "24:00:01.4"},
  2569  		{1, types.NewFloat64Causet(-86401.4), "-24:00:01.4"},
  2570  		{5, types.NewFloat64Causet(86401.54321), "24:00:01.54321"},
  2571  		{-1, types.NewFloat64Causet(86401.54321), "24:00:01.543210"},
  2572  		{0, types.NewStringCauset("123.4"), "00:02:03.400000"},
  2573  		{0, types.NewStringCauset("123.4567891"), "00:02:03.456789"},
  2574  		{0, types.NewStringCauset("123"), "00:02:03.000000"},
  2575  		{0, types.NewStringCauset("abc"), "00:00:00.000000"},
  2576  	}
  2577  	for _, test := range tests {
  2578  		expr := s.datumsToConstants([]types.Causet{test.input})
  2579  		expr[0].GetType().Decimal = test.inputDecimal
  2580  		f, err := fc.getFunction(s.ctx, expr)
  2581  		c.Assert(err, IsNil, Commentf("%+v", test))
  2582  		d, err := evalBuiltinFunc(f, chunk.Event{})
  2583  		c.Assert(err, IsNil, Commentf("%+v", test))
  2584  		result, _ := d.ToString()
  2585  		c.Assert(result, Equals, test.expect, Commentf("%+v", test))
  2586  	}
  2587  }
  2588  
  2589  func (s *testEvaluatorSuite) TestConvertTz(c *C) {
  2590  	tests := []struct {
  2591  		t       interface{}
  2592  		fromTz  interface{}
  2593  		toTz    interface{}
  2594  		Success bool
  2595  		expect  string
  2596  	}{
  2597  		{"2004-01-01 12:00:00.111", "-00:00", "+12:34", true, "2004-01-02 00:34:00.111"},
  2598  		{"2004-01-01 12:00:00.11", "+00:00", "+12:34", true, "2004-01-02 00:34:00.11"},
  2599  		{"2004-01-01 12:00:00.11111111111", "-00:00", "+12:34", true, "2004-01-02 00:34:00.111111"},
  2600  		{"2004-01-01 12:00:00", "GMT", "MET", true, "2004-01-01 13:00:00"},
  2601  		{"2004-01-01 12:00:00", "-01:00", "-12:00", true, "2004-01-01 01:00:00"},
  2602  		{"2004-01-01 12:00:00", "-00:00", "+13:00", true, "2004-01-02 01:00:00"},
  2603  		{"2004-01-01 12:00:00", "-00:00", "-13:00", true, ""},
  2604  		{"2004-01-01 12:00:00", "-00:00", "-12:88", true, ""},
  2605  		{"2004-01-01 12:00:00", "+10:82", "GMT", true, ""},
  2606  		{"2004-01-01 12:00:00", "+00:00", "GMT", true, ""},
  2607  		{"2004-01-01 12:00:00", "GMT", "+00:00", true, ""},
  2608  		{20040101, "+00:00", "+10:32", true, "2004-01-01 10:32:00"},
  2609  		{3.14159, "+00:00", "+10:32", true, ""},
  2610  		{"2004-01-01 12:00:00", "", "GMT", true, ""},
  2611  		{"2004-01-01 12:00:00", "GMT", "", true, ""},
  2612  		{"2004-01-01 12:00:00", "a", "GMT", true, ""},
  2613  		{"2004-01-01 12:00:00", "0", "GMT", true, ""},
  2614  		{"2004-01-01 12:00:00", "GMT", "a", true, ""},
  2615  		{"2004-01-01 12:00:00", "GMT", "0", true, ""},
  2616  		{nil, "GMT", "+00:00", true, ""},
  2617  		{"2004-01-01 12:00:00", nil, "+00:00", true, ""},
  2618  		{"2004-01-01 12:00:00", "GMT", nil, true, ""},
  2619  	}
  2620  	fc := funcs[ast.ConvertTz]
  2621  	for _, test := range tests {
  2622  		f, err := fc.getFunction(s.ctx,
  2623  			s.datumsToConstants(
  2624  				[]types.Causet{
  2625  					types.NewCauset(test.t),
  2626  					types.NewCauset(test.fromTz),
  2627  					types.NewCauset(test.toTz)}))
  2628  		c.Assert(err, IsNil)
  2629  		d, err := evalBuiltinFunc(f, chunk.Event{})
  2630  		if test.Success {
  2631  			c.Assert(err, IsNil)
  2632  		} else {
  2633  			c.Assert(err, NotNil)
  2634  		}
  2635  		result, _ := d.ToString()
  2636  		c.Assert(result, Equals, test.expect, Commentf("convert_tz(\"%v\", \"%s\", \"%s\")", test.t, test.fromTz, test.toTz))
  2637  	}
  2638  }
  2639  
  2640  func (s *testEvaluatorSuite) TestPeriodDiff(c *C) {
  2641  	tests := []struct {
  2642  		Period1 int64
  2643  		Period2 int64
  2644  		Success bool
  2645  		Expect  int64
  2646  	}{
  2647  		{201611, 201611, true, 0},
  2648  		{200802, 200703, true, 11},
  2649  		{201701, 201611, true, 2},
  2650  		{201702, 201611, true, 3},
  2651  		{201510, 201611, true, -13},
  2652  		{201702, 1611, true, 3},
  2653  		{197102, 7011, true, 3},
  2654  	}
  2655  
  2656  	tests2 := []struct {
  2657  		Period1 int64
  2658  		Period2 int64
  2659  	}{
  2660  		{0, 999999999},
  2661  		{9999999, 0},
  2662  		{411, 200413},
  2663  		{197000, 207700},
  2664  		{12509, 12323},
  2665  		{12509, 12323},
  2666  	}
  2667  	fc := funcs[ast.PeriodDiff]
  2668  	for _, test := range tests {
  2669  		period1 := types.NewIntCauset(test.Period1)
  2670  		period2 := types.NewIntCauset(test.Period2)
  2671  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{period1, period2}))
  2672  		c.Assert(err, IsNil)
  2673  		c.Assert(f, NotNil)
  2674  		result, err := evalBuiltinFunc(f, chunk.Event{})
  2675  		if !test.Success {
  2676  			c.Assert(result.IsNull(), IsTrue)
  2677  			continue
  2678  		}
  2679  		c.Assert(err, IsNil)
  2680  		c.Assert(result.HoTT(), Equals, types.HoTTInt64)
  2681  		value := result.GetInt64()
  2682  		c.Assert(value, Equals, test.Expect)
  2683  	}
  2684  
  2685  	for _, test := range tests2 {
  2686  		period1 := types.NewIntCauset(test.Period1)
  2687  		period2 := types.NewIntCauset(test.Period2)
  2688  		f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{period1, period2}))
  2689  		c.Assert(err, IsNil)
  2690  		c.Assert(f, NotNil)
  2691  		_, err = evalBuiltinFunc(f, chunk.Event{})
  2692  		c.Assert(err, NotNil)
  2693  		c.Assert(err.Error(), Equals, "[memex:1210]Incorrect arguments to period_diff")
  2694  	}
  2695  
  2696  	// nil
  2697  	args := []types.Causet{types.NewCauset(nil), types.NewIntCauset(0)}
  2698  	f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
  2699  	c.Assert(err, IsNil)
  2700  	v, err := evalBuiltinFunc(f, chunk.Event{})
  2701  	c.Assert(err, IsNil)
  2702  	c.Assert(v.HoTT(), Equals, types.HoTTNull)
  2703  
  2704  	args = []types.Causet{types.NewIntCauset(0), types.NewCauset(nil)}
  2705  	f, err = fc.getFunction(s.ctx, s.datumsToConstants(args))
  2706  	c.Assert(err, IsNil)
  2707  	v, err = evalBuiltinFunc(f, chunk.Event{})
  2708  	c.Assert(err, IsNil)
  2709  	c.Assert(v.HoTT(), Equals, types.HoTTNull)
  2710  }
  2711  
  2712  func (s *testEvaluatorSuite) TestLastDay(c *C) {
  2713  	tests := []struct {
  2714  		param  interface{}
  2715  		expect string
  2716  	}{
  2717  		{"2003-02-05", "2003-02-28"},
  2718  		{"2004-02-05", "2004-02-29"},
  2719  		{"2004-01-01 01:01:01", "2004-01-31"},
  2720  		{950501, "1995-05-31"},
  2721  	}
  2722  
  2723  	fc := funcs[ast.LastDay]
  2724  	for _, test := range tests {
  2725  		t := []types.Causet{types.NewCauset(test.param)}
  2726  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t))
  2727  		c.Assert(err, IsNil)
  2728  		d, err := evalBuiltinFunc(f, chunk.Event{})
  2729  		c.Assert(err, IsNil)
  2730  		result, _ := d.ToString()
  2731  		c.Assert(result, Equals, test.expect)
  2732  	}
  2733  
  2734  	testsNull := []interface{}{
  2735  		"0000-00-00",
  2736  		"1992-13-00",
  2737  		"2007-10-07 23:59:61",
  2738  		"2005-00-00",
  2739  		"2005-00-01",
  2740  		"2243-01 00:00:00",
  2741  		123456789}
  2742  
  2743  	for _, i := range testsNull {
  2744  		t := []types.Causet{types.NewCauset(i)}
  2745  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t))
  2746  		c.Assert(err, IsNil)
  2747  		d, err := evalBuiltinFunc(f, chunk.Event{})
  2748  		c.Assert(err, IsNil)
  2749  		c.Assert(d.IsNull(), IsTrue)
  2750  	}
  2751  }
  2752  
  2753  func (s *testEvaluatorSuite) TestWithTimeZone(c *C) {
  2754  	sv := s.ctx.GetStochastikVars()
  2755  	originTZ := sv.Location()
  2756  	sv.TimeZone, _ = time.LoadLocation("Asia/Tokyo")
  2757  	defer func() {
  2758  		sv.TimeZone = originTZ
  2759  	}()
  2760  
  2761  	timeToGoTime := func(d types.Causet, loc *time.Location) time.Time {
  2762  		result, _ := d.GetMysqlTime().GoTime(loc)
  2763  		return result
  2764  	}
  2765  	durationToGoTime := func(d types.Causet, loc *time.Location) time.Time {
  2766  		t, _ := d.GetMysqlDuration().ConvertToTime(sv.StmtCtx, allegrosql.TypeDatetime)
  2767  		result, _ := t.GoTime(sv.TimeZone)
  2768  		return result
  2769  	}
  2770  
  2771  	tests := []struct {
  2772  		method        string
  2773  		Input         []types.Causet
  2774  		convertToTime func(types.Causet, *time.Location) time.Time
  2775  	}{
  2776  		{ast.Sysdate, makeCausets(2), timeToGoTime},
  2777  		{ast.Sysdate, nil, timeToGoTime},
  2778  		{ast.Curdate, nil, timeToGoTime},
  2779  		{ast.CurrentTime, makeCausets(2), durationToGoTime},
  2780  		{ast.CurrentTime, nil, durationToGoTime},
  2781  		{ast.Curtime, nil, durationToGoTime},
  2782  	}
  2783  
  2784  	for _, t := range tests {
  2785  		now := time.Now().In(sv.TimeZone)
  2786  		f, err := funcs[t.method].getFunction(s.ctx, s.datumsToConstants(t.Input))
  2787  		c.Assert(err, IsNil)
  2788  		resetStmtContext(s.ctx)
  2789  		d, err := evalBuiltinFunc(f, chunk.Event{})
  2790  		c.Assert(err, IsNil)
  2791  		result := t.convertToTime(d, sv.TimeZone)
  2792  		c.Assert(result.Sub(now), LessEqual, 2*time.Second)
  2793  	}
  2794  }
  2795  
  2796  func (s *testEvaluatorSuite) TestMilevaDBParseTso(c *C) {
  2797  	s.ctx.GetStochastikVars().TimeZone = time.UTC
  2798  	tests := []struct {
  2799  		param  interface{}
  2800  		expect string
  2801  	}{
  2802  		{404411537129996288, "2020-11-20 09:53:04.877000"},
  2803  		{"404411537129996288", "2020-11-20 09:53:04.877000"},
  2804  		{1, "1970-01-01 00:00:00.000000"},
  2805  	}
  2806  
  2807  	fc := funcs[ast.MilevaDBParseTso]
  2808  	for _, test := range tests {
  2809  		t := []types.Causet{types.NewCauset(test.param)}
  2810  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t))
  2811  		c.Assert(err, IsNil)
  2812  		d, err := evalBuiltinFunc(f, chunk.Event{})
  2813  		c.Assert(err, IsNil)
  2814  		result, _ := d.ToString()
  2815  		c.Assert(result, Equals, test.expect)
  2816  	}
  2817  
  2818  	testsNull := []interface{}{
  2819  		0,
  2820  		-1,
  2821  		"-1"}
  2822  
  2823  	for _, i := range testsNull {
  2824  		t := []types.Causet{types.NewCauset(i)}
  2825  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t))
  2826  		c.Assert(err, IsNil)
  2827  		d, err := evalBuiltinFunc(f, chunk.Event{})
  2828  		c.Assert(err, IsNil)
  2829  		c.Assert(d.IsNull(), IsTrue)
  2830  	}
  2831  }
  2832  
  2833  func (s *testEvaluatorSuite) TestGetIntervalFromDecimal(c *C) {
  2834  	du := baseDateArithmitical{}
  2835  
  2836  	tests := []struct {
  2837  		param  string
  2838  		expect string
  2839  		unit   string
  2840  	}{
  2841  		{"1.100", "1:100", "MINUTE_SECOND"},
  2842  		{"1.10000", "1-10000", "YEAR_MONTH"},
  2843  		{"1.10000", "1 10000", "DAY_HOUR"},
  2844  		{"11000", "0 00:00:11000", "DAY_MICROSECOND"},
  2845  		{"11000", "00:00:11000", "HOUR_MICROSECOND"},
  2846  		{"11.1000", "00:11:1000", "HOUR_SECOND"},
  2847  		{"1000", "00:1000", "MINUTE_MICROSECOND"},
  2848  	}
  2849  
  2850  	for _, test := range tests {
  2851  		interval, isNull, err := du.getIntervalFromDecimal(s.ctx, s.datumsToConstants([]types.Causet{types.NewCauset("CURRENT DATE"), types.NewDecimalCauset(newMyDecimal(c, test.param))}), chunk.Event{}, test.unit)
  2852  		c.Assert(isNull, IsFalse)
  2853  		c.Assert(err, IsNil)
  2854  		c.Assert(interval, Equals, test.expect)
  2855  	}
  2856  }