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

     1  // Copyright 2020 The ql Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSES/QL-LICENSE file.
     4  
     5  // Copyright 2020 WHTCORPS INC, Inc.
     6  //
     7  // Licensed under the Apache License, Version 2.0 (the "License");
     8  // you may not use this file except in compliance with the License.
     9  // You may obtain a copy of the License at
    10  //
    11  //     http://www.apache.org/licenses/LICENSE-2.0
    12  //
    13  // Unless required by applicable law or agreed to in writing, software
    14  // distributed under the License is distributed on an "AS IS" BASIS,
    15  // See the License for the specific language governing permissions and
    16  // limitations under the License.
    17  
    18  package memex
    19  
    20  import (
    21  	"fmt"
    22  	"math"
    23  	"regexp"
    24  	"strconv"
    25  	"strings"
    26  	"time"
    27  
    28  	"github.com/cznic/mathutil"
    29  	"github.com/whtcorpsinc/errors"
    30  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    31  	"github.com/whtcorpsinc/BerolinaSQL/terror"
    32  	"github.com/whtcorpsinc/milevadb/stochastikctx"
    33  	"github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx"
    34  	"github.com/whtcorpsinc/milevadb/stochastikctx/variable"
    35  	"github.com/whtcorpsinc/milevadb/causetstore/einsteindb/oracle"
    36  	"github.com/whtcorpsinc/milevadb/types"
    37  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    38  	"github.com/whtcorpsinc/milevadb/soliton/logutil"
    39  	"github.com/whtcorpsinc/fidelpb/go-fidelpb"
    40  	"go.uber.org/zap"
    41  )
    42  
    43  const ( // GET_FORMAT first argument.
    44  	dateFormat      = "DATE"
    45  	datetimeFormat  = "DATETIME"
    46  	timestampFormat = "TIMESTAMP"
    47  	timeFormat      = "TIME"
    48  )
    49  
    50  const ( // GET_FORMAT location.
    51  	usaLocation      = "USA"
    52  	jisLocation      = "JIS"
    53  	isoLocation      = "ISO"
    54  	eurLocation      = "EUR"
    55  	internalLocation = "INTERNAL"
    56  )
    57  
    58  var (
    59  	// durationPattern checks whether a string matchs the format of duration.
    60  	durationPattern = regexp.MustCompile(`^\s*[-]?(((\d{1,2}\s+)?0*\d{0,3}(:0*\d{1,2}){0,2})|(\d{1,7}))?(\.\d*)?\s*$`)
    61  
    62  	// timestampPattern checks whether a string matchs the format of timestamp.
    63  	timestampPattern = regexp.MustCompile(`^\s*0*\d{1,4}([^\d]0*\d{1,2}){2}\s+(0*\d{0,2}([^\d]0*\d{1,2}){2})?(\.\d*)?\s*$`)
    64  
    65  	// datePattern determine whether to match the format of date.
    66  	datePattern = regexp.MustCompile(`^\s*((0*\d{1,4}([^\d]0*\d{1,2}){2})|(\d{2,4}(\d{2}){2}))\s*$`)
    67  )
    68  
    69  var (
    70  	_ functionClass = &dateFunctionClass{}
    71  	_ functionClass = &dateLiteralFunctionClass{}
    72  	_ functionClass = &dateDiffFunctionClass{}
    73  	_ functionClass = &timeDiffFunctionClass{}
    74  	_ functionClass = &dateFormatFunctionClass{}
    75  	_ functionClass = &hourFunctionClass{}
    76  	_ functionClass = &minuteFunctionClass{}
    77  	_ functionClass = &secondFunctionClass{}
    78  	_ functionClass = &microSecondFunctionClass{}
    79  	_ functionClass = &monthFunctionClass{}
    80  	_ functionClass = &monthNameFunctionClass{}
    81  	_ functionClass = &nowFunctionClass{}
    82  	_ functionClass = &dayNameFunctionClass{}
    83  	_ functionClass = &dayOfMonthFunctionClass{}
    84  	_ functionClass = &dayOfWeekFunctionClass{}
    85  	_ functionClass = &dayOfYearFunctionClass{}
    86  	_ functionClass = &weekFunctionClass{}
    87  	_ functionClass = &weekDayFunctionClass{}
    88  	_ functionClass = &weekOfYearFunctionClass{}
    89  	_ functionClass = &yearFunctionClass{}
    90  	_ functionClass = &yearWeekFunctionClass{}
    91  	_ functionClass = &fromUnixTimeFunctionClass{}
    92  	_ functionClass = &getFormatFunctionClass{}
    93  	_ functionClass = &strToDateFunctionClass{}
    94  	_ functionClass = &sysDateFunctionClass{}
    95  	_ functionClass = &currentDateFunctionClass{}
    96  	_ functionClass = &currentTimeFunctionClass{}
    97  	_ functionClass = &timeFunctionClass{}
    98  	_ functionClass = &timeLiteralFunctionClass{}
    99  	_ functionClass = &utcDateFunctionClass{}
   100  	_ functionClass = &utcTimestampFunctionClass{}
   101  	_ functionClass = &extractFunctionClass{}
   102  	_ functionClass = &unixTimestampFunctionClass{}
   103  	_ functionClass = &addTimeFunctionClass{}
   104  	_ functionClass = &convertTzFunctionClass{}
   105  	_ functionClass = &makeDateFunctionClass{}
   106  	_ functionClass = &makeTimeFunctionClass{}
   107  	_ functionClass = &periodAddFunctionClass{}
   108  	_ functionClass = &periodDiffFunctionClass{}
   109  	_ functionClass = &quarterFunctionClass{}
   110  	_ functionClass = &secToTimeFunctionClass{}
   111  	_ functionClass = &subTimeFunctionClass{}
   112  	_ functionClass = &timeFormatFunctionClass{}
   113  	_ functionClass = &timeToSecFunctionClass{}
   114  	_ functionClass = &timestampAddFunctionClass{}
   115  	_ functionClass = &toDaysFunctionClass{}
   116  	_ functionClass = &toSecondsFunctionClass{}
   117  	_ functionClass = &utcTimeFunctionClass{}
   118  	_ functionClass = &timestampFunctionClass{}
   119  	_ functionClass = &timestampLiteralFunctionClass{}
   120  	_ functionClass = &lastDayFunctionClass{}
   121  	_ functionClass = &addDateFunctionClass{}
   122  	_ functionClass = &subDateFunctionClass{}
   123  )
   124  
   125  var (
   126  	_ builtinFuncNew = &builtinUnixTimestampIntSig{}
   127  )
   128  
   129  var (
   130  	_ builtinFunc = &builtinDateSig{}
   131  	_ builtinFunc = &builtinDateLiteralSig{}
   132  	_ builtinFunc = &builtinDateDiffSig{}
   133  	_ builtinFunc = &builtinNullTimeDiffSig{}
   134  	_ builtinFunc = &builtinTimeStringTimeDiffSig{}
   135  	_ builtinFunc = &builtinDurationStringTimeDiffSig{}
   136  	_ builtinFunc = &builtinDurationDurationTimeDiffSig{}
   137  	_ builtinFunc = &builtinStringTimeTimeDiffSig{}
   138  	_ builtinFunc = &builtinStringDurationTimeDiffSig{}
   139  	_ builtinFunc = &builtinStringStringTimeDiffSig{}
   140  	_ builtinFunc = &builtinTimeTimeTimeDiffSig{}
   141  	_ builtinFunc = &builtinDateFormatSig{}
   142  	_ builtinFunc = &builtinHourSig{}
   143  	_ builtinFunc = &builtinMinuteSig{}
   144  	_ builtinFunc = &builtinSecondSig{}
   145  	_ builtinFunc = &builtinMicroSecondSig{}
   146  	_ builtinFunc = &builtinMonthSig{}
   147  	_ builtinFunc = &builtinMonthNameSig{}
   148  	_ builtinFunc = &builtinNowWithArgSig{}
   149  	_ builtinFunc = &builtinNowWithoutArgSig{}
   150  	_ builtinFunc = &builtinDayNameSig{}
   151  	_ builtinFunc = &builtinDayOfMonthSig{}
   152  	_ builtinFunc = &builtinDayOfWeekSig{}
   153  	_ builtinFunc = &builtinDayOfYearSig{}
   154  	_ builtinFunc = &builtinWeekWithModeSig{}
   155  	_ builtinFunc = &builtinWeekWithoutModeSig{}
   156  	_ builtinFunc = &builtinWeekDaySig{}
   157  	_ builtinFunc = &builtinWeekOfYearSig{}
   158  	_ builtinFunc = &builtinYearSig{}
   159  	_ builtinFunc = &builtinYearWeekWithModeSig{}
   160  	_ builtinFunc = &builtinYearWeekWithoutModeSig{}
   161  	_ builtinFunc = &builtinGetFormatSig{}
   162  	_ builtinFunc = &builtinSysDateWithFspSig{}
   163  	_ builtinFunc = &builtinSysDateWithoutFspSig{}
   164  	_ builtinFunc = &builtinCurrentDateSig{}
   165  	_ builtinFunc = &builtinCurrentTime0ArgSig{}
   166  	_ builtinFunc = &builtinCurrentTime1ArgSig{}
   167  	_ builtinFunc = &builtinTimeSig{}
   168  	_ builtinFunc = &builtinTimeLiteralSig{}
   169  	_ builtinFunc = &builtinUTCDateSig{}
   170  	_ builtinFunc = &builtinUTCTimestampWithArgSig{}
   171  	_ builtinFunc = &builtinUTCTimestampWithoutArgSig{}
   172  	_ builtinFunc = &builtinAddDatetimeAndDurationSig{}
   173  	_ builtinFunc = &builtinAddDatetimeAndStringSig{}
   174  	_ builtinFunc = &builtinAddTimeDateTimeNullSig{}
   175  	_ builtinFunc = &builtinAddStringAndDurationSig{}
   176  	_ builtinFunc = &builtinAddStringAndStringSig{}
   177  	_ builtinFunc = &builtinAddTimeStringNullSig{}
   178  	_ builtinFunc = &builtinAddDurationAndDurationSig{}
   179  	_ builtinFunc = &builtinAddDurationAndStringSig{}
   180  	_ builtinFunc = &builtinAddTimeDurationNullSig{}
   181  	_ builtinFunc = &builtinAddDateAndDurationSig{}
   182  	_ builtinFunc = &builtinAddDateAndStringSig{}
   183  	_ builtinFunc = &builtinSubDatetimeAndDurationSig{}
   184  	_ builtinFunc = &builtinSubDatetimeAndStringSig{}
   185  	_ builtinFunc = &builtinSubTimeDateTimeNullSig{}
   186  	_ builtinFunc = &builtinSubStringAndDurationSig{}
   187  	_ builtinFunc = &builtinSubStringAndStringSig{}
   188  	_ builtinFunc = &builtinSubTimeStringNullSig{}
   189  	_ builtinFunc = &builtinSubDurationAndDurationSig{}
   190  	_ builtinFunc = &builtinSubDurationAndStringSig{}
   191  	_ builtinFunc = &builtinSubTimeDurationNullSig{}
   192  	_ builtinFunc = &builtinSubDateAndDurationSig{}
   193  	_ builtinFunc = &builtinSubDateAndStringSig{}
   194  	_ builtinFunc = &builtinUnixTimestampCurrentSig{}
   195  	_ builtinFunc = &builtinUnixTimestampIntSig{}
   196  	_ builtinFunc = &builtinUnixTimestamFIDelecSig{}
   197  	_ builtinFunc = &builtinConvertTzSig{}
   198  	_ builtinFunc = &builtinMakeDateSig{}
   199  	_ builtinFunc = &builtinMakeTimeSig{}
   200  	_ builtinFunc = &builtinPeriodAddSig{}
   201  	_ builtinFunc = &builtinPeriodDiffSig{}
   202  	_ builtinFunc = &builtinQuarterSig{}
   203  	_ builtinFunc = &builtinSecToTimeSig{}
   204  	_ builtinFunc = &builtinTimeToSecSig{}
   205  	_ builtinFunc = &builtinTimestampAddSig{}
   206  	_ builtinFunc = &builtinToDaysSig{}
   207  	_ builtinFunc = &builtinToSecondsSig{}
   208  	_ builtinFunc = &builtinUTCTimeWithArgSig{}
   209  	_ builtinFunc = &builtinUTCTimeWithoutArgSig{}
   210  	_ builtinFunc = &builtinTimestamp1ArgSig{}
   211  	_ builtinFunc = &builtinTimestamp2ArgsSig{}
   212  	_ builtinFunc = &builtinTimestampLiteralSig{}
   213  	_ builtinFunc = &builtinLastDaySig{}
   214  	_ builtinFunc = &builtinStrToDateDateSig{}
   215  	_ builtinFunc = &builtinStrToDateDatetimeSig{}
   216  	_ builtinFunc = &builtinStrToDateDurationSig{}
   217  	_ builtinFunc = &builtinFromUnixTime1ArgSig{}
   218  	_ builtinFunc = &builtinFromUnixTime2ArgSig{}
   219  	_ builtinFunc = &builtinExtractDatetimeSig{}
   220  	_ builtinFunc = &builtinExtractDurationSig{}
   221  	_ builtinFunc = &builtinAddDateStringStringSig{}
   222  	_ builtinFunc = &builtinAddDateStringIntSig{}
   223  	_ builtinFunc = &builtinAddDateStringRealSig{}
   224  	_ builtinFunc = &builtinAddDateStringDecimalSig{}
   225  	_ builtinFunc = &builtinAddDateIntStringSig{}
   226  	_ builtinFunc = &builtinAddDateIntIntSig{}
   227  	_ builtinFunc = &builtinAddDateIntRealSig{}
   228  	_ builtinFunc = &builtinAddDateIntDecimalSig{}
   229  	_ builtinFunc = &builtinAddDateDatetimeStringSig{}
   230  	_ builtinFunc = &builtinAddDateDatetimeIntSig{}
   231  	_ builtinFunc = &builtinAddDateDatetimeRealSig{}
   232  	_ builtinFunc = &builtinAddDateDatetimeDecimalSig{}
   233  	_ builtinFunc = &builtinSubDateStringStringSig{}
   234  	_ builtinFunc = &builtinSubDateStringIntSig{}
   235  	_ builtinFunc = &builtinSubDateStringRealSig{}
   236  	_ builtinFunc = &builtinSubDateStringDecimalSig{}
   237  	_ builtinFunc = &builtinSubDateIntStringSig{}
   238  	_ builtinFunc = &builtinSubDateIntIntSig{}
   239  	_ builtinFunc = &builtinSubDateIntRealSig{}
   240  	_ builtinFunc = &builtinSubDateIntDecimalSig{}
   241  	_ builtinFunc = &builtinSubDateDatetimeStringSig{}
   242  	_ builtinFunc = &builtinSubDateDatetimeIntSig{}
   243  	_ builtinFunc = &builtinSubDateDatetimeRealSig{}
   244  	_ builtinFunc = &builtinSubDateDatetimeDecimalSig{}
   245  )
   246  
   247  func convertTimeToMysqlTime(t time.Time, fsp int8, roundMode types.RoundMode) (types.Time, error) {
   248  	var tr time.Time
   249  	var err error
   250  	if roundMode == types.ModeTruncate {
   251  		tr, err = types.TruncateFrac(t, fsp)
   252  	} else {
   253  		tr, err = types.RoundFrac(t, fsp)
   254  	}
   255  	if err != nil {
   256  		return types.ZeroTime, err
   257  	}
   258  
   259  	return types.NewTime(types.FromGoTime(tr), allegrosql.TypeDatetime, fsp), nil
   260  }
   261  
   262  type dateFunctionClass struct {
   263  	baseFunctionClass
   264  }
   265  
   266  func (c *dateFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   267  	if err := c.verifyArgs(args); err != nil {
   268  		return nil, err
   269  	}
   270  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDatetime, types.ETDatetime)
   271  	if err != nil {
   272  		return nil, err
   273  	}
   274  	bf.tp.Tp, bf.tp.Flen, bf.tp.Decimal = allegrosql.TypeDate, 10, 0
   275  	sig := &builtinDateSig{bf}
   276  	sig.setPbCode(fidelpb.ScalarFuncSig_Date)
   277  	return sig, nil
   278  }
   279  
   280  type builtinDateSig struct {
   281  	baseBuiltinFunc
   282  }
   283  
   284  func (b *builtinDateSig) Clone() builtinFunc {
   285  	newSig := &builtinDateSig{}
   286  	newSig.cloneFrom(&b.baseBuiltinFunc)
   287  	return newSig
   288  }
   289  
   290  // evalTime evals DATE(expr).
   291  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date
   292  func (b *builtinDateSig) evalTime(event chunk.Event) (types.Time, bool, error) {
   293  	expr, isNull, err := b.args[0].EvalTime(b.ctx, event)
   294  	if isNull || err != nil {
   295  		return types.ZeroTime, true, handleInvalidTimeError(b.ctx, err)
   296  	}
   297  
   298  	if expr.IsZero() {
   299  		return types.ZeroTime, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, expr.String()))
   300  	}
   301  
   302  	expr.SetCoreTime(types.FromDate(expr.Year(), expr.Month(), expr.Day(), 0, 0, 0, 0))
   303  	expr.SetType(allegrosql.TypeDate)
   304  	return expr, false, nil
   305  }
   306  
   307  type dateLiteralFunctionClass struct {
   308  	baseFunctionClass
   309  }
   310  
   311  func (c *dateLiteralFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   312  	if err := c.verifyArgs(args); err != nil {
   313  		return nil, err
   314  	}
   315  	con, ok := args[0].(*Constant)
   316  	if !ok {
   317  		panic("Unexpected parameter for date literal")
   318  	}
   319  	dt, err := con.Eval(chunk.Event{})
   320  	if err != nil {
   321  		return nil, err
   322  	}
   323  	str := dt.GetString()
   324  	if !datePattern.MatchString(str) {
   325  		return nil, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, str)
   326  	}
   327  	tm, err := types.ParseDate(ctx.GetStochastikVars().StmtCtx, str)
   328  	if err != nil {
   329  		return nil, err
   330  	}
   331  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, []Expression{}, types.ETDatetime)
   332  	if err != nil {
   333  		return nil, err
   334  	}
   335  	bf.tp.Tp, bf.tp.Flen, bf.tp.Decimal = allegrosql.TypeDate, 10, 0
   336  	sig := &builtinDateLiteralSig{bf, tm}
   337  	return sig, nil
   338  }
   339  
   340  type builtinDateLiteralSig struct {
   341  	baseBuiltinFunc
   342  	literal types.Time
   343  }
   344  
   345  func (b *builtinDateLiteralSig) Clone() builtinFunc {
   346  	newSig := &builtinDateLiteralSig{literal: b.literal}
   347  	newSig.cloneFrom(&b.baseBuiltinFunc)
   348  	return newSig
   349  }
   350  
   351  // evalTime evals DATE 'stringLit'.
   352  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-literals.html
   353  func (b *builtinDateLiteralSig) evalTime(event chunk.Event) (types.Time, bool, error) {
   354  	mode := b.ctx.GetStochastikVars().ALLEGROSQLMode
   355  	if mode.HasNoZeroDateMode() && b.literal.IsZero() {
   356  		return b.literal, true, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, b.literal.String())
   357  	}
   358  	if mode.HasNoZeroInDateMode() && (b.literal.InvalidZero() && !b.literal.IsZero()) {
   359  		return b.literal, true, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, b.literal.String())
   360  	}
   361  	return b.literal, false, nil
   362  }
   363  
   364  type dateDiffFunctionClass struct {
   365  	baseFunctionClass
   366  }
   367  
   368  func (c *dateDiffFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   369  	if err := c.verifyArgs(args); err != nil {
   370  		return nil, err
   371  	}
   372  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETDatetime, types.ETDatetime)
   373  	if err != nil {
   374  		return nil, err
   375  	}
   376  	sig := &builtinDateDiffSig{bf}
   377  	sig.setPbCode(fidelpb.ScalarFuncSig_DateDiff)
   378  	return sig, nil
   379  }
   380  
   381  type builtinDateDiffSig struct {
   382  	baseBuiltinFunc
   383  }
   384  
   385  func (b *builtinDateDiffSig) Clone() builtinFunc {
   386  	newSig := &builtinDateDiffSig{}
   387  	newSig.cloneFrom(&b.baseBuiltinFunc)
   388  	return newSig
   389  }
   390  
   391  // evalInt evals a builtinDateDiffSig.
   392  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_datediff
   393  func (b *builtinDateDiffSig) evalInt(event chunk.Event) (int64, bool, error) {
   394  	lhs, isNull, err := b.args[0].EvalTime(b.ctx, event)
   395  	if isNull || err != nil {
   396  		return 0, true, handleInvalidTimeError(b.ctx, err)
   397  	}
   398  	rhs, isNull, err := b.args[1].EvalTime(b.ctx, event)
   399  	if isNull || err != nil {
   400  		return 0, true, handleInvalidTimeError(b.ctx, err)
   401  	}
   402  	if invalidLHS, invalidRHS := lhs.InvalidZero(), rhs.InvalidZero(); invalidLHS || invalidRHS {
   403  		if invalidLHS {
   404  			err = handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, lhs.String()))
   405  		}
   406  		if invalidRHS {
   407  			err = handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, rhs.String()))
   408  		}
   409  		return 0, true, err
   410  	}
   411  	return int64(types.DateDiff(lhs.CoreTime(), rhs.CoreTime())), false, nil
   412  }
   413  
   414  type timeDiffFunctionClass struct {
   415  	baseFunctionClass
   416  }
   417  
   418  func (c *timeDiffFunctionClass) getArgEvalTp(fieldTp *types.FieldType) types.EvalType {
   419  	argTp := types.ETString
   420  	switch tp := fieldTp.EvalType(); tp {
   421  	case types.ETDuration, types.ETDatetime, types.ETTimestamp:
   422  		argTp = tp
   423  	}
   424  	return argTp
   425  }
   426  
   427  func (c *timeDiffFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   428  	if err := c.verifyArgs(args); err != nil {
   429  		return nil, err
   430  	}
   431  
   432  	arg0FieldTp, arg1FieldTp := args[0].GetType(), args[1].GetType()
   433  	arg0Tp, arg1Tp := c.getArgEvalTp(arg0FieldTp), c.getArgEvalTp(arg1FieldTp)
   434  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDuration, arg0Tp, arg1Tp)
   435  	if err != nil {
   436  		return nil, err
   437  	}
   438  
   439  	arg0Dec, err := getExpressionFsp(ctx, args[0])
   440  	if err != nil {
   441  		return nil, err
   442  	}
   443  	arg1Dec, err := getExpressionFsp(ctx, args[1])
   444  	if err != nil {
   445  		return nil, err
   446  	}
   447  	bf.tp.Decimal = mathutil.Max(arg0Dec, arg1Dec)
   448  
   449  	var sig builtinFunc
   450  	// arg0 and arg1 must be the same time type(compatible), or timediff will return NULL.
   451  	// TODO: we don't really need Duration type, actually in MyALLEGROSQL, it use Time class to represent
   452  	// all the time type, and use filed type to distinguish datetime, date, timestamp or time(duration).
   453  	// With the duration type, we are hard to port all the MyALLEGROSQL behavior.
   454  	switch arg0Tp {
   455  	case types.ETDuration:
   456  		switch arg1Tp {
   457  		case types.ETDuration:
   458  			sig = &builtinDurationDurationTimeDiffSig{bf}
   459  			sig.setPbCode(fidelpb.ScalarFuncSig_DurationDurationTimeDiff)
   460  		case types.ETDatetime, types.ETTimestamp:
   461  			sig = &builtinNullTimeDiffSig{bf}
   462  			sig.setPbCode(fidelpb.ScalarFuncSig_NullTimeDiff)
   463  		default:
   464  			sig = &builtinDurationStringTimeDiffSig{bf}
   465  			sig.setPbCode(fidelpb.ScalarFuncSig_DurationStringTimeDiff)
   466  		}
   467  	case types.ETDatetime, types.ETTimestamp:
   468  		switch arg1Tp {
   469  		case types.ETDuration:
   470  			sig = &builtinNullTimeDiffSig{bf}
   471  			sig.setPbCode(fidelpb.ScalarFuncSig_NullTimeDiff)
   472  		case types.ETDatetime, types.ETTimestamp:
   473  			sig = &builtinTimeTimeTimeDiffSig{bf}
   474  			sig.setPbCode(fidelpb.ScalarFuncSig_TimeTimeTimeDiff)
   475  		default:
   476  			sig = &builtinTimeStringTimeDiffSig{bf}
   477  			sig.setPbCode(fidelpb.ScalarFuncSig_TimeStringTimeDiff)
   478  		}
   479  	default:
   480  		switch arg1Tp {
   481  		case types.ETDuration:
   482  			sig = &builtinStringDurationTimeDiffSig{bf}
   483  			sig.setPbCode(fidelpb.ScalarFuncSig_StringDurationTimeDiff)
   484  		case types.ETDatetime, types.ETTimestamp:
   485  			sig = &builtinStringTimeTimeDiffSig{bf}
   486  			sig.setPbCode(fidelpb.ScalarFuncSig_StringTimeTimeDiff)
   487  		default:
   488  			sig = &builtinStringStringTimeDiffSig{bf}
   489  			sig.setPbCode(fidelpb.ScalarFuncSig_StringStringTimeDiff)
   490  		}
   491  	}
   492  	return sig, nil
   493  }
   494  
   495  type builtinDurationDurationTimeDiffSig struct {
   496  	baseBuiltinFunc
   497  }
   498  
   499  func (b *builtinDurationDurationTimeDiffSig) Clone() builtinFunc {
   500  	newSig := &builtinDurationDurationTimeDiffSig{}
   501  	newSig.cloneFrom(&b.baseBuiltinFunc)
   502  	return newSig
   503  }
   504  
   505  // evalDuration evals a builtinDurationDurationTimeDiffSig.
   506  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timediff
   507  func (b *builtinDurationDurationTimeDiffSig) evalDuration(event chunk.Event) (d types.Duration, isNull bool, err error) {
   508  	lhs, isNull, err := b.args[0].EvalDuration(b.ctx, event)
   509  	if isNull || err != nil {
   510  		return d, isNull, err
   511  	}
   512  
   513  	rhs, isNull, err := b.args[1].EvalDuration(b.ctx, event)
   514  	if isNull || err != nil {
   515  		return d, isNull, err
   516  	}
   517  
   518  	d, isNull, err = calculateDurationTimeDiff(b.ctx, lhs, rhs)
   519  	return d, isNull, err
   520  }
   521  
   522  type builtinTimeTimeTimeDiffSig struct {
   523  	baseBuiltinFunc
   524  }
   525  
   526  func (b *builtinTimeTimeTimeDiffSig) Clone() builtinFunc {
   527  	newSig := &builtinTimeTimeTimeDiffSig{}
   528  	newSig.cloneFrom(&b.baseBuiltinFunc)
   529  	return newSig
   530  }
   531  
   532  // evalDuration evals a builtinTimeTimeTimeDiffSig.
   533  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timediff
   534  func (b *builtinTimeTimeTimeDiffSig) evalDuration(event chunk.Event) (d types.Duration, isNull bool, err error) {
   535  	lhs, isNull, err := b.args[0].EvalTime(b.ctx, event)
   536  	if isNull || err != nil {
   537  		return d, isNull, err
   538  	}
   539  
   540  	rhs, isNull, err := b.args[1].EvalTime(b.ctx, event)
   541  	if isNull || err != nil {
   542  		return d, isNull, err
   543  	}
   544  
   545  	sc := b.ctx.GetStochastikVars().StmtCtx
   546  	d, isNull, err = calculateTimeDiff(sc, lhs, rhs)
   547  	return d, isNull, err
   548  }
   549  
   550  type builtinDurationStringTimeDiffSig struct {
   551  	baseBuiltinFunc
   552  }
   553  
   554  func (b *builtinDurationStringTimeDiffSig) Clone() builtinFunc {
   555  	newSig := &builtinDurationStringTimeDiffSig{}
   556  	newSig.cloneFrom(&b.baseBuiltinFunc)
   557  	return newSig
   558  }
   559  
   560  // evalDuration evals a builtinDurationStringTimeDiffSig.
   561  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timediff
   562  func (b *builtinDurationStringTimeDiffSig) evalDuration(event chunk.Event) (d types.Duration, isNull bool, err error) {
   563  	lhs, isNull, err := b.args[0].EvalDuration(b.ctx, event)
   564  	if isNull || err != nil {
   565  		return d, isNull, err
   566  	}
   567  
   568  	rhsStr, isNull, err := b.args[1].EvalString(b.ctx, event)
   569  	if isNull || err != nil {
   570  		return d, isNull, err
   571  	}
   572  
   573  	sc := b.ctx.GetStochastikVars().StmtCtx
   574  	rhs, _, isDuration, err := convertStringToDuration(sc, rhsStr, int8(b.tp.Decimal))
   575  	if err != nil || !isDuration {
   576  		return d, true, err
   577  	}
   578  
   579  	d, isNull, err = calculateDurationTimeDiff(b.ctx, lhs, rhs)
   580  	return d, isNull, err
   581  }
   582  
   583  type builtinStringDurationTimeDiffSig struct {
   584  	baseBuiltinFunc
   585  }
   586  
   587  func (b *builtinStringDurationTimeDiffSig) Clone() builtinFunc {
   588  	newSig := &builtinStringDurationTimeDiffSig{}
   589  	newSig.cloneFrom(&b.baseBuiltinFunc)
   590  	return newSig
   591  }
   592  
   593  // evalDuration evals a builtinStringDurationTimeDiffSig.
   594  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timediff
   595  func (b *builtinStringDurationTimeDiffSig) evalDuration(event chunk.Event) (d types.Duration, isNull bool, err error) {
   596  	lhsStr, isNull, err := b.args[0].EvalString(b.ctx, event)
   597  	if isNull || err != nil {
   598  		return d, isNull, err
   599  	}
   600  
   601  	rhs, isNull, err := b.args[1].EvalDuration(b.ctx, event)
   602  	if isNull || err != nil {
   603  		return d, isNull, err
   604  	}
   605  
   606  	sc := b.ctx.GetStochastikVars().StmtCtx
   607  	lhs, _, isDuration, err := convertStringToDuration(sc, lhsStr, int8(b.tp.Decimal))
   608  	if err != nil || !isDuration {
   609  		return d, true, err
   610  	}
   611  
   612  	d, isNull, err = calculateDurationTimeDiff(b.ctx, lhs, rhs)
   613  	return d, isNull, err
   614  }
   615  
   616  // calculateTimeDiff calculates interval difference of two types.Time.
   617  func calculateTimeDiff(sc *stmtctx.StatementContext, lhs, rhs types.Time) (d types.Duration, isNull bool, err error) {
   618  	d = lhs.Sub(sc, &rhs)
   619  	d.Duration, err = types.TruncateOverflowMyALLEGROSQLTime(d.Duration)
   620  	if types.ErrTruncatedWrongVal.Equal(err) {
   621  		err = sc.HandleTruncate(err)
   622  	}
   623  	return d, err != nil, err
   624  }
   625  
   626  // calculateDurationTimeDiff calculates interval difference of two types.Duration.
   627  func calculateDurationTimeDiff(ctx stochastikctx.Context, lhs, rhs types.Duration) (d types.Duration, isNull bool, err error) {
   628  	d, err = lhs.Sub(rhs)
   629  	if err != nil {
   630  		return d, true, err
   631  	}
   632  
   633  	d.Duration, err = types.TruncateOverflowMyALLEGROSQLTime(d.Duration)
   634  	if types.ErrTruncatedWrongVal.Equal(err) {
   635  		sc := ctx.GetStochastikVars().StmtCtx
   636  		err = sc.HandleTruncate(err)
   637  	}
   638  	return d, err != nil, err
   639  }
   640  
   641  type builtinTimeStringTimeDiffSig struct {
   642  	baseBuiltinFunc
   643  }
   644  
   645  func (b *builtinTimeStringTimeDiffSig) Clone() builtinFunc {
   646  	newSig := &builtinTimeStringTimeDiffSig{}
   647  	newSig.cloneFrom(&b.baseBuiltinFunc)
   648  	return newSig
   649  }
   650  
   651  // evalDuration evals a builtinTimeStringTimeDiffSig.
   652  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timediff
   653  func (b *builtinTimeStringTimeDiffSig) evalDuration(event chunk.Event) (d types.Duration, isNull bool, err error) {
   654  	lhs, isNull, err := b.args[0].EvalTime(b.ctx, event)
   655  	if isNull || err != nil {
   656  		return d, isNull, err
   657  	}
   658  
   659  	rhsStr, isNull, err := b.args[1].EvalString(b.ctx, event)
   660  	if isNull || err != nil {
   661  		return d, isNull, err
   662  	}
   663  
   664  	sc := b.ctx.GetStochastikVars().StmtCtx
   665  	_, rhs, isDuration, err := convertStringToDuration(sc, rhsStr, int8(b.tp.Decimal))
   666  	if err != nil || isDuration {
   667  		return d, true, err
   668  	}
   669  
   670  	d, isNull, err = calculateTimeDiff(sc, lhs, rhs)
   671  	return d, isNull, err
   672  }
   673  
   674  type builtinStringTimeTimeDiffSig struct {
   675  	baseBuiltinFunc
   676  }
   677  
   678  func (b *builtinStringTimeTimeDiffSig) Clone() builtinFunc {
   679  	newSig := &builtinStringTimeTimeDiffSig{}
   680  	newSig.cloneFrom(&b.baseBuiltinFunc)
   681  	return newSig
   682  }
   683  
   684  // evalDuration evals a builtinStringTimeTimeDiffSig.
   685  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timediff
   686  func (b *builtinStringTimeTimeDiffSig) evalDuration(event chunk.Event) (d types.Duration, isNull bool, err error) {
   687  	lhsStr, isNull, err := b.args[0].EvalString(b.ctx, event)
   688  	if isNull || err != nil {
   689  		return d, isNull, err
   690  	}
   691  
   692  	rhs, isNull, err := b.args[1].EvalTime(b.ctx, event)
   693  	if isNull || err != nil {
   694  		return d, isNull, err
   695  	}
   696  
   697  	sc := b.ctx.GetStochastikVars().StmtCtx
   698  	_, lhs, isDuration, err := convertStringToDuration(sc, lhsStr, int8(b.tp.Decimal))
   699  	if err != nil || isDuration {
   700  		return d, true, err
   701  	}
   702  
   703  	d, isNull, err = calculateTimeDiff(sc, lhs, rhs)
   704  	return d, isNull, err
   705  }
   706  
   707  type builtinStringStringTimeDiffSig struct {
   708  	baseBuiltinFunc
   709  }
   710  
   711  func (b *builtinStringStringTimeDiffSig) Clone() builtinFunc {
   712  	newSig := &builtinStringStringTimeDiffSig{}
   713  	newSig.cloneFrom(&b.baseBuiltinFunc)
   714  	return newSig
   715  }
   716  
   717  // evalDuration evals a builtinStringStringTimeDiffSig.
   718  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timediff
   719  func (b *builtinStringStringTimeDiffSig) evalDuration(event chunk.Event) (d types.Duration, isNull bool, err error) {
   720  	lhs, isNull, err := b.args[0].EvalString(b.ctx, event)
   721  	if isNull || err != nil {
   722  		return d, isNull, err
   723  	}
   724  
   725  	rhs, isNull, err := b.args[1].EvalString(b.ctx, event)
   726  	if isNull || err != nil {
   727  		return d, isNull, err
   728  	}
   729  
   730  	sc := b.ctx.GetStochastikVars().StmtCtx
   731  	fsp := int8(b.tp.Decimal)
   732  	lhsDur, lhsTime, lhsIsDuration, err := convertStringToDuration(sc, lhs, fsp)
   733  	if err != nil {
   734  		return d, true, err
   735  	}
   736  
   737  	rhsDur, rhsTime, rhsIsDuration, err := convertStringToDuration(sc, rhs, fsp)
   738  	if err != nil {
   739  		return d, true, err
   740  	}
   741  
   742  	if lhsIsDuration != rhsIsDuration {
   743  		return d, true, nil
   744  	}
   745  
   746  	if lhsIsDuration {
   747  		d, isNull, err = calculateDurationTimeDiff(b.ctx, lhsDur, rhsDur)
   748  	} else {
   749  		d, isNull, err = calculateTimeDiff(sc, lhsTime, rhsTime)
   750  	}
   751  
   752  	return d, isNull, err
   753  }
   754  
   755  type builtinNullTimeDiffSig struct {
   756  	baseBuiltinFunc
   757  }
   758  
   759  func (b *builtinNullTimeDiffSig) Clone() builtinFunc {
   760  	newSig := &builtinNullTimeDiffSig{}
   761  	newSig.cloneFrom(&b.baseBuiltinFunc)
   762  	return newSig
   763  }
   764  
   765  // evalDuration evals a builtinNullTimeDiffSig.
   766  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timediff
   767  func (b *builtinNullTimeDiffSig) evalDuration(event chunk.Event) (d types.Duration, isNull bool, err error) {
   768  	return d, true, nil
   769  }
   770  
   771  // convertStringToDuration converts string to duration, it return types.Time because in some case
   772  // it will converts string to datetime.
   773  func convertStringToDuration(sc *stmtctx.StatementContext, str string, fsp int8) (d types.Duration, t types.Time,
   774  	isDuration bool, err error) {
   775  	if n := strings.IndexByte(str, '.'); n >= 0 {
   776  		lenStrFsp := len(str[n+1:])
   777  		if lenStrFsp <= int(types.MaxFsp) {
   778  			fsp = mathutil.MaxInt8(int8(lenStrFsp), fsp)
   779  		}
   780  	}
   781  	return types.StrToDuration(sc, str, fsp)
   782  }
   783  
   784  type dateFormatFunctionClass struct {
   785  	baseFunctionClass
   786  }
   787  
   788  func (c *dateFormatFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   789  	if err := c.verifyArgs(args); err != nil {
   790  		return nil, err
   791  	}
   792  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETDatetime, types.ETString)
   793  	if err != nil {
   794  		return nil, err
   795  	}
   796  	// worst case: formatMask=%r%r%r...%r, each %r takes 11 characters
   797  	bf.tp.Flen = (args[1].GetType().Flen + 1) / 2 * 11
   798  	sig := &builtinDateFormatSig{bf}
   799  	sig.setPbCode(fidelpb.ScalarFuncSig_DateFormatSig)
   800  	return sig, nil
   801  }
   802  
   803  type builtinDateFormatSig struct {
   804  	baseBuiltinFunc
   805  }
   806  
   807  func (b *builtinDateFormatSig) Clone() builtinFunc {
   808  	newSig := &builtinDateFormatSig{}
   809  	newSig.cloneFrom(&b.baseBuiltinFunc)
   810  	return newSig
   811  }
   812  
   813  // evalString evals a builtinDateFormatSig.
   814  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format
   815  func (b *builtinDateFormatSig) evalString(event chunk.Event) (string, bool, error) {
   816  	t, isNull, err := b.args[0].EvalTime(b.ctx, event)
   817  	if isNull || err != nil {
   818  		return "", isNull, handleInvalidTimeError(b.ctx, err)
   819  	}
   820  	formatMask, isNull, err := b.args[1].EvalString(b.ctx, event)
   821  	if isNull || err != nil {
   822  		return "", isNull, err
   823  	}
   824  	// MyALLEGROSQL compatibility, #11203
   825  	// If format mask is 0 then return 0 without warnings
   826  	if formatMask == "0" {
   827  		return "0", false, nil
   828  	}
   829  
   830  	if t.InvalidZero() {
   831  		// MyALLEGROSQL compatibility, #11203
   832  		// 0 | 0.0 should be converted to null without warnings
   833  		n, err := t.ToNumber().ToInt()
   834  		isOriginalIntOrDecimalZero := err == nil && n == 0
   835  		// Args like "0000-00-00", "0000-00-00 00:00:00" set Fsp to 6
   836  		isOriginalStringZero := t.Fsp() > 0
   837  		if isOriginalIntOrDecimalZero && !isOriginalStringZero {
   838  			return "", true, nil
   839  		}
   840  		return "", true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, t.String()))
   841  	}
   842  
   843  	res, err := t.DateFormat(formatMask)
   844  	return res, isNull, err
   845  }
   846  
   847  type fromDaysFunctionClass struct {
   848  	baseFunctionClass
   849  }
   850  
   851  func (c *fromDaysFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   852  	if err := c.verifyArgs(args); err != nil {
   853  		return nil, err
   854  	}
   855  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDatetime, types.ETInt)
   856  	if err != nil {
   857  		return nil, err
   858  	}
   859  	bf.tp.Flen, bf.tp.Decimal = 10, 0
   860  	sig := &builtinFromDaysSig{bf}
   861  	sig.setPbCode(fidelpb.ScalarFuncSig_FromDays)
   862  	return sig, nil
   863  }
   864  
   865  type builtinFromDaysSig struct {
   866  	baseBuiltinFunc
   867  }
   868  
   869  func (b *builtinFromDaysSig) Clone() builtinFunc {
   870  	newSig := &builtinFromDaysSig{}
   871  	newSig.cloneFrom(&b.baseBuiltinFunc)
   872  	return newSig
   873  }
   874  
   875  // evalTime evals FROM_DAYS(N).
   876  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_from-days
   877  func (b *builtinFromDaysSig) evalTime(event chunk.Event) (types.Time, bool, error) {
   878  	n, isNull, err := b.args[0].EvalInt(b.ctx, event)
   879  	if isNull || err != nil {
   880  		return types.ZeroTime, true, err
   881  	}
   882  
   883  	return types.TimeFromDays(n), false, nil
   884  }
   885  
   886  type hourFunctionClass struct {
   887  	baseFunctionClass
   888  }
   889  
   890  func (c *hourFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   891  	if err := c.verifyArgs(args); err != nil {
   892  		return nil, err
   893  	}
   894  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETDuration)
   895  	if err != nil {
   896  		return nil, err
   897  	}
   898  	bf.tp.Flen, bf.tp.Decimal = 3, 0
   899  	sig := &builtinHourSig{bf}
   900  	sig.setPbCode(fidelpb.ScalarFuncSig_Hour)
   901  	return sig, nil
   902  }
   903  
   904  type builtinHourSig struct {
   905  	baseBuiltinFunc
   906  }
   907  
   908  func (b *builtinHourSig) Clone() builtinFunc {
   909  	newSig := &builtinHourSig{}
   910  	newSig.cloneFrom(&b.baseBuiltinFunc)
   911  	return newSig
   912  }
   913  
   914  // evalInt evals HOUR(time).
   915  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_hour
   916  func (b *builtinHourSig) evalInt(event chunk.Event) (int64, bool, error) {
   917  	dur, isNull, err := b.args[0].EvalDuration(b.ctx, event)
   918  	// ignore error and return NULL
   919  	if isNull || err != nil {
   920  		return 0, true, nil
   921  	}
   922  	return int64(dur.Hour()), false, nil
   923  }
   924  
   925  type minuteFunctionClass struct {
   926  	baseFunctionClass
   927  }
   928  
   929  func (c *minuteFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   930  	if err := c.verifyArgs(args); err != nil {
   931  		return nil, err
   932  	}
   933  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETDuration)
   934  	if err != nil {
   935  		return nil, err
   936  	}
   937  	bf.tp.Flen, bf.tp.Decimal = 2, 0
   938  	sig := &builtinMinuteSig{bf}
   939  	sig.setPbCode(fidelpb.ScalarFuncSig_Minute)
   940  	return sig, nil
   941  }
   942  
   943  type builtinMinuteSig struct {
   944  	baseBuiltinFunc
   945  }
   946  
   947  func (b *builtinMinuteSig) Clone() builtinFunc {
   948  	newSig := &builtinMinuteSig{}
   949  	newSig.cloneFrom(&b.baseBuiltinFunc)
   950  	return newSig
   951  }
   952  
   953  // evalInt evals MINUTE(time).
   954  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_minute
   955  func (b *builtinMinuteSig) evalInt(event chunk.Event) (int64, bool, error) {
   956  	dur, isNull, err := b.args[0].EvalDuration(b.ctx, event)
   957  	// ignore error and return NULL
   958  	if isNull || err != nil {
   959  		return 0, true, nil
   960  	}
   961  	return int64(dur.Minute()), false, nil
   962  }
   963  
   964  type secondFunctionClass struct {
   965  	baseFunctionClass
   966  }
   967  
   968  func (c *secondFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   969  	if err := c.verifyArgs(args); err != nil {
   970  		return nil, err
   971  	}
   972  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETDuration)
   973  	if err != nil {
   974  		return nil, err
   975  	}
   976  	bf.tp.Flen, bf.tp.Decimal = 2, 0
   977  	sig := &builtinSecondSig{bf}
   978  	sig.setPbCode(fidelpb.ScalarFuncSig_Second)
   979  	return sig, nil
   980  }
   981  
   982  type builtinSecondSig struct {
   983  	baseBuiltinFunc
   984  }
   985  
   986  func (b *builtinSecondSig) Clone() builtinFunc {
   987  	newSig := &builtinSecondSig{}
   988  	newSig.cloneFrom(&b.baseBuiltinFunc)
   989  	return newSig
   990  }
   991  
   992  // evalInt evals SECOND(time).
   993  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_second
   994  func (b *builtinSecondSig) evalInt(event chunk.Event) (int64, bool, error) {
   995  	dur, isNull, err := b.args[0].EvalDuration(b.ctx, event)
   996  	// ignore error and return NULL
   997  	if isNull || err != nil {
   998  		return 0, true, nil
   999  	}
  1000  	return int64(dur.Second()), false, nil
  1001  }
  1002  
  1003  type microSecondFunctionClass struct {
  1004  	baseFunctionClass
  1005  }
  1006  
  1007  func (c *microSecondFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1008  	if err := c.verifyArgs(args); err != nil {
  1009  		return nil, err
  1010  	}
  1011  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETDuration)
  1012  	if err != nil {
  1013  		return nil, err
  1014  	}
  1015  	bf.tp.Flen, bf.tp.Decimal = 6, 0
  1016  	sig := &builtinMicroSecondSig{bf}
  1017  	sig.setPbCode(fidelpb.ScalarFuncSig_MicroSecond)
  1018  	return sig, nil
  1019  }
  1020  
  1021  type builtinMicroSecondSig struct {
  1022  	baseBuiltinFunc
  1023  }
  1024  
  1025  func (b *builtinMicroSecondSig) Clone() builtinFunc {
  1026  	newSig := &builtinMicroSecondSig{}
  1027  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1028  	return newSig
  1029  }
  1030  
  1031  // evalInt evals MICROSECOND(expr).
  1032  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_microsecond
  1033  func (b *builtinMicroSecondSig) evalInt(event chunk.Event) (int64, bool, error) {
  1034  	dur, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  1035  	// ignore error and return NULL
  1036  	if isNull || err != nil {
  1037  		return 0, true, nil
  1038  	}
  1039  	return int64(dur.MicroSecond()), false, nil
  1040  }
  1041  
  1042  type monthFunctionClass struct {
  1043  	baseFunctionClass
  1044  }
  1045  
  1046  func (c *monthFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1047  	if err := c.verifyArgs(args); err != nil {
  1048  		return nil, err
  1049  	}
  1050  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETDatetime)
  1051  	if err != nil {
  1052  		return nil, err
  1053  	}
  1054  	bf.tp.Flen, bf.tp.Decimal = 2, 0
  1055  	sig := &builtinMonthSig{bf}
  1056  	sig.setPbCode(fidelpb.ScalarFuncSig_Month)
  1057  	return sig, nil
  1058  }
  1059  
  1060  type builtinMonthSig struct {
  1061  	baseBuiltinFunc
  1062  }
  1063  
  1064  func (b *builtinMonthSig) Clone() builtinFunc {
  1065  	newSig := &builtinMonthSig{}
  1066  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1067  	return newSig
  1068  }
  1069  
  1070  // evalInt evals MONTH(date).
  1071  // see: https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_month
  1072  func (b *builtinMonthSig) evalInt(event chunk.Event) (int64, bool, error) {
  1073  	date, isNull, err := b.args[0].EvalTime(b.ctx, event)
  1074  
  1075  	if isNull || err != nil {
  1076  		return 0, true, handleInvalidTimeError(b.ctx, err)
  1077  	}
  1078  
  1079  	if date.IsZero() {
  1080  		if b.ctx.GetStochastikVars().ALLEGROSQLMode.HasNoZeroDateMode() {
  1081  			return 0, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, date.String()))
  1082  		}
  1083  		return 0, false, nil
  1084  	}
  1085  
  1086  	return int64(date.Month()), false, nil
  1087  }
  1088  
  1089  // monthNameFunctionClass see https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_monthname
  1090  type monthNameFunctionClass struct {
  1091  	baseFunctionClass
  1092  }
  1093  
  1094  func (c *monthNameFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1095  	if err := c.verifyArgs(args); err != nil {
  1096  		return nil, err
  1097  	}
  1098  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETDatetime)
  1099  	if err != nil {
  1100  		return nil, err
  1101  	}
  1102  	bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo()
  1103  	bf.tp.Flen = 10
  1104  	sig := &builtinMonthNameSig{bf}
  1105  	sig.setPbCode(fidelpb.ScalarFuncSig_MonthName)
  1106  	return sig, nil
  1107  }
  1108  
  1109  type builtinMonthNameSig struct {
  1110  	baseBuiltinFunc
  1111  }
  1112  
  1113  func (b *builtinMonthNameSig) Clone() builtinFunc {
  1114  	newSig := &builtinMonthNameSig{}
  1115  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1116  	return newSig
  1117  }
  1118  
  1119  func (b *builtinMonthNameSig) evalString(event chunk.Event) (string, bool, error) {
  1120  	arg, isNull, err := b.args[0].EvalTime(b.ctx, event)
  1121  	if isNull || err != nil {
  1122  		return "", true, handleInvalidTimeError(b.ctx, err)
  1123  	}
  1124  	mon := arg.Month()
  1125  	if (arg.IsZero() && b.ctx.GetStochastikVars().ALLEGROSQLMode.HasNoZeroDateMode()) || mon < 0 || mon > len(types.MonthNames) {
  1126  		return "", true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, arg.String()))
  1127  	} else if mon == 0 || arg.IsZero() {
  1128  		return "", true, nil
  1129  	}
  1130  	return types.MonthNames[mon-1], false, nil
  1131  }
  1132  
  1133  type dayNameFunctionClass struct {
  1134  	baseFunctionClass
  1135  }
  1136  
  1137  func (c *dayNameFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1138  	if err := c.verifyArgs(args); err != nil {
  1139  		return nil, err
  1140  	}
  1141  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETDatetime)
  1142  	if err != nil {
  1143  		return nil, err
  1144  	}
  1145  	bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo()
  1146  	bf.tp.Flen = 10
  1147  	sig := &builtinDayNameSig{bf}
  1148  	sig.setPbCode(fidelpb.ScalarFuncSig_DayName)
  1149  	return sig, nil
  1150  }
  1151  
  1152  type builtinDayNameSig struct {
  1153  	baseBuiltinFunc
  1154  }
  1155  
  1156  func (b *builtinDayNameSig) Clone() builtinFunc {
  1157  	newSig := &builtinDayNameSig{}
  1158  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1159  	return newSig
  1160  }
  1161  
  1162  func (b *builtinDayNameSig) evalIndex(event chunk.Event) (int64, bool, error) {
  1163  	arg, isNull, err := b.args[0].EvalTime(b.ctx, event)
  1164  	if isNull || err != nil {
  1165  		return 0, isNull, err
  1166  	}
  1167  	if arg.InvalidZero() {
  1168  		return 0, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, arg.String()))
  1169  	}
  1170  	// Monday is 0, ... Sunday = 6 in MyALLEGROSQL
  1171  	// but in go, Sunday is 0, ... Saturday is 6
  1172  	// w will do a conversion.
  1173  	res := (int64(arg.Weekday()) + 6) % 7
  1174  	return res, false, nil
  1175  }
  1176  
  1177  // evalString evals a builtinDayNameSig.
  1178  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_dayname
  1179  func (b *builtinDayNameSig) evalString(event chunk.Event) (string, bool, error) {
  1180  	idx, isNull, err := b.evalIndex(event)
  1181  	if isNull || err != nil {
  1182  		return "", isNull, err
  1183  	}
  1184  	return types.WeekdayNames[idx], false, nil
  1185  }
  1186  
  1187  func (b *builtinDayNameSig) evalReal(event chunk.Event) (float64, bool, error) {
  1188  	idx, isNull, err := b.evalIndex(event)
  1189  	if isNull || err != nil {
  1190  		return 0, isNull, err
  1191  	}
  1192  	return float64(idx), false, nil
  1193  }
  1194  
  1195  func (b *builtinDayNameSig) evalInt(event chunk.Event) (int64, bool, error) {
  1196  	idx, isNull, err := b.evalIndex(event)
  1197  	if isNull || err != nil {
  1198  		return 0, isNull, err
  1199  	}
  1200  	return idx, false, nil
  1201  }
  1202  
  1203  type dayOfMonthFunctionClass struct {
  1204  	baseFunctionClass
  1205  }
  1206  
  1207  func (c *dayOfMonthFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1208  	if err := c.verifyArgs(args); err != nil {
  1209  		return nil, err
  1210  	}
  1211  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETDatetime)
  1212  	if err != nil {
  1213  		return nil, err
  1214  	}
  1215  	bf.tp.Flen = 2
  1216  	sig := &builtinDayOfMonthSig{bf}
  1217  	sig.setPbCode(fidelpb.ScalarFuncSig_DayOfMonth)
  1218  	return sig, nil
  1219  }
  1220  
  1221  type builtinDayOfMonthSig struct {
  1222  	baseBuiltinFunc
  1223  }
  1224  
  1225  func (b *builtinDayOfMonthSig) Clone() builtinFunc {
  1226  	newSig := &builtinDayOfMonthSig{}
  1227  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1228  	return newSig
  1229  }
  1230  
  1231  // evalInt evals a builtinDayOfMonthSig.
  1232  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_dayofmonth
  1233  func (b *builtinDayOfMonthSig) evalInt(event chunk.Event) (int64, bool, error) {
  1234  	arg, isNull, err := b.args[0].EvalTime(b.ctx, event)
  1235  	if isNull || err != nil {
  1236  		return 0, true, handleInvalidTimeError(b.ctx, err)
  1237  	}
  1238  	if arg.IsZero() {
  1239  		if b.ctx.GetStochastikVars().ALLEGROSQLMode.HasNoZeroDateMode() {
  1240  			return 0, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, arg.String()))
  1241  		}
  1242  		return 0, false, nil
  1243  	}
  1244  	return int64(arg.Day()), false, nil
  1245  }
  1246  
  1247  type dayOfWeekFunctionClass struct {
  1248  	baseFunctionClass
  1249  }
  1250  
  1251  func (c *dayOfWeekFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1252  	if err := c.verifyArgs(args); err != nil {
  1253  		return nil, err
  1254  	}
  1255  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETDatetime)
  1256  	if err != nil {
  1257  		return nil, err
  1258  	}
  1259  	bf.tp.Flen = 1
  1260  	sig := &builtinDayOfWeekSig{bf}
  1261  	sig.setPbCode(fidelpb.ScalarFuncSig_DayOfWeek)
  1262  	return sig, nil
  1263  }
  1264  
  1265  type builtinDayOfWeekSig struct {
  1266  	baseBuiltinFunc
  1267  }
  1268  
  1269  func (b *builtinDayOfWeekSig) Clone() builtinFunc {
  1270  	newSig := &builtinDayOfWeekSig{}
  1271  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1272  	return newSig
  1273  }
  1274  
  1275  // evalInt evals a builtinDayOfWeekSig.
  1276  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_dayofweek
  1277  func (b *builtinDayOfWeekSig) evalInt(event chunk.Event) (int64, bool, error) {
  1278  	arg, isNull, err := b.args[0].EvalTime(b.ctx, event)
  1279  	if isNull || err != nil {
  1280  		return 0, true, handleInvalidTimeError(b.ctx, err)
  1281  	}
  1282  	if arg.InvalidZero() {
  1283  		return 0, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, arg.String()))
  1284  	}
  1285  	// 1 is Sunday, 2 is Monday, .... 7 is Saturday
  1286  	return int64(arg.Weekday() + 1), false, nil
  1287  }
  1288  
  1289  type dayOfYearFunctionClass struct {
  1290  	baseFunctionClass
  1291  }
  1292  
  1293  func (c *dayOfYearFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1294  	if err := c.verifyArgs(args); err != nil {
  1295  		return nil, err
  1296  	}
  1297  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETDatetime)
  1298  	if err != nil {
  1299  		return nil, err
  1300  	}
  1301  	bf.tp.Flen = 3
  1302  	sig := &builtinDayOfYearSig{bf}
  1303  	sig.setPbCode(fidelpb.ScalarFuncSig_DayOfYear)
  1304  	return sig, nil
  1305  }
  1306  
  1307  type builtinDayOfYearSig struct {
  1308  	baseBuiltinFunc
  1309  }
  1310  
  1311  func (b *builtinDayOfYearSig) Clone() builtinFunc {
  1312  	newSig := &builtinDayOfYearSig{}
  1313  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1314  	return newSig
  1315  }
  1316  
  1317  // evalInt evals a builtinDayOfYearSig.
  1318  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_dayofyear
  1319  func (b *builtinDayOfYearSig) evalInt(event chunk.Event) (int64, bool, error) {
  1320  	arg, isNull, err := b.args[0].EvalTime(b.ctx, event)
  1321  	if isNull || err != nil {
  1322  		return 0, isNull, handleInvalidTimeError(b.ctx, err)
  1323  	}
  1324  	if arg.InvalidZero() {
  1325  		return 0, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, arg.String()))
  1326  	}
  1327  
  1328  	return int64(arg.YearDay()), false, nil
  1329  }
  1330  
  1331  type weekFunctionClass struct {
  1332  	baseFunctionClass
  1333  }
  1334  
  1335  func (c *weekFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1336  	if err := c.verifyArgs(args); err != nil {
  1337  		return nil, err
  1338  	}
  1339  
  1340  	argTps := []types.EvalType{types.ETDatetime}
  1341  	if len(args) == 2 {
  1342  		argTps = append(argTps, types.ETInt)
  1343  	}
  1344  
  1345  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, argTps...)
  1346  	if err != nil {
  1347  		return nil, err
  1348  	}
  1349  
  1350  	bf.tp.Flen, bf.tp.Decimal = 2, 0
  1351  
  1352  	var sig builtinFunc
  1353  	if len(args) == 2 {
  1354  		sig = &builtinWeekWithModeSig{bf}
  1355  		sig.setPbCode(fidelpb.ScalarFuncSig_WeekWithMode)
  1356  	} else {
  1357  		sig = &builtinWeekWithoutModeSig{bf}
  1358  		sig.setPbCode(fidelpb.ScalarFuncSig_WeekWithoutMode)
  1359  	}
  1360  	return sig, nil
  1361  }
  1362  
  1363  type builtinWeekWithModeSig struct {
  1364  	baseBuiltinFunc
  1365  }
  1366  
  1367  func (b *builtinWeekWithModeSig) Clone() builtinFunc {
  1368  	newSig := &builtinWeekWithModeSig{}
  1369  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1370  	return newSig
  1371  }
  1372  
  1373  // evalInt evals WEEK(date, mode).
  1374  // see: https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_week
  1375  func (b *builtinWeekWithModeSig) evalInt(event chunk.Event) (int64, bool, error) {
  1376  	date, isNull, err := b.args[0].EvalTime(b.ctx, event)
  1377  
  1378  	if isNull || err != nil {
  1379  		return 0, true, handleInvalidTimeError(b.ctx, err)
  1380  	}
  1381  
  1382  	if date.IsZero() {
  1383  		return 0, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, date.String()))
  1384  	}
  1385  
  1386  	mode, isNull, err := b.args[1].EvalInt(b.ctx, event)
  1387  	if isNull || err != nil {
  1388  		return 0, isNull, err
  1389  	}
  1390  
  1391  	week := date.Week(int(mode))
  1392  	return int64(week), false, nil
  1393  }
  1394  
  1395  type builtinWeekWithoutModeSig struct {
  1396  	baseBuiltinFunc
  1397  }
  1398  
  1399  func (b *builtinWeekWithoutModeSig) Clone() builtinFunc {
  1400  	newSig := &builtinWeekWithoutModeSig{}
  1401  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1402  	return newSig
  1403  }
  1404  
  1405  // evalInt evals WEEK(date).
  1406  // see: https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_week
  1407  func (b *builtinWeekWithoutModeSig) evalInt(event chunk.Event) (int64, bool, error) {
  1408  	date, isNull, err := b.args[0].EvalTime(b.ctx, event)
  1409  
  1410  	if isNull || err != nil {
  1411  		return 0, true, handleInvalidTimeError(b.ctx, err)
  1412  	}
  1413  
  1414  	if date.IsZero() {
  1415  		return 0, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, date.String()))
  1416  	}
  1417  
  1418  	mode := 0
  1419  	modeStr, ok := b.ctx.GetStochastikVars().GetSystemVar(variable.DefaultWeekFormat)
  1420  	if ok && modeStr != "" {
  1421  		mode, err = strconv.Atoi(modeStr)
  1422  		if err != nil {
  1423  			return 0, true, handleInvalidTimeError(b.ctx, types.ErrInvalidWeekModeFormat.GenWithStackByArgs(modeStr))
  1424  		}
  1425  	}
  1426  
  1427  	week := date.Week(mode)
  1428  	return int64(week), false, nil
  1429  }
  1430  
  1431  type weekDayFunctionClass struct {
  1432  	baseFunctionClass
  1433  }
  1434  
  1435  func (c *weekDayFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1436  	if err := c.verifyArgs(args); err != nil {
  1437  		return nil, err
  1438  	}
  1439  
  1440  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETDatetime)
  1441  	if err != nil {
  1442  		return nil, err
  1443  	}
  1444  	bf.tp.Flen = 1
  1445  
  1446  	sig := &builtinWeekDaySig{bf}
  1447  	sig.setPbCode(fidelpb.ScalarFuncSig_WeekDay)
  1448  	return sig, nil
  1449  }
  1450  
  1451  type builtinWeekDaySig struct {
  1452  	baseBuiltinFunc
  1453  }
  1454  
  1455  func (b *builtinWeekDaySig) Clone() builtinFunc {
  1456  	newSig := &builtinWeekDaySig{}
  1457  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1458  	return newSig
  1459  }
  1460  
  1461  // evalInt evals WEEKDAY(date).
  1462  func (b *builtinWeekDaySig) evalInt(event chunk.Event) (int64, bool, error) {
  1463  	date, isNull, err := b.args[0].EvalTime(b.ctx, event)
  1464  	if isNull || err != nil {
  1465  		return 0, true, handleInvalidTimeError(b.ctx, err)
  1466  	}
  1467  
  1468  	if date.IsZero() {
  1469  		return 0, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, date.String()))
  1470  	}
  1471  
  1472  	return int64(date.Weekday()+6) % 7, false, nil
  1473  }
  1474  
  1475  type weekOfYearFunctionClass struct {
  1476  	baseFunctionClass
  1477  }
  1478  
  1479  func (c *weekOfYearFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1480  	if err := c.verifyArgs(args); err != nil {
  1481  		return nil, err
  1482  	}
  1483  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETDatetime)
  1484  	if err != nil {
  1485  		return nil, err
  1486  	}
  1487  	bf.tp.Flen, bf.tp.Decimal = 2, 0
  1488  	sig := &builtinWeekOfYearSig{bf}
  1489  	sig.setPbCode(fidelpb.ScalarFuncSig_WeekOfYear)
  1490  	return sig, nil
  1491  }
  1492  
  1493  type builtinWeekOfYearSig struct {
  1494  	baseBuiltinFunc
  1495  }
  1496  
  1497  func (b *builtinWeekOfYearSig) Clone() builtinFunc {
  1498  	newSig := &builtinWeekOfYearSig{}
  1499  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1500  	return newSig
  1501  }
  1502  
  1503  // evalInt evals WEEKOFYEAR(date).
  1504  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_weekofyear
  1505  func (b *builtinWeekOfYearSig) evalInt(event chunk.Event) (int64, bool, error) {
  1506  	date, isNull, err := b.args[0].EvalTime(b.ctx, event)
  1507  
  1508  	if isNull || err != nil {
  1509  		return 0, true, handleInvalidTimeError(b.ctx, err)
  1510  	}
  1511  
  1512  	if date.IsZero() {
  1513  		return 0, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, date.String()))
  1514  	}
  1515  
  1516  	week := date.Week(3)
  1517  	return int64(week), false, nil
  1518  }
  1519  
  1520  type yearFunctionClass struct {
  1521  	baseFunctionClass
  1522  }
  1523  
  1524  func (c *yearFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1525  	if err := c.verifyArgs(args); err != nil {
  1526  		return nil, err
  1527  	}
  1528  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETDatetime)
  1529  	if err != nil {
  1530  		return nil, err
  1531  	}
  1532  	bf.tp.Flen, bf.tp.Decimal = 4, 0
  1533  	sig := &builtinYearSig{bf}
  1534  	sig.setPbCode(fidelpb.ScalarFuncSig_Year)
  1535  	return sig, nil
  1536  }
  1537  
  1538  type builtinYearSig struct {
  1539  	baseBuiltinFunc
  1540  }
  1541  
  1542  func (b *builtinYearSig) Clone() builtinFunc {
  1543  	newSig := &builtinYearSig{}
  1544  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1545  	return newSig
  1546  }
  1547  
  1548  // evalInt evals YEAR(date).
  1549  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_year
  1550  func (b *builtinYearSig) evalInt(event chunk.Event) (int64, bool, error) {
  1551  	date, isNull, err := b.args[0].EvalTime(b.ctx, event)
  1552  
  1553  	if isNull || err != nil {
  1554  		return 0, true, handleInvalidTimeError(b.ctx, err)
  1555  	}
  1556  
  1557  	if date.IsZero() {
  1558  		if b.ctx.GetStochastikVars().ALLEGROSQLMode.HasNoZeroDateMode() {
  1559  			return 0, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, date.String()))
  1560  		}
  1561  		return 0, false, nil
  1562  	}
  1563  	return int64(date.Year()), false, nil
  1564  }
  1565  
  1566  type yearWeekFunctionClass struct {
  1567  	baseFunctionClass
  1568  }
  1569  
  1570  func (c *yearWeekFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1571  	if err := c.verifyArgs(args); err != nil {
  1572  		return nil, err
  1573  	}
  1574  	argTps := []types.EvalType{types.ETDatetime}
  1575  	if len(args) == 2 {
  1576  		argTps = append(argTps, types.ETInt)
  1577  	}
  1578  
  1579  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, argTps...)
  1580  	if err != nil {
  1581  		return nil, err
  1582  	}
  1583  
  1584  	bf.tp.Flen, bf.tp.Decimal = 6, 0
  1585  
  1586  	var sig builtinFunc
  1587  	if len(args) == 2 {
  1588  		sig = &builtinYearWeekWithModeSig{bf}
  1589  		sig.setPbCode(fidelpb.ScalarFuncSig_YearWeekWithMode)
  1590  	} else {
  1591  		sig = &builtinYearWeekWithoutModeSig{bf}
  1592  		sig.setPbCode(fidelpb.ScalarFuncSig_YearWeekWithoutMode)
  1593  	}
  1594  	return sig, nil
  1595  }
  1596  
  1597  type builtinYearWeekWithModeSig struct {
  1598  	baseBuiltinFunc
  1599  }
  1600  
  1601  func (b *builtinYearWeekWithModeSig) Clone() builtinFunc {
  1602  	newSig := &builtinYearWeekWithModeSig{}
  1603  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1604  	return newSig
  1605  }
  1606  
  1607  // evalInt evals YEARWEEK(date,mode).
  1608  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_yearweek
  1609  func (b *builtinYearWeekWithModeSig) evalInt(event chunk.Event) (int64, bool, error) {
  1610  	date, isNull, err := b.args[0].EvalTime(b.ctx, event)
  1611  	if isNull || err != nil {
  1612  		return 0, isNull, handleInvalidTimeError(b.ctx, err)
  1613  	}
  1614  	if date.IsZero() {
  1615  		return 0, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, date.String()))
  1616  	}
  1617  
  1618  	mode, isNull, err := b.args[1].EvalInt(b.ctx, event)
  1619  	if err != nil {
  1620  		return 0, true, err
  1621  	}
  1622  	if isNull {
  1623  		mode = 0
  1624  	}
  1625  
  1626  	year, week := date.YearWeek(int(mode))
  1627  	result := int64(week + year*100)
  1628  	if result < 0 {
  1629  		return int64(math.MaxUint32), false, nil
  1630  	}
  1631  	return result, false, nil
  1632  }
  1633  
  1634  type builtinYearWeekWithoutModeSig struct {
  1635  	baseBuiltinFunc
  1636  }
  1637  
  1638  func (b *builtinYearWeekWithoutModeSig) Clone() builtinFunc {
  1639  	newSig := &builtinYearWeekWithoutModeSig{}
  1640  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1641  	return newSig
  1642  }
  1643  
  1644  // evalInt evals YEARWEEK(date).
  1645  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_yearweek
  1646  func (b *builtinYearWeekWithoutModeSig) evalInt(event chunk.Event) (int64, bool, error) {
  1647  	date, isNull, err := b.args[0].EvalTime(b.ctx, event)
  1648  	if isNull || err != nil {
  1649  		return 0, true, handleInvalidTimeError(b.ctx, err)
  1650  	}
  1651  
  1652  	if date.InvalidZero() {
  1653  		return 0, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, date.String()))
  1654  	}
  1655  
  1656  	year, week := date.YearWeek(0)
  1657  	result := int64(week + year*100)
  1658  	if result < 0 {
  1659  		return int64(math.MaxUint32), false, nil
  1660  	}
  1661  	return result, false, nil
  1662  }
  1663  
  1664  type fromUnixTimeFunctionClass struct {
  1665  	baseFunctionClass
  1666  }
  1667  
  1668  func (c *fromUnixTimeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) {
  1669  	if err = c.verifyArgs(args); err != nil {
  1670  		return nil, err
  1671  	}
  1672  
  1673  	retTp, argTps := types.ETDatetime, make([]types.EvalType, 0, len(args))
  1674  	argTps = append(argTps, types.ETDecimal)
  1675  	if len(args) == 2 {
  1676  		retTp = types.ETString
  1677  		argTps = append(argTps, types.ETString)
  1678  	}
  1679  
  1680  	isArg0Str := args[0].GetType().EvalType() == types.ETString
  1681  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, retTp, argTps...)
  1682  	if err != nil {
  1683  		return nil, err
  1684  	}
  1685  
  1686  	if len(args) > 1 {
  1687  		bf.tp.Flen = args[1].GetType().Flen
  1688  		sig = &builtinFromUnixTime2ArgSig{bf}
  1689  		sig.setPbCode(fidelpb.ScalarFuncSig_FromUnixTime2Arg)
  1690  		return sig, nil
  1691  	}
  1692  
  1693  	// Calculate the time fsp.
  1694  	bf.tp.Decimal = int(types.MaxFsp)
  1695  	if !isArg0Str {
  1696  		if args[0].GetType().Decimal != types.UnspecifiedLength {
  1697  			bf.tp.Decimal = mathutil.Min(bf.tp.Decimal, args[0].GetType().Decimal)
  1698  		}
  1699  	}
  1700  
  1701  	sig = &builtinFromUnixTime1ArgSig{bf}
  1702  	sig.setPbCode(fidelpb.ScalarFuncSig_FromUnixTime1Arg)
  1703  	return sig, nil
  1704  }
  1705  
  1706  func evalFromUnixTime(ctx stochastikctx.Context, fsp int8, unixTimeStamp *types.MyDecimal) (res types.Time, isNull bool, err error) {
  1707  	// 0 <= unixTimeStamp <= INT32_MAX
  1708  	if unixTimeStamp.IsNegative() {
  1709  		return res, true, nil
  1710  	}
  1711  	integralPart, err := unixTimeStamp.ToInt()
  1712  	if err != nil && !terror.ErrorEqual(err, types.ErrTruncated) {
  1713  		return res, true, err
  1714  	}
  1715  	if integralPart > int64(math.MaxInt32) {
  1716  		return res, true, nil
  1717  	}
  1718  	// Split the integral part and fractional part of a decimal timestamp.
  1719  	// e.g. for timestamp 12345.678,
  1720  	// first get the integral part 12345,
  1721  	// then (12345.678 - 12345) * (10^9) to get the decimal part and convert it to nanosecond precision.
  1722  	integerDecimalTp := new(types.MyDecimal).FromInt(integralPart)
  1723  	fracDecimalTp := new(types.MyDecimal)
  1724  	err = types.DecimalSub(unixTimeStamp, integerDecimalTp, fracDecimalTp)
  1725  	if err != nil {
  1726  		return res, true, err
  1727  	}
  1728  	nano := new(types.MyDecimal).FromInt(int64(time.Second))
  1729  	x := new(types.MyDecimal)
  1730  	err = types.DecimalMul(fracDecimalTp, nano, x)
  1731  	if err != nil {
  1732  		return res, true, err
  1733  	}
  1734  	fractionalPart, err := x.ToInt() // here fractionalPart is result multiplying the original fractional part by 10^9.
  1735  	if err != nil && !terror.ErrorEqual(err, types.ErrTruncated) {
  1736  		return res, true, err
  1737  	}
  1738  	if fsp < 0 {
  1739  		fsp = types.MaxFsp
  1740  	}
  1741  
  1742  	sc := ctx.GetStochastikVars().StmtCtx
  1743  	tmp := time.Unix(integralPart, fractionalPart).In(sc.TimeZone)
  1744  	t, err := convertTimeToMysqlTime(tmp, fsp, types.ModeHalfEven)
  1745  	if err != nil {
  1746  		return res, true, err
  1747  	}
  1748  	return t, false, nil
  1749  }
  1750  
  1751  type builtinFromUnixTime1ArgSig struct {
  1752  	baseBuiltinFunc
  1753  }
  1754  
  1755  func (b *builtinFromUnixTime1ArgSig) Clone() builtinFunc {
  1756  	newSig := &builtinFromUnixTime1ArgSig{}
  1757  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1758  	return newSig
  1759  }
  1760  
  1761  // evalTime evals a builtinFromUnixTime1ArgSig.
  1762  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_from-unixtime
  1763  func (b *builtinFromUnixTime1ArgSig) evalTime(event chunk.Event) (res types.Time, isNull bool, err error) {
  1764  	unixTimeStamp, isNull, err := b.args[0].EvalDecimal(b.ctx, event)
  1765  	if err != nil || isNull {
  1766  		return res, isNull, err
  1767  	}
  1768  	return evalFromUnixTime(b.ctx, int8(b.tp.Decimal), unixTimeStamp)
  1769  }
  1770  
  1771  type builtinFromUnixTime2ArgSig struct {
  1772  	baseBuiltinFunc
  1773  }
  1774  
  1775  func (b *builtinFromUnixTime2ArgSig) Clone() builtinFunc {
  1776  	newSig := &builtinFromUnixTime2ArgSig{}
  1777  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1778  	return newSig
  1779  }
  1780  
  1781  // evalString evals a builtinFromUnixTime2ArgSig.
  1782  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_from-unixtime
  1783  func (b *builtinFromUnixTime2ArgSig) evalString(event chunk.Event) (res string, isNull bool, err error) {
  1784  	format, isNull, err := b.args[1].EvalString(b.ctx, event)
  1785  	if isNull || err != nil {
  1786  		return "", true, err
  1787  	}
  1788  	unixTimeStamp, isNull, err := b.args[0].EvalDecimal(b.ctx, event)
  1789  	if err != nil || isNull {
  1790  		return "", isNull, err
  1791  	}
  1792  	t, isNull, err := evalFromUnixTime(b.ctx, int8(b.tp.Decimal), unixTimeStamp)
  1793  	if isNull || err != nil {
  1794  		return "", isNull, err
  1795  	}
  1796  	res, err = t.DateFormat(format)
  1797  	return res, err != nil, err
  1798  }
  1799  
  1800  type getFormatFunctionClass struct {
  1801  	baseFunctionClass
  1802  }
  1803  
  1804  func (c *getFormatFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1805  	if err := c.verifyArgs(args); err != nil {
  1806  		return nil, err
  1807  	}
  1808  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString, types.ETString)
  1809  	if err != nil {
  1810  		return nil, err
  1811  	}
  1812  	bf.tp.Flen = 17
  1813  	sig := &builtinGetFormatSig{bf}
  1814  	sig.setPbCode(fidelpb.ScalarFuncSig_GetFormat)
  1815  	return sig, nil
  1816  }
  1817  
  1818  type builtinGetFormatSig struct {
  1819  	baseBuiltinFunc
  1820  }
  1821  
  1822  func (b *builtinGetFormatSig) Clone() builtinFunc {
  1823  	newSig := &builtinGetFormatSig{}
  1824  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1825  	return newSig
  1826  }
  1827  
  1828  // evalString evals a builtinGetFormatSig.
  1829  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_get-format
  1830  func (b *builtinGetFormatSig) evalString(event chunk.Event) (string, bool, error) {
  1831  	t, isNull, err := b.args[0].EvalString(b.ctx, event)
  1832  	if isNull || err != nil {
  1833  		return "", isNull, err
  1834  	}
  1835  	l, isNull, err := b.args[1].EvalString(b.ctx, event)
  1836  	if isNull || err != nil {
  1837  		return "", isNull, err
  1838  	}
  1839  
  1840  	res := b.getFormat(t, l)
  1841  	return res, false, nil
  1842  }
  1843  
  1844  type strToDateFunctionClass struct {
  1845  	baseFunctionClass
  1846  }
  1847  
  1848  func (c *strToDateFunctionClass) getRetTp(ctx stochastikctx.Context, arg Expression) (tp byte, fsp int8) {
  1849  	tp = allegrosql.TypeDatetime
  1850  	if _, ok := arg.(*Constant); !ok {
  1851  		return tp, types.MaxFsp
  1852  	}
  1853  	strArg := WrapWithCastAsString(ctx, arg)
  1854  	format, isNull, err := strArg.EvalString(ctx, chunk.Event{})
  1855  	if err != nil || isNull {
  1856  		return
  1857  	}
  1858  
  1859  	isDuration, isDate := types.GetFormatType(format)
  1860  	if isDuration && !isDate {
  1861  		tp = allegrosql.TypeDuration
  1862  	} else if !isDuration && isDate {
  1863  		tp = allegrosql.TypeDate
  1864  	}
  1865  	if strings.Contains(format, "%f") {
  1866  		fsp = types.MaxFsp
  1867  	}
  1868  	return
  1869  }
  1870  
  1871  // getFunction see https://dev.allegrosql.com/doc/refman/5.5/en/date-and-time-functions.html#function_str-to-date
  1872  func (c *strToDateFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) {
  1873  	if err := c.verifyArgs(args); err != nil {
  1874  		return nil, err
  1875  	}
  1876  	retTp, fsp := c.getRetTp(ctx, args[1])
  1877  	switch retTp {
  1878  	case allegrosql.TypeDate:
  1879  		bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDatetime, types.ETString, types.ETString)
  1880  		if err != nil {
  1881  			return nil, err
  1882  		}
  1883  		bf.tp.Tp, bf.tp.Flen, bf.tp.Decimal = allegrosql.TypeDate, allegrosql.MaxDateWidth, int(types.MinFsp)
  1884  		sig = &builtinStrToDateDateSig{bf}
  1885  		sig.setPbCode(fidelpb.ScalarFuncSig_StrToDateDate)
  1886  	case allegrosql.TypeDatetime:
  1887  		bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDatetime, types.ETString, types.ETString)
  1888  		if err != nil {
  1889  			return nil, err
  1890  		}
  1891  		if fsp == types.MinFsp {
  1892  			bf.tp.Flen, bf.tp.Decimal = allegrosql.MaxDatetimeWidthNoFsp, int(types.MinFsp)
  1893  		} else {
  1894  			bf.tp.Flen, bf.tp.Decimal = allegrosql.MaxDatetimeWidthWithFsp, int(types.MaxFsp)
  1895  		}
  1896  		sig = &builtinStrToDateDatetimeSig{bf}
  1897  		sig.setPbCode(fidelpb.ScalarFuncSig_StrToDateDatetime)
  1898  	case allegrosql.TypeDuration:
  1899  		bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDuration, types.ETString, types.ETString)
  1900  		if err != nil {
  1901  			return nil, err
  1902  		}
  1903  		if fsp == types.MinFsp {
  1904  			bf.tp.Flen, bf.tp.Decimal = allegrosql.MaxDurationWidthNoFsp, int(types.MinFsp)
  1905  		} else {
  1906  			bf.tp.Flen, bf.tp.Decimal = allegrosql.MaxDurationWidthWithFsp, int(types.MaxFsp)
  1907  		}
  1908  		sig = &builtinStrToDateDurationSig{bf}
  1909  		sig.setPbCode(fidelpb.ScalarFuncSig_StrToDateDuration)
  1910  	}
  1911  	return sig, nil
  1912  }
  1913  
  1914  type builtinStrToDateDateSig struct {
  1915  	baseBuiltinFunc
  1916  }
  1917  
  1918  func (b *builtinStrToDateDateSig) Clone() builtinFunc {
  1919  	newSig := &builtinStrToDateDateSig{}
  1920  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1921  	return newSig
  1922  }
  1923  
  1924  func (b *builtinStrToDateDateSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  1925  	date, isNull, err := b.args[0].EvalString(b.ctx, event)
  1926  	if isNull || err != nil {
  1927  		return types.ZeroTime, isNull, err
  1928  	}
  1929  	format, isNull, err := b.args[1].EvalString(b.ctx, event)
  1930  	if isNull || err != nil {
  1931  		return types.ZeroTime, isNull, err
  1932  	}
  1933  	var t types.Time
  1934  	sc := b.ctx.GetStochastikVars().StmtCtx
  1935  	succ := t.StrToDate(sc, date, format)
  1936  	if !succ {
  1937  		return types.ZeroTime, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, t.String()))
  1938  	}
  1939  	if b.ctx.GetStochastikVars().ALLEGROSQLMode.HasNoZeroDateMode() && (t.Year() == 0 || t.Month() == 0 || t.Day() == 0) {
  1940  		return types.ZeroTime, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, t.String()))
  1941  	}
  1942  	t.SetType(allegrosql.TypeDate)
  1943  	t.SetFsp(types.MinFsp)
  1944  	return t, false, nil
  1945  }
  1946  
  1947  type builtinStrToDateDatetimeSig struct {
  1948  	baseBuiltinFunc
  1949  }
  1950  
  1951  func (b *builtinStrToDateDatetimeSig) Clone() builtinFunc {
  1952  	newSig := &builtinStrToDateDatetimeSig{}
  1953  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1954  	return newSig
  1955  }
  1956  
  1957  func (b *builtinStrToDateDatetimeSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  1958  	date, isNull, err := b.args[0].EvalString(b.ctx, event)
  1959  	if isNull || err != nil {
  1960  		return types.ZeroTime, isNull, err
  1961  	}
  1962  	format, isNull, err := b.args[1].EvalString(b.ctx, event)
  1963  	if isNull || err != nil {
  1964  		return types.ZeroTime, isNull, err
  1965  	}
  1966  	var t types.Time
  1967  	sc := b.ctx.GetStochastikVars().StmtCtx
  1968  	succ := t.StrToDate(sc, date, format)
  1969  	if !succ {
  1970  		return types.ZeroTime, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, t.String()))
  1971  	}
  1972  	if b.ctx.GetStochastikVars().ALLEGROSQLMode.HasNoZeroDateMode() && (t.Year() == 0 || t.Month() == 0 || t.Day() == 0) {
  1973  		return types.ZeroTime, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, t.String()))
  1974  	}
  1975  	t.SetType(allegrosql.TypeDatetime)
  1976  	t.SetFsp(int8(b.tp.Decimal))
  1977  	return t, false, nil
  1978  }
  1979  
  1980  type builtinStrToDateDurationSig struct {
  1981  	baseBuiltinFunc
  1982  }
  1983  
  1984  func (b *builtinStrToDateDurationSig) Clone() builtinFunc {
  1985  	newSig := &builtinStrToDateDurationSig{}
  1986  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1987  	return newSig
  1988  }
  1989  
  1990  // evalDuration
  1991  // TODO: If the NO_ZERO_DATE or NO_ZERO_IN_DATE ALLEGROALLEGROSQL mode is enabled, zero dates or part of dates are disallowed.
  1992  // In that case, STR_TO_DATE() returns NULL and generates a warning.
  1993  func (b *builtinStrToDateDurationSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  1994  	date, isNull, err := b.args[0].EvalString(b.ctx, event)
  1995  	if isNull || err != nil {
  1996  		return types.Duration{}, isNull, err
  1997  	}
  1998  	format, isNull, err := b.args[1].EvalString(b.ctx, event)
  1999  	if isNull || err != nil {
  2000  		return types.Duration{}, isNull, err
  2001  	}
  2002  	var t types.Time
  2003  	sc := b.ctx.GetStochastikVars().StmtCtx
  2004  	succ := t.StrToDate(sc, date, format)
  2005  	if !succ {
  2006  		return types.Duration{}, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, t.String()))
  2007  	}
  2008  	if b.ctx.GetStochastikVars().ALLEGROSQLMode.HasNoZeroDateMode() && (t.Year() == 0 || t.Month() == 0 || t.Day() == 0) {
  2009  		return types.Duration{}, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, t.String()))
  2010  	}
  2011  	t.SetFsp(int8(b.tp.Decimal))
  2012  	dur, err := t.ConvertToDuration()
  2013  	return dur, err != nil, err
  2014  }
  2015  
  2016  type sysDateFunctionClass struct {
  2017  	baseFunctionClass
  2018  }
  2019  
  2020  func (c *sysDateFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  2021  	if err := c.verifyArgs(args); err != nil {
  2022  		return nil, err
  2023  	}
  2024  	var argTps = make([]types.EvalType, 0)
  2025  	if len(args) == 1 {
  2026  		argTps = append(argTps, types.ETInt)
  2027  	}
  2028  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDatetime, argTps...)
  2029  	if err != nil {
  2030  		return nil, err
  2031  	}
  2032  	bf.tp.Flen, bf.tp.Decimal = 19, 0
  2033  
  2034  	var sig builtinFunc
  2035  	if len(args) == 1 {
  2036  		sig = &builtinSysDateWithFspSig{bf}
  2037  		sig.setPbCode(fidelpb.ScalarFuncSig_SysDateWithFsp)
  2038  	} else {
  2039  		sig = &builtinSysDateWithoutFspSig{bf}
  2040  		sig.setPbCode(fidelpb.ScalarFuncSig_SysDateWithoutFsp)
  2041  	}
  2042  	return sig, nil
  2043  }
  2044  
  2045  type builtinSysDateWithFspSig struct {
  2046  	baseBuiltinFunc
  2047  }
  2048  
  2049  func (b *builtinSysDateWithFspSig) Clone() builtinFunc {
  2050  	newSig := &builtinSysDateWithFspSig{}
  2051  	newSig.cloneFrom(&b.baseBuiltinFunc)
  2052  	return newSig
  2053  }
  2054  
  2055  // evalTime evals SYSDATE(fsp).
  2056  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_sysdate
  2057  func (b *builtinSysDateWithFspSig) evalTime(event chunk.Event) (d types.Time, isNull bool, err error) {
  2058  	fsp, isNull, err := b.args[0].EvalInt(b.ctx, event)
  2059  	if isNull || err != nil {
  2060  		return types.ZeroTime, isNull, err
  2061  	}
  2062  
  2063  	loc := b.ctx.GetStochastikVars().Location()
  2064  	now := time.Now().In(loc)
  2065  	result, err := convertTimeToMysqlTime(now, int8(fsp), types.ModeHalfEven)
  2066  	if err != nil {
  2067  		return types.ZeroTime, true, err
  2068  	}
  2069  	return result, false, nil
  2070  }
  2071  
  2072  type builtinSysDateWithoutFspSig struct {
  2073  	baseBuiltinFunc
  2074  }
  2075  
  2076  func (b *builtinSysDateWithoutFspSig) Clone() builtinFunc {
  2077  	newSig := &builtinSysDateWithoutFspSig{}
  2078  	newSig.cloneFrom(&b.baseBuiltinFunc)
  2079  	return newSig
  2080  }
  2081  
  2082  // evalTime evals SYSDATE().
  2083  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_sysdate
  2084  func (b *builtinSysDateWithoutFspSig) evalTime(event chunk.Event) (d types.Time, isNull bool, err error) {
  2085  	tz := b.ctx.GetStochastikVars().Location()
  2086  	now := time.Now().In(tz)
  2087  	result, err := convertTimeToMysqlTime(now, 0, types.ModeHalfEven)
  2088  	if err != nil {
  2089  		return types.ZeroTime, true, err
  2090  	}
  2091  	return result, false, nil
  2092  }
  2093  
  2094  type currentDateFunctionClass struct {
  2095  	baseFunctionClass
  2096  }
  2097  
  2098  func (c *currentDateFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  2099  	if err := c.verifyArgs(args); err != nil {
  2100  		return nil, err
  2101  	}
  2102  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDatetime)
  2103  	if err != nil {
  2104  		return nil, err
  2105  	}
  2106  	bf.tp.Flen, bf.tp.Decimal = 10, 0
  2107  	sig := &builtinCurrentDateSig{bf}
  2108  	return sig, nil
  2109  }
  2110  
  2111  type builtinCurrentDateSig struct {
  2112  	baseBuiltinFunc
  2113  }
  2114  
  2115  func (b *builtinCurrentDateSig) Clone() builtinFunc {
  2116  	newSig := &builtinCurrentDateSig{}
  2117  	newSig.cloneFrom(&b.baseBuiltinFunc)
  2118  	return newSig
  2119  }
  2120  
  2121  // evalTime evals CURDATE().
  2122  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_curdate
  2123  func (b *builtinCurrentDateSig) evalTime(event chunk.Event) (d types.Time, isNull bool, err error) {
  2124  	tz := b.ctx.GetStochastikVars().Location()
  2125  	nowTs, err := getStmtTimestamp(b.ctx)
  2126  	if err != nil {
  2127  		return types.ZeroTime, true, err
  2128  	}
  2129  	year, month, day := nowTs.In(tz).Date()
  2130  	result := types.NewTime(types.FromDate(year, int(month), day, 0, 0, 0, 0), allegrosql.TypeDate, 0)
  2131  	return result, false, nil
  2132  }
  2133  
  2134  type currentTimeFunctionClass struct {
  2135  	baseFunctionClass
  2136  }
  2137  
  2138  func (c *currentTimeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) {
  2139  	if err = c.verifyArgs(args); err != nil {
  2140  		return nil, err
  2141  	}
  2142  
  2143  	if len(args) == 0 {
  2144  		bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDuration)
  2145  		if err != nil {
  2146  			return nil, err
  2147  		}
  2148  		bf.tp.Flen, bf.tp.Decimal = allegrosql.MaxDurationWidthNoFsp, int(types.MinFsp)
  2149  		sig = &builtinCurrentTime0ArgSig{bf}
  2150  		sig.setPbCode(fidelpb.ScalarFuncSig_CurrentTime0Arg)
  2151  		return sig, nil
  2152  	}
  2153  	// args[0] must be a constant which should not be null.
  2154  	_, ok := args[0].(*Constant)
  2155  	fsp := int64(types.MaxFsp)
  2156  	if ok {
  2157  		fsp, _, err = args[0].EvalInt(ctx, chunk.Event{})
  2158  		if err != nil {
  2159  			return nil, err
  2160  		}
  2161  		if fsp > int64(types.MaxFsp) {
  2162  			return nil, errors.Errorf("Too-big precision %v specified for 'curtime'. Maximum is %v.", fsp, types.MaxFsp)
  2163  		} else if fsp < int64(types.MinFsp) {
  2164  			return nil, errors.Errorf("Invalid negative %d specified, must in [0, 6].", fsp)
  2165  		}
  2166  	}
  2167  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDuration, types.ETInt)
  2168  	if err != nil {
  2169  		return nil, err
  2170  	}
  2171  	bf.tp.Flen, bf.tp.Decimal = allegrosql.MaxDurationWidthWithFsp, int(fsp)
  2172  	sig = &builtinCurrentTime1ArgSig{bf}
  2173  	sig.setPbCode(fidelpb.ScalarFuncSig_CurrentTime1Arg)
  2174  	return sig, nil
  2175  }
  2176  
  2177  type builtinCurrentTime0ArgSig struct {
  2178  	baseBuiltinFunc
  2179  }
  2180  
  2181  func (b *builtinCurrentTime0ArgSig) Clone() builtinFunc {
  2182  	newSig := &builtinCurrentTime0ArgSig{}
  2183  	newSig.cloneFrom(&b.baseBuiltinFunc)
  2184  	return newSig
  2185  }
  2186  
  2187  func (b *builtinCurrentTime0ArgSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  2188  	tz := b.ctx.GetStochastikVars().Location()
  2189  	nowTs, err := getStmtTimestamp(b.ctx)
  2190  	if err != nil {
  2191  		return types.Duration{}, true, err
  2192  	}
  2193  	dur := nowTs.In(tz).Format(types.TimeFormat)
  2194  	res, err := types.ParseDuration(b.ctx.GetStochastikVars().StmtCtx, dur, types.MinFsp)
  2195  	if err != nil {
  2196  		return types.Duration{}, true, err
  2197  	}
  2198  	return res, false, nil
  2199  }
  2200  
  2201  type builtinCurrentTime1ArgSig struct {
  2202  	baseBuiltinFunc
  2203  }
  2204  
  2205  func (b *builtinCurrentTime1ArgSig) Clone() builtinFunc {
  2206  	newSig := &builtinCurrentTime1ArgSig{}
  2207  	newSig.cloneFrom(&b.baseBuiltinFunc)
  2208  	return newSig
  2209  }
  2210  
  2211  func (b *builtinCurrentTime1ArgSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  2212  	fsp, _, err := b.args[0].EvalInt(b.ctx, event)
  2213  	if err != nil {
  2214  		return types.Duration{}, true, err
  2215  	}
  2216  	tz := b.ctx.GetStochastikVars().Location()
  2217  	nowTs, err := getStmtTimestamp(b.ctx)
  2218  	if err != nil {
  2219  		return types.Duration{}, true, err
  2220  	}
  2221  	dur := nowTs.In(tz).Format(types.TimeFSPFormat)
  2222  	res, err := types.ParseDuration(b.ctx.GetStochastikVars().StmtCtx, dur, int8(fsp))
  2223  	if err != nil {
  2224  		return types.Duration{}, true, err
  2225  	}
  2226  	return res, false, nil
  2227  }
  2228  
  2229  type timeFunctionClass struct {
  2230  	baseFunctionClass
  2231  }
  2232  
  2233  func (c *timeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  2234  	err := c.verifyArgs(args)
  2235  	if err != nil {
  2236  		return nil, err
  2237  	}
  2238  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDuration, types.ETString)
  2239  	if err != nil {
  2240  		return nil, err
  2241  	}
  2242  	bf.tp.Decimal, err = getExpressionFsp(ctx, args[0])
  2243  	if err != nil {
  2244  		return nil, err
  2245  	}
  2246  	sig := &builtinTimeSig{bf}
  2247  	sig.setPbCode(fidelpb.ScalarFuncSig_Time)
  2248  	return sig, nil
  2249  }
  2250  
  2251  type builtinTimeSig struct {
  2252  	baseBuiltinFunc
  2253  }
  2254  
  2255  func (b *builtinTimeSig) Clone() builtinFunc {
  2256  	newSig := &builtinTimeSig{}
  2257  	newSig.cloneFrom(&b.baseBuiltinFunc)
  2258  	return newSig
  2259  }
  2260  
  2261  // evalDuration evals a builtinTimeSig.
  2262  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_time.
  2263  func (b *builtinTimeSig) evalDuration(event chunk.Event) (res types.Duration, isNull bool, err error) {
  2264  	expr, isNull, err := b.args[0].EvalString(b.ctx, event)
  2265  	if isNull || err != nil {
  2266  		return res, isNull, err
  2267  	}
  2268  
  2269  	fsp := 0
  2270  	if idx := strings.Index(expr, "."); idx != -1 {
  2271  		fsp = len(expr) - idx - 1
  2272  	}
  2273  
  2274  	var tmpFsp int8
  2275  	if tmpFsp, err = types.CheckFsp(fsp); err != nil {
  2276  		return res, isNull, err
  2277  	}
  2278  	fsp = int(tmpFsp)
  2279  
  2280  	sc := b.ctx.GetStochastikVars().StmtCtx
  2281  	res, err = types.ParseDuration(sc, expr, int8(fsp))
  2282  	if types.ErrTruncatedWrongVal.Equal(err) {
  2283  		err = sc.HandleTruncate(err)
  2284  	}
  2285  	return res, isNull, err
  2286  }
  2287  
  2288  type timeLiteralFunctionClass struct {
  2289  	baseFunctionClass
  2290  }
  2291  
  2292  func (c *timeLiteralFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  2293  	if err := c.verifyArgs(args); err != nil {
  2294  		return nil, err
  2295  	}
  2296  	con, ok := args[0].(*Constant)
  2297  	if !ok {
  2298  		panic("Unexpected parameter for time literal")
  2299  	}
  2300  	dt, err := con.Eval(chunk.Event{})
  2301  	if err != nil {
  2302  		return nil, err
  2303  	}
  2304  	str := dt.GetString()
  2305  	if !isDuration(str) {
  2306  		return nil, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, str)
  2307  	}
  2308  	duration, err := types.ParseDuration(ctx.GetStochastikVars().StmtCtx, str, types.GetFsp(str))
  2309  	if err != nil {
  2310  		return nil, err
  2311  	}
  2312  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, []Expression{}, types.ETDuration)
  2313  	if err != nil {
  2314  		return nil, err
  2315  	}
  2316  	bf.tp.Flen, bf.tp.Decimal = 10, int(duration.Fsp)
  2317  	if int(duration.Fsp) > 0 {
  2318  		bf.tp.Flen += 1 + int(duration.Fsp)
  2319  	}
  2320  	sig := &builtinTimeLiteralSig{bf, duration}
  2321  	return sig, nil
  2322  }
  2323  
  2324  type builtinTimeLiteralSig struct {
  2325  	baseBuiltinFunc
  2326  	duration types.Duration
  2327  }
  2328  
  2329  func (b *builtinTimeLiteralSig) Clone() builtinFunc {
  2330  	newSig := &builtinTimeLiteralSig{duration: b.duration}
  2331  	newSig.cloneFrom(&b.baseBuiltinFunc)
  2332  	return newSig
  2333  }
  2334  
  2335  // evalDuration evals TIME 'stringLit'.
  2336  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-literals.html
  2337  func (b *builtinTimeLiteralSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  2338  	return b.duration, false, nil
  2339  }
  2340  
  2341  type utcDateFunctionClass struct {
  2342  	baseFunctionClass
  2343  }
  2344  
  2345  func (c *utcDateFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  2346  	if err := c.verifyArgs(args); err != nil {
  2347  		return nil, err
  2348  	}
  2349  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDatetime)
  2350  	if err != nil {
  2351  		return nil, err
  2352  	}
  2353  	bf.tp.Flen, bf.tp.Decimal = 10, 0
  2354  	sig := &builtinUTCDateSig{bf}
  2355  	return sig, nil
  2356  }
  2357  
  2358  type builtinUTCDateSig struct {
  2359  	baseBuiltinFunc
  2360  }
  2361  
  2362  func (b *builtinUTCDateSig) Clone() builtinFunc {
  2363  	newSig := &builtinUTCDateSig{}
  2364  	newSig.cloneFrom(&b.baseBuiltinFunc)
  2365  	return newSig
  2366  }
  2367  
  2368  // evalTime evals UTC_DATE, UTC_DATE().
  2369  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_utc-date
  2370  func (b *builtinUTCDateSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  2371  	nowTs, err := getStmtTimestamp(b.ctx)
  2372  	if err != nil {
  2373  		return types.ZeroTime, true, err
  2374  	}
  2375  	year, month, day := nowTs.UTC().Date()
  2376  	result := types.NewTime(types.FromGoTime(time.Date(year, month, day, 0, 0, 0, 0, time.UTC)), allegrosql.TypeDate, types.UnspecifiedFsp)
  2377  	return result, false, nil
  2378  }
  2379  
  2380  type utcTimestampFunctionClass struct {
  2381  	baseFunctionClass
  2382  }
  2383  
  2384  func getFlenAndDecimal4UTCTimestampAndNow(ctx stochastikctx.Context, arg Expression) (flen, decimal int) {
  2385  	if constant, ok := arg.(*Constant); ok {
  2386  		fsp, isNull, err := constant.EvalInt(ctx, chunk.Event{})
  2387  		if isNull || err != nil || fsp > int64(types.MaxFsp) {
  2388  			decimal = int(types.MaxFsp)
  2389  		} else if fsp < int64(types.MinFsp) {
  2390  			decimal = int(types.MinFsp)
  2391  		} else {
  2392  			decimal = int(fsp)
  2393  		}
  2394  	}
  2395  	if decimal > 0 {
  2396  		flen = 19 + 1 + decimal
  2397  	} else {
  2398  		flen = 19
  2399  	}
  2400  	return flen, decimal
  2401  }
  2402  
  2403  func (c *utcTimestampFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  2404  	if err := c.verifyArgs(args); err != nil {
  2405  		return nil, err
  2406  	}
  2407  	argTps := make([]types.EvalType, 0, 1)
  2408  	if len(args) == 1 {
  2409  		argTps = append(argTps, types.ETInt)
  2410  	}
  2411  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDatetime, argTps...)
  2412  	if err != nil {
  2413  		return nil, err
  2414  	}
  2415  
  2416  	if len(args) == 1 {
  2417  		bf.tp.Flen, bf.tp.Decimal = getFlenAndDecimal4UTCTimestampAndNow(bf.ctx, args[0])
  2418  	} else {
  2419  		bf.tp.Flen, bf.tp.Decimal = 19, 0
  2420  	}
  2421  
  2422  	var sig builtinFunc
  2423  	if len(args) == 1 {
  2424  		sig = &builtinUTCTimestampWithArgSig{bf}
  2425  		sig.setPbCode(fidelpb.ScalarFuncSig_UTCTimestampWithArg)
  2426  	} else {
  2427  		sig = &builtinUTCTimestampWithoutArgSig{bf}
  2428  		sig.setPbCode(fidelpb.ScalarFuncSig_UTCTimestampWithoutArg)
  2429  	}
  2430  	return sig, nil
  2431  }
  2432  
  2433  func evalUTCTimestampWithFsp(ctx stochastikctx.Context, fsp int8) (types.Time, bool, error) {
  2434  	nowTs, err := getStmtTimestamp(ctx)
  2435  	if err != nil {
  2436  		return types.ZeroTime, true, err
  2437  	}
  2438  	result, err := convertTimeToMysqlTime(nowTs.UTC(), fsp, types.ModeHalfEven)
  2439  	if err != nil {
  2440  		return types.ZeroTime, true, err
  2441  	}
  2442  	return result, false, nil
  2443  }
  2444  
  2445  type builtinUTCTimestampWithArgSig struct {
  2446  	baseBuiltinFunc
  2447  }
  2448  
  2449  func (b *builtinUTCTimestampWithArgSig) Clone() builtinFunc {
  2450  	newSig := &builtinUTCTimestampWithArgSig{}
  2451  	newSig.cloneFrom(&b.baseBuiltinFunc)
  2452  	return newSig
  2453  }
  2454  
  2455  // evalTime evals UTC_TIMESTAMP(fsp).
  2456  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_utc-timestamp
  2457  func (b *builtinUTCTimestampWithArgSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  2458  	num, isNull, err := b.args[0].EvalInt(b.ctx, event)
  2459  	if err != nil {
  2460  		return types.ZeroTime, true, err
  2461  	}
  2462  
  2463  	if !isNull && num > int64(types.MaxFsp) {
  2464  		return types.ZeroTime, true, errors.Errorf("Too-big precision %v specified for 'utc_timestamp'. Maximum is %v.", num, types.MaxFsp)
  2465  	}
  2466  	if !isNull && num < int64(types.MinFsp) {
  2467  		return types.ZeroTime, true, errors.Errorf("Invalid negative %d specified, must in [0, 6].", num)
  2468  	}
  2469  
  2470  	result, isNull, err := evalUTCTimestampWithFsp(b.ctx, int8(num))
  2471  	return result, isNull, err
  2472  }
  2473  
  2474  type builtinUTCTimestampWithoutArgSig struct {
  2475  	baseBuiltinFunc
  2476  }
  2477  
  2478  func (b *builtinUTCTimestampWithoutArgSig) Clone() builtinFunc {
  2479  	newSig := &builtinUTCTimestampWithoutArgSig{}
  2480  	newSig.cloneFrom(&b.baseBuiltinFunc)
  2481  	return newSig
  2482  }
  2483  
  2484  // evalTime evals UTC_TIMESTAMP().
  2485  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_utc-timestamp
  2486  func (b *builtinUTCTimestampWithoutArgSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  2487  	result, isNull, err := evalUTCTimestampWithFsp(b.ctx, int8(0))
  2488  	return result, isNull, err
  2489  }
  2490  
  2491  type nowFunctionClass struct {
  2492  	baseFunctionClass
  2493  }
  2494  
  2495  func (c *nowFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  2496  	if err := c.verifyArgs(args); err != nil {
  2497  		return nil, err
  2498  	}
  2499  	argTps := make([]types.EvalType, 0, 1)
  2500  	if len(args) == 1 {
  2501  		argTps = append(argTps, types.ETInt)
  2502  	}
  2503  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDatetime, argTps...)
  2504  	if err != nil {
  2505  		return nil, err
  2506  	}
  2507  
  2508  	if len(args) == 1 {
  2509  		bf.tp.Flen, bf.tp.Decimal = getFlenAndDecimal4UTCTimestampAndNow(bf.ctx, args[0])
  2510  	} else {
  2511  		bf.tp.Flen, bf.tp.Decimal = 19, 0
  2512  	}
  2513  
  2514  	var sig builtinFunc
  2515  	if len(args) == 1 {
  2516  		sig = &builtinNowWithArgSig{bf}
  2517  		sig.setPbCode(fidelpb.ScalarFuncSig_NowWithArg)
  2518  	} else {
  2519  		sig = &builtinNowWithoutArgSig{bf}
  2520  		sig.setPbCode(fidelpb.ScalarFuncSig_NowWithoutArg)
  2521  	}
  2522  	return sig, nil
  2523  }
  2524  
  2525  func evalNowWithFsp(ctx stochastikctx.Context, fsp int8) (types.Time, bool, error) {
  2526  	nowTs, err := getStmtTimestamp(ctx)
  2527  	if err != nil {
  2528  		return types.ZeroTime, true, err
  2529  	}
  2530  
  2531  	// In MyALLEGROSQL's implementation, now() will truncate the result instead of rounding it.
  2532  	// Results below are from MyALLEGROSQL 5.7, which can prove it.
  2533  	// allegrosql> select now(6), now(3), now();
  2534  	//	+----------------------------+-------------------------+---------------------+
  2535  	//	| now(6)                     | now(3)                  | now()               |
  2536  	//	+----------------------------+-------------------------+---------------------+
  2537  	//	| 2020-03-25 15:57:56.612966 | 2020-03-25 15:57:56.612 | 2020-03-25 15:57:56 |
  2538  	//	+----------------------------+-------------------------+---------------------+
  2539  	result, err := convertTimeToMysqlTime(nowTs, fsp, types.ModeTruncate)
  2540  	if err != nil {
  2541  		return types.ZeroTime, true, err
  2542  	}
  2543  
  2544  	err = result.ConvertTimeZone(time.Local, ctx.GetStochastikVars().Location())
  2545  	if err != nil {
  2546  		return types.ZeroTime, true, err
  2547  	}
  2548  
  2549  	return result, false, nil
  2550  }
  2551  
  2552  type builtinNowWithArgSig struct {
  2553  	baseBuiltinFunc
  2554  }
  2555  
  2556  func (b *builtinNowWithArgSig) Clone() builtinFunc {
  2557  	newSig := &builtinNowWithArgSig{}
  2558  	newSig.cloneFrom(&b.baseBuiltinFunc)
  2559  	return newSig
  2560  }
  2561  
  2562  // evalTime evals NOW(fsp)
  2563  // see: https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_now
  2564  func (b *builtinNowWithArgSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  2565  	fsp, isNull, err := b.args[0].EvalInt(b.ctx, event)
  2566  
  2567  	if err != nil {
  2568  		return types.ZeroTime, true, err
  2569  	}
  2570  
  2571  	if isNull {
  2572  		fsp = 0
  2573  	} else if fsp > int64(types.MaxFsp) {
  2574  		return types.ZeroTime, true, errors.Errorf("Too-big precision %v specified for 'now'. Maximum is %v.", fsp, types.MaxFsp)
  2575  	} else if fsp < int64(types.MinFsp) {
  2576  		return types.ZeroTime, true, errors.Errorf("Invalid negative %d specified, must in [0, 6].", fsp)
  2577  	}
  2578  
  2579  	result, isNull, err := evalNowWithFsp(b.ctx, int8(fsp))
  2580  	return result, isNull, err
  2581  }
  2582  
  2583  type builtinNowWithoutArgSig struct {
  2584  	baseBuiltinFunc
  2585  }
  2586  
  2587  func (b *builtinNowWithoutArgSig) Clone() builtinFunc {
  2588  	newSig := &builtinNowWithoutArgSig{}
  2589  	newSig.cloneFrom(&b.baseBuiltinFunc)
  2590  	return newSig
  2591  }
  2592  
  2593  // evalTime evals NOW()
  2594  // see: https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_now
  2595  func (b *builtinNowWithoutArgSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  2596  	result, isNull, err := evalNowWithFsp(b.ctx, int8(0))
  2597  	return result, isNull, err
  2598  }
  2599  
  2600  type extractFunctionClass struct {
  2601  	baseFunctionClass
  2602  }
  2603  
  2604  func (c *extractFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) {
  2605  	if err = c.verifyArgs(args); err != nil {
  2606  		return nil, err
  2607  	}
  2608  
  2609  	datetimeUnits := map[string]struct{}{
  2610  		"DAY":             {},
  2611  		"WEEK":            {},
  2612  		"MONTH":           {},
  2613  		"QUARTER":         {},
  2614  		"YEAR":            {},
  2615  		"DAY_MICROSECOND": {},
  2616  		"DAY_SECOND":      {},
  2617  		"DAY_MINUTE":      {},
  2618  		"DAY_HOUR":        {},
  2619  		"YEAR_MONTH":      {},
  2620  	}
  2621  	isDatetimeUnit := true
  2622  	args[0] = WrapWithCastAsString(ctx, args[0])
  2623  	if _, isCon := args[0].(*Constant); isCon {
  2624  		unit, _, err1 := args[0].EvalString(ctx, chunk.Event{})
  2625  		if err1 != nil {
  2626  			return nil, err1
  2627  		}
  2628  		_, isDatetimeUnit = datetimeUnits[unit]
  2629  	}
  2630  	var bf baseBuiltinFunc
  2631  	if isDatetimeUnit {
  2632  		bf, err = newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETString, types.ETDatetime)
  2633  		if err != nil {
  2634  			return nil, err
  2635  		}
  2636  		sig = &builtinExtractDatetimeSig{bf}
  2637  		sig.setPbCode(fidelpb.ScalarFuncSig_ExtractDatetime)
  2638  	} else {
  2639  		bf, err = newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETString, types.ETDuration)
  2640  		if err != nil {
  2641  			return nil, err
  2642  		}
  2643  		sig = &builtinExtractDurationSig{bf}
  2644  		sig.setPbCode(fidelpb.ScalarFuncSig_ExtractDuration)
  2645  	}
  2646  	return sig, nil
  2647  }
  2648  
  2649  type builtinExtractDatetimeSig struct {
  2650  	baseBuiltinFunc
  2651  }
  2652  
  2653  func (b *builtinExtractDatetimeSig) Clone() builtinFunc {
  2654  	newSig := &builtinExtractDatetimeSig{}
  2655  	newSig.cloneFrom(&b.baseBuiltinFunc)
  2656  	return newSig
  2657  }
  2658  
  2659  // evalInt evals a builtinExtractDatetimeSig.
  2660  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_extract
  2661  func (b *builtinExtractDatetimeSig) evalInt(event chunk.Event) (int64, bool, error) {
  2662  	unit, isNull, err := b.args[0].EvalString(b.ctx, event)
  2663  	if isNull || err != nil {
  2664  		return 0, isNull, err
  2665  	}
  2666  	dt, isNull, err := b.args[1].EvalTime(b.ctx, event)
  2667  	if isNull || err != nil {
  2668  		return 0, isNull, err
  2669  	}
  2670  	res, err := types.ExtractDatetimeNum(&dt, unit)
  2671  	return res, err != nil, err
  2672  }
  2673  
  2674  type builtinExtractDurationSig struct {
  2675  	baseBuiltinFunc
  2676  }
  2677  
  2678  func (b *builtinExtractDurationSig) Clone() builtinFunc {
  2679  	newSig := &builtinExtractDurationSig{}
  2680  	newSig.cloneFrom(&b.baseBuiltinFunc)
  2681  	return newSig
  2682  }
  2683  
  2684  // evalInt evals a builtinExtractDurationSig.
  2685  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_extract
  2686  func (b *builtinExtractDurationSig) evalInt(event chunk.Event) (int64, bool, error) {
  2687  	unit, isNull, err := b.args[0].EvalString(b.ctx, event)
  2688  	if isNull || err != nil {
  2689  		return 0, isNull, err
  2690  	}
  2691  	dur, isNull, err := b.args[1].EvalDuration(b.ctx, event)
  2692  	if isNull || err != nil {
  2693  		return 0, isNull, err
  2694  	}
  2695  	res, err := types.ExtractDurationNum(&dur, unit)
  2696  	return res, err != nil, err
  2697  }
  2698  
  2699  // baseDateArithmitical is the base class for all "builtinAddDateXXXSig" and "builtinSubDateXXXSig",
  2700  // which provides parameter getter and date arithmetical calculate functions.
  2701  type baseDateArithmitical struct {
  2702  	// intervalRegexp is "*Regexp" used to extract string interval for "DAY" unit.
  2703  	intervalRegexp *regexp.Regexp
  2704  }
  2705  
  2706  func newDateArighmeticalUtil() baseDateArithmitical {
  2707  	return baseDateArithmitical{
  2708  		intervalRegexp: regexp.MustCompile(`-?[\d]+`),
  2709  	}
  2710  }
  2711  
  2712  func (du *baseDateArithmitical) getDateFromString(ctx stochastikctx.Context, args []Expression, event chunk.Event, unit string) (types.Time, bool, error) {
  2713  	dateStr, isNull, err := args[0].EvalString(ctx, event)
  2714  	if isNull || err != nil {
  2715  		return types.ZeroTime, true, err
  2716  	}
  2717  
  2718  	dateTp := allegrosql.TypeDate
  2719  	if !types.IsDateFormat(dateStr) || types.IsClockUnit(unit) {
  2720  		dateTp = allegrosql.TypeDatetime
  2721  	}
  2722  
  2723  	sc := ctx.GetStochastikVars().StmtCtx
  2724  	date, err := types.ParseTime(sc, dateStr, dateTp, types.MaxFsp)
  2725  	return date, err != nil, handleInvalidTimeError(ctx, err)
  2726  }
  2727  
  2728  func (du *baseDateArithmitical) getDateFromInt(ctx stochastikctx.Context, args []Expression, event chunk.Event, unit string) (types.Time, bool, error) {
  2729  	dateInt, isNull, err := args[0].EvalInt(ctx, event)
  2730  	if isNull || err != nil {
  2731  		return types.ZeroTime, true, err
  2732  	}
  2733  
  2734  	sc := ctx.GetStochastikVars().StmtCtx
  2735  	date, err := types.ParseTimeFromInt64(sc, dateInt)
  2736  	if err != nil {
  2737  		return types.ZeroTime, true, handleInvalidTimeError(ctx, err)
  2738  	}
  2739  
  2740  	dateTp := allegrosql.TypeDate
  2741  	if date.Type() == allegrosql.TypeDatetime || date.Type() == allegrosql.TypeTimestamp || types.IsClockUnit(unit) {
  2742  		dateTp = allegrosql.TypeDatetime
  2743  	}
  2744  	date.SetType(dateTp)
  2745  	return date, false, nil
  2746  }
  2747  
  2748  func (du *baseDateArithmitical) getDateFromDatetime(ctx stochastikctx.Context, args []Expression, event chunk.Event, unit string) (types.Time, bool, error) {
  2749  	date, isNull, err := args[0].EvalTime(ctx, event)
  2750  	if isNull || err != nil {
  2751  		return types.ZeroTime, true, err
  2752  	}
  2753  
  2754  	dateTp := allegrosql.TypeDate
  2755  	if date.Type() == allegrosql.TypeDatetime || date.Type() == allegrosql.TypeTimestamp || types.IsClockUnit(unit) {
  2756  		dateTp = allegrosql.TypeDatetime
  2757  	}
  2758  	date.SetType(dateTp)
  2759  	return date, false, nil
  2760  }
  2761  
  2762  func (du *baseDateArithmitical) getIntervalFromString(ctx stochastikctx.Context, args []Expression, event chunk.Event, unit string) (string, bool, error) {
  2763  	interval, isNull, err := args[1].EvalString(ctx, event)
  2764  	if isNull || err != nil {
  2765  		return "", true, err
  2766  	}
  2767  	// unit "DAY" and "HOUR" has to be specially handled.
  2768  	if toLower := strings.ToLower(unit); toLower == "day" || toLower == "hour" {
  2769  		if strings.ToLower(interval) == "true" {
  2770  			interval = "1"
  2771  		} else if strings.ToLower(interval) == "false" {
  2772  			interval = "0"
  2773  		} else {
  2774  			interval = du.intervalRegexp.FindString(interval)
  2775  		}
  2776  	}
  2777  	return interval, false, nil
  2778  }
  2779  
  2780  func (du *baseDateArithmitical) getIntervalFromDecimal(ctx stochastikctx.Context, args []Expression, event chunk.Event, unit string) (string, bool, error) {
  2781  	decimal, isNull, err := args[1].EvalDecimal(ctx, event)
  2782  	if isNull || err != nil {
  2783  		return "", true, err
  2784  	}
  2785  	interval := decimal.String()
  2786  
  2787  	switch strings.ToUpper(unit) {
  2788  	case "HOUR_MINUTE", "MINUTE_SECOND", "YEAR_MONTH", "DAY_HOUR", "DAY_MINUTE",
  2789  		"DAY_SECOND", "DAY_MICROSECOND", "HOUR_MICROSECOND", "HOUR_SECOND", "MINUTE_MICROSECOND", "SECOND_MICROSECOND":
  2790  		neg := false
  2791  		if interval != "" && interval[0] == '-' {
  2792  			neg = true
  2793  			interval = interval[1:]
  2794  		}
  2795  		switch strings.ToUpper(unit) {
  2796  		case "HOUR_MINUTE", "MINUTE_SECOND":
  2797  			interval = strings.Replace(interval, ".", ":", -1)
  2798  		case "YEAR_MONTH":
  2799  			interval = strings.Replace(interval, ".", "-", -1)
  2800  		case "DAY_HOUR":
  2801  			interval = strings.Replace(interval, ".", " ", -1)
  2802  		case "DAY_MINUTE":
  2803  			interval = "0 " + strings.Replace(interval, ".", ":", -1)
  2804  		case "DAY_SECOND":
  2805  			interval = "0 00:" + strings.Replace(interval, ".", ":", -1)
  2806  		case "DAY_MICROSECOND":
  2807  			interval = "0 00:00:" + interval
  2808  		case "HOUR_MICROSECOND":
  2809  			interval = "00:00:" + interval
  2810  		case "HOUR_SECOND":
  2811  			interval = "00:" + strings.Replace(interval, ".", ":", -1)
  2812  		case "MINUTE_MICROSECOND":
  2813  			interval = "00:" + interval
  2814  		case "SECOND_MICROSECOND":
  2815  			/* keep interval as original decimal */
  2816  		}
  2817  		if neg {
  2818  			interval = "-" + interval
  2819  		}
  2820  	case "SECOND":
  2821  		// interval is already like the %f format.
  2822  	default:
  2823  		// YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, MINUTE, MICROSECOND
  2824  		castExpr := WrapWithCastAsString(ctx, WrapWithCastAsInt(ctx, args[1]))
  2825  		interval, isNull, err = castExpr.EvalString(ctx, event)
  2826  		if isNull || err != nil {
  2827  			return "", true, err
  2828  		}
  2829  	}
  2830  
  2831  	return interval, false, nil
  2832  }
  2833  
  2834  func (du *baseDateArithmitical) getIntervalFromInt(ctx stochastikctx.Context, args []Expression, event chunk.Event, unit string) (string, bool, error) {
  2835  	interval, isNull, err := args[1].EvalInt(ctx, event)
  2836  	if isNull || err != nil {
  2837  		return "", true, err
  2838  	}
  2839  	return strconv.FormatInt(interval, 10), false, nil
  2840  }
  2841  
  2842  func (du *baseDateArithmitical) getIntervalFromReal(ctx stochastikctx.Context, args []Expression, event chunk.Event, unit string) (string, bool, error) {
  2843  	interval, isNull, err := args[1].EvalReal(ctx, event)
  2844  	if isNull || err != nil {
  2845  		return "", true, err
  2846  	}
  2847  	return strconv.FormatFloat(interval, 'f', args[1].GetType().Decimal, 64), false, nil
  2848  }
  2849  
  2850  func (du *baseDateArithmitical) add(ctx stochastikctx.Context, date types.Time, interval string, unit string) (types.Time, bool, error) {
  2851  	year, month, day, nano, err := types.ParseDurationValue(unit, interval)
  2852  	if err := handleInvalidTimeError(ctx, err); err != nil {
  2853  		return types.ZeroTime, true, err
  2854  	}
  2855  
  2856  	goTime, err := date.GoTime(time.Local)
  2857  	if err := handleInvalidTimeError(ctx, err); err != nil {
  2858  		return types.ZeroTime, true, err
  2859  	}
  2860  
  2861  	goTime = goTime.Add(time.Duration(nano))
  2862  	goTime = types.AddDate(year, month, day, goTime)
  2863  
  2864  	if goTime.Nanosecond() == 0 {
  2865  		date.SetFsp(0)
  2866  	} else {
  2867  		date.SetFsp(6)
  2868  	}
  2869  
  2870  	if goTime.Year() < 0 || goTime.Year() > 9999 {
  2871  		return types.ZeroTime, true, handleInvalidTimeError(ctx, types.ErrDatetimeFunctionOverflow.GenWithStackByArgs("datetime"))
  2872  	}
  2873  
  2874  	date.SetCoreTime(types.FromGoTime(goTime))
  2875  	overflow, err := types.DateTimeIsOverflow(ctx.GetStochastikVars().StmtCtx, date)
  2876  	if err := handleInvalidTimeError(ctx, err); err != nil {
  2877  		return types.ZeroTime, true, err
  2878  	}
  2879  	if overflow {
  2880  		return types.ZeroTime, true, handleInvalidTimeError(ctx, types.ErrDatetimeFunctionOverflow.GenWithStackByArgs("datetime"))
  2881  	}
  2882  	return date, false, nil
  2883  }
  2884  
  2885  func (du *baseDateArithmitical) addDuration(ctx stochastikctx.Context, d types.Duration, interval string, unit string) (types.Duration, bool, error) {
  2886  	dur, err := types.ExtractDurationValue(unit, interval)
  2887  	if err != nil {
  2888  		return types.ZeroDuration, true, handleInvalidTimeError(ctx, err)
  2889  	}
  2890  	retDur, err := d.Add(dur)
  2891  	if err != nil {
  2892  		return types.ZeroDuration, true, err
  2893  	}
  2894  	return retDur, false, nil
  2895  }
  2896  
  2897  func (du *baseDateArithmitical) subDuration(ctx stochastikctx.Context, d types.Duration, interval string, unit string) (types.Duration, bool, error) {
  2898  	dur, err := types.ExtractDurationValue(unit, interval)
  2899  	if err != nil {
  2900  		return types.ZeroDuration, true, handleInvalidTimeError(ctx, err)
  2901  	}
  2902  	retDur, err := d.Sub(dur)
  2903  	if err != nil {
  2904  		return types.ZeroDuration, true, err
  2905  	}
  2906  	return retDur, false, nil
  2907  }
  2908  
  2909  func (du *baseDateArithmitical) sub(ctx stochastikctx.Context, date types.Time, interval string, unit string) (types.Time, bool, error) {
  2910  	year, month, day, nano, err := types.ParseDurationValue(unit, interval)
  2911  	if err := handleInvalidTimeError(ctx, err); err != nil {
  2912  		return types.ZeroTime, true, err
  2913  	}
  2914  	year, month, day, nano = -year, -month, -day, -nano
  2915  
  2916  	goTime, err := date.GoTime(time.Local)
  2917  	if err := handleInvalidTimeError(ctx, err); err != nil {
  2918  		return types.ZeroTime, true, err
  2919  	}
  2920  
  2921  	duration := time.Duration(nano)
  2922  	goTime = goTime.Add(duration)
  2923  	goTime = types.AddDate(year, month, day, goTime)
  2924  
  2925  	if goTime.Nanosecond() == 0 {
  2926  		date.SetFsp(0)
  2927  	} else {
  2928  		date.SetFsp(6)
  2929  	}
  2930  
  2931  	if goTime.Year() < 0 || goTime.Year() > 9999 {
  2932  		return types.ZeroTime, true, handleInvalidTimeError(ctx, types.ErrDatetimeFunctionOverflow.GenWithStackByArgs("datetime"))
  2933  	}
  2934  
  2935  	date.SetCoreTime(types.FromGoTime(goTime))
  2936  	overflow, err := types.DateTimeIsOverflow(ctx.GetStochastikVars().StmtCtx, date)
  2937  	if err := handleInvalidTimeError(ctx, err); err != nil {
  2938  		return types.ZeroTime, true, err
  2939  	}
  2940  	if overflow {
  2941  		return types.ZeroTime, true, handleInvalidTimeError(ctx, types.ErrDatetimeFunctionOverflow.GenWithStackByArgs("datetime"))
  2942  	}
  2943  	return date, false, nil
  2944  }
  2945  
  2946  func (du *baseDateArithmitical) vecGetDateFromInt(b *baseBuiltinFunc, input *chunk.Chunk, unit string, result *chunk.DeferredCauset) error {
  2947  	n := input.NumEvents()
  2948  	buf, err := b.bufSlabPredictor.get(types.ETInt, n)
  2949  	if err != nil {
  2950  		return err
  2951  	}
  2952  	defer b.bufSlabPredictor.put(buf)
  2953  	if err := b.args[0].VecEvalInt(b.ctx, input, buf); err != nil {
  2954  		return err
  2955  	}
  2956  
  2957  	result.ResizeTime(n, false)
  2958  	result.MergeNulls(buf)
  2959  	dates := result.Times()
  2960  	i64s := buf.Int64s()
  2961  	sc := b.ctx.GetStochastikVars().StmtCtx
  2962  	isClockUnit := types.IsClockUnit(unit)
  2963  	for i := 0; i < n; i++ {
  2964  		if result.IsNull(i) {
  2965  			continue
  2966  		}
  2967  
  2968  		date, err := types.ParseTimeFromInt64(sc, i64s[i])
  2969  		if err != nil {
  2970  			err = handleInvalidTimeError(b.ctx, err)
  2971  			if err != nil {
  2972  				return err
  2973  			}
  2974  			result.SetNull(i, true)
  2975  			continue
  2976  		}
  2977  
  2978  		dateTp := allegrosql.TypeDate
  2979  		if date.Type() == allegrosql.TypeDatetime || date.Type() == allegrosql.TypeTimestamp || isClockUnit {
  2980  			dateTp = allegrosql.TypeDatetime
  2981  		}
  2982  		date.SetType(dateTp)
  2983  		dates[i] = date
  2984  	}
  2985  	return nil
  2986  }
  2987  
  2988  func (du *baseDateArithmitical) vecGetDateFromString(b *baseBuiltinFunc, input *chunk.Chunk, unit string, result *chunk.DeferredCauset) error {
  2989  	n := input.NumEvents()
  2990  	buf, err := b.bufSlabPredictor.get(types.ETString, n)
  2991  	if err != nil {
  2992  		return err
  2993  	}
  2994  	defer b.bufSlabPredictor.put(buf)
  2995  	if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil {
  2996  		return err
  2997  	}
  2998  
  2999  	result.ResizeTime(n, false)
  3000  	result.MergeNulls(buf)
  3001  	dates := result.Times()
  3002  	sc := b.ctx.GetStochastikVars().StmtCtx
  3003  	isClockUnit := types.IsClockUnit(unit)
  3004  	for i := 0; i < n; i++ {
  3005  		if result.IsNull(i) {
  3006  			continue
  3007  		}
  3008  
  3009  		dateStr := buf.GetString(i)
  3010  		dateTp := allegrosql.TypeDate
  3011  		if !types.IsDateFormat(dateStr) || isClockUnit {
  3012  			dateTp = allegrosql.TypeDatetime
  3013  		}
  3014  
  3015  		date, err := types.ParseTime(sc, dateStr, dateTp, types.MaxFsp)
  3016  		if err != nil {
  3017  			err = handleInvalidTimeError(b.ctx, err)
  3018  			if err != nil {
  3019  				return err
  3020  			}
  3021  			result.SetNull(i, true)
  3022  		} else {
  3023  			dates[i] = date
  3024  		}
  3025  
  3026  	}
  3027  	return nil
  3028  }
  3029  
  3030  func (du *baseDateArithmitical) vecGetDateFromDatetime(b *baseBuiltinFunc, input *chunk.Chunk, unit string, result *chunk.DeferredCauset) error {
  3031  	n := input.NumEvents()
  3032  	result.ResizeTime(n, false)
  3033  	if err := b.args[0].VecEvalTime(b.ctx, input, result); err != nil {
  3034  		return err
  3035  	}
  3036  
  3037  	dates := result.Times()
  3038  	isClockUnit := types.IsClockUnit(unit)
  3039  	for i := 0; i < n; i++ {
  3040  		if result.IsNull(i) {
  3041  			continue
  3042  		}
  3043  
  3044  		dateTp := allegrosql.TypeDate
  3045  		if dates[i].Type() == allegrosql.TypeDatetime || dates[i].Type() == allegrosql.TypeTimestamp || isClockUnit {
  3046  			dateTp = allegrosql.TypeDatetime
  3047  		}
  3048  		dates[i].SetType(dateTp)
  3049  	}
  3050  	return nil
  3051  }
  3052  
  3053  func (du *baseDateArithmitical) vecGetIntervalFromString(b *baseBuiltinFunc, input *chunk.Chunk, unit string, result *chunk.DeferredCauset) error {
  3054  	n := input.NumEvents()
  3055  	buf, err := b.bufSlabPredictor.get(types.ETString, n)
  3056  	if err != nil {
  3057  		return err
  3058  	}
  3059  	defer b.bufSlabPredictor.put(buf)
  3060  	if err := b.args[1].VecEvalString(b.ctx, input, buf); err != nil {
  3061  		return err
  3062  	}
  3063  
  3064  	amendInterval := func(val string) string {
  3065  		return val
  3066  	}
  3067  	if unitLower := strings.ToLower(unit); unitLower == "day" || unitLower == "hour" {
  3068  		amendInterval = func(val string) string {
  3069  			if intervalLower := strings.ToLower(val); intervalLower == "true" {
  3070  				return "1"
  3071  			} else if intervalLower == "false" {
  3072  				return "0"
  3073  			}
  3074  			return du.intervalRegexp.FindString(val)
  3075  		}
  3076  	}
  3077  
  3078  	result.ReserveString(n)
  3079  	for i := 0; i < n; i++ {
  3080  		if buf.IsNull(i) {
  3081  			result.AppendNull()
  3082  			continue
  3083  		}
  3084  
  3085  		result.AppendString(amendInterval(buf.GetString(i)))
  3086  	}
  3087  	return nil
  3088  }
  3089  
  3090  func (du *baseDateArithmitical) vecGetIntervalFromDecimal(b *baseBuiltinFunc, input *chunk.Chunk, unit string, result *chunk.DeferredCauset) error {
  3091  	n := input.NumEvents()
  3092  	buf, err := b.bufSlabPredictor.get(types.ETDecimal, n)
  3093  	if err != nil {
  3094  		return err
  3095  	}
  3096  	defer b.bufSlabPredictor.put(buf)
  3097  	if err := b.args[1].VecEvalDecimal(b.ctx, input, buf); err != nil {
  3098  		return err
  3099  	}
  3100  
  3101  	isCompoundUnit := false
  3102  	amendInterval := func(val string, event *chunk.Event) (string, bool, error) {
  3103  		return val, false, nil
  3104  	}
  3105  	switch unitUpper := strings.ToUpper(unit); unitUpper {
  3106  	case "HOUR_MINUTE", "MINUTE_SECOND", "YEAR_MONTH", "DAY_HOUR", "DAY_MINUTE",
  3107  		"DAY_SECOND", "DAY_MICROSECOND", "HOUR_MICROSECOND", "HOUR_SECOND", "MINUTE_MICROSECOND", "SECOND_MICROSECOND":
  3108  		isCompoundUnit = true
  3109  		switch strings.ToUpper(unit) {
  3110  		case "HOUR_MINUTE", "MINUTE_SECOND":
  3111  			amendInterval = func(val string, _ *chunk.Event) (string, bool, error) {
  3112  				return strings.Replace(val, ".", ":", -1), false, nil
  3113  			}
  3114  		case "YEAR_MONTH":
  3115  			amendInterval = func(val string, _ *chunk.Event) (string, bool, error) {
  3116  				return strings.Replace(val, ".", "-", -1), false, nil
  3117  			}
  3118  		case "DAY_HOUR":
  3119  			amendInterval = func(val string, _ *chunk.Event) (string, bool, error) {
  3120  				return strings.Replace(val, ".", " ", -1), false, nil
  3121  			}
  3122  		case "DAY_MINUTE":
  3123  			amendInterval = func(val string, _ *chunk.Event) (string, bool, error) {
  3124  				return "0 " + strings.Replace(val, ".", ":", -1), false, nil
  3125  			}
  3126  		case "DAY_SECOND":
  3127  			amendInterval = func(val string, _ *chunk.Event) (string, bool, error) {
  3128  				return "0 00:" + strings.Replace(val, ".", ":", -1), false, nil
  3129  			}
  3130  		case "DAY_MICROSECOND":
  3131  			amendInterval = func(val string, _ *chunk.Event) (string, bool, error) {
  3132  				return "0 00:00:" + val, false, nil
  3133  			}
  3134  		case "HOUR_MICROSECOND":
  3135  			amendInterval = func(val string, _ *chunk.Event) (string, bool, error) {
  3136  				return "00:00:" + val, false, nil
  3137  			}
  3138  		case "HOUR_SECOND":
  3139  			amendInterval = func(val string, _ *chunk.Event) (string, bool, error) {
  3140  				return "00:" + strings.Replace(val, ".", ":", -1), false, nil
  3141  			}
  3142  		case "MINUTE_MICROSECOND":
  3143  			amendInterval = func(val string, _ *chunk.Event) (string, bool, error) {
  3144  				return "00:" + val, false, nil
  3145  			}
  3146  		case "SECOND_MICROSECOND":
  3147  			/* keep interval as original decimal */
  3148  		}
  3149  	case "SECOND":
  3150  		/* keep interval as original decimal */
  3151  	default:
  3152  		// YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, MINUTE, MICROSECOND
  3153  		castExpr := WrapWithCastAsString(b.ctx, WrapWithCastAsInt(b.ctx, b.args[1]))
  3154  		amendInterval = func(_ string, event *chunk.Event) (string, bool, error) {
  3155  			interval, isNull, err := castExpr.EvalString(b.ctx, *event)
  3156  			return interval, isNull || err != nil, err
  3157  		}
  3158  	}
  3159  
  3160  	result.ReserveString(n)
  3161  	decs := buf.Decimals()
  3162  	for i := 0; i < n; i++ {
  3163  		if buf.IsNull(i) {
  3164  			result.AppendNull()
  3165  			continue
  3166  		}
  3167  
  3168  		interval := decs[i].String()
  3169  		event := input.GetEvent(i)
  3170  		isNeg := false
  3171  		if isCompoundUnit && interval != "" && interval[0] == '-' {
  3172  			isNeg = true
  3173  			interval = interval[1:]
  3174  		}
  3175  		interval, isNull, err := amendInterval(interval, &event)
  3176  		if err != nil {
  3177  			return err
  3178  		}
  3179  		if isNull {
  3180  			result.AppendNull()
  3181  			continue
  3182  		}
  3183  		if isCompoundUnit && isNeg {
  3184  			interval = "-" + interval
  3185  		}
  3186  		result.AppendString(interval)
  3187  	}
  3188  	return nil
  3189  }
  3190  
  3191  func (du *baseDateArithmitical) vecGetIntervalFromInt(b *baseBuiltinFunc, input *chunk.Chunk, unit string, result *chunk.DeferredCauset) error {
  3192  	n := input.NumEvents()
  3193  	buf, err := b.bufSlabPredictor.get(types.ETInt, n)
  3194  	if err != nil {
  3195  		return err
  3196  	}
  3197  	defer b.bufSlabPredictor.put(buf)
  3198  	if err := b.args[1].VecEvalInt(b.ctx, input, buf); err != nil {
  3199  		return err
  3200  	}
  3201  
  3202  	result.ReserveString(n)
  3203  	i64s := buf.Int64s()
  3204  	for i := 0; i < n; i++ {
  3205  		if buf.IsNull(i) {
  3206  			result.AppendNull()
  3207  		} else {
  3208  			result.AppendString(strconv.FormatInt(i64s[i], 10))
  3209  		}
  3210  	}
  3211  	return nil
  3212  }
  3213  
  3214  func (du *baseDateArithmitical) vecGetIntervalFromReal(b *baseBuiltinFunc, input *chunk.Chunk, unit string, result *chunk.DeferredCauset) error {
  3215  	n := input.NumEvents()
  3216  	buf, err := b.bufSlabPredictor.get(types.ETReal, n)
  3217  	if err != nil {
  3218  		return err
  3219  	}
  3220  	defer b.bufSlabPredictor.put(buf)
  3221  	if err := b.args[1].VecEvalReal(b.ctx, input, buf); err != nil {
  3222  		return err
  3223  	}
  3224  
  3225  	result.ReserveString(n)
  3226  	f64s := buf.Float64s()
  3227  	prec := b.args[1].GetType().Decimal
  3228  	for i := 0; i < n; i++ {
  3229  		if buf.IsNull(i) {
  3230  			result.AppendNull()
  3231  		} else {
  3232  			result.AppendString(strconv.FormatFloat(f64s[i], 'f', prec, 64))
  3233  		}
  3234  	}
  3235  	return nil
  3236  }
  3237  
  3238  type addDateFunctionClass struct {
  3239  	baseFunctionClass
  3240  }
  3241  
  3242  func (c *addDateFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) {
  3243  	if err = c.verifyArgs(args); err != nil {
  3244  		return nil, err
  3245  	}
  3246  
  3247  	dateEvalTp := args[0].GetType().EvalType()
  3248  	if dateEvalTp != types.ETString && dateEvalTp != types.ETInt && dateEvalTp != types.ETDuration {
  3249  		dateEvalTp = types.ETDatetime
  3250  	}
  3251  
  3252  	intervalEvalTp := args[1].GetType().EvalType()
  3253  	if intervalEvalTp != types.ETString && intervalEvalTp != types.ETDecimal && intervalEvalTp != types.ETReal {
  3254  		intervalEvalTp = types.ETInt
  3255  	}
  3256  
  3257  	argTps := []types.EvalType{dateEvalTp, intervalEvalTp, types.ETString}
  3258  	var bf baseBuiltinFunc
  3259  	if dateEvalTp == types.ETDuration {
  3260  		unit, _, err := args[2].EvalString(ctx, chunk.Event{})
  3261  		if err != nil {
  3262  			return nil, err
  3263  		}
  3264  		internalFsp := 0
  3265  		switch unit {
  3266  		// If the unit has micro second, then the fsp must be the MaxFsp.
  3267  		case "MICROSECOND", "SECOND_MICROSECOND", "MINUTE_MICROSECOND", "HOUR_MICROSECOND", "DAY_MICROSECOND":
  3268  			internalFsp = int(types.MaxFsp)
  3269  		// If the unit is second, the fsp is related with the arg[1]'s.
  3270  		case "SECOND":
  3271  			internalFsp = int(types.MaxFsp)
  3272  			if intervalEvalTp != types.ETString {
  3273  				internalFsp = mathutil.Min(args[1].GetType().Decimal, int(types.MaxFsp))
  3274  			}
  3275  			// Otherwise, the fsp should be 0.
  3276  		}
  3277  		bf, err = newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDuration, argTps...)
  3278  		if err != nil {
  3279  			return nil, err
  3280  		}
  3281  		arg0Dec, err := getExpressionFsp(ctx, args[0])
  3282  		if err != nil {
  3283  			return nil, err
  3284  		}
  3285  		bf.tp.Flen, bf.tp.Decimal = allegrosql.MaxDurationWidthWithFsp, mathutil.Max(arg0Dec, internalFsp)
  3286  	} else {
  3287  		bf, err = newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDatetime, argTps...)
  3288  		if err != nil {
  3289  			return nil, err
  3290  		}
  3291  		bf.tp.Flen, bf.tp.Decimal = allegrosql.MaxDatetimeFullWidth, types.UnspecifiedLength
  3292  	}
  3293  
  3294  	switch {
  3295  	case dateEvalTp == types.ETString && intervalEvalTp == types.ETString:
  3296  		sig = &builtinAddDateStringStringSig{
  3297  			baseBuiltinFunc:      bf,
  3298  			baseDateArithmitical: newDateArighmeticalUtil(),
  3299  		}
  3300  		sig.setPbCode(fidelpb.ScalarFuncSig_AddDateStringString)
  3301  	case dateEvalTp == types.ETString && intervalEvalTp == types.ETInt:
  3302  		sig = &builtinAddDateStringIntSig{
  3303  			baseBuiltinFunc:      bf,
  3304  			baseDateArithmitical: newDateArighmeticalUtil(),
  3305  		}
  3306  		sig.setPbCode(fidelpb.ScalarFuncSig_AddDateStringInt)
  3307  	case dateEvalTp == types.ETString && intervalEvalTp == types.ETReal:
  3308  		sig = &builtinAddDateStringRealSig{
  3309  			baseBuiltinFunc:      bf,
  3310  			baseDateArithmitical: newDateArighmeticalUtil(),
  3311  		}
  3312  		sig.setPbCode(fidelpb.ScalarFuncSig_AddDateStringReal)
  3313  	case dateEvalTp == types.ETString && intervalEvalTp == types.ETDecimal:
  3314  		sig = &builtinAddDateStringDecimalSig{
  3315  			baseBuiltinFunc:      bf,
  3316  			baseDateArithmitical: newDateArighmeticalUtil(),
  3317  		}
  3318  		sig.setPbCode(fidelpb.ScalarFuncSig_AddDateStringDecimal)
  3319  	case dateEvalTp == types.ETInt && intervalEvalTp == types.ETString:
  3320  		sig = &builtinAddDateIntStringSig{
  3321  			baseBuiltinFunc:      bf,
  3322  			baseDateArithmitical: newDateArighmeticalUtil(),
  3323  		}
  3324  		sig.setPbCode(fidelpb.ScalarFuncSig_AddDateIntString)
  3325  	case dateEvalTp == types.ETInt && intervalEvalTp == types.ETInt:
  3326  		sig = &builtinAddDateIntIntSig{
  3327  			baseBuiltinFunc:      bf,
  3328  			baseDateArithmitical: newDateArighmeticalUtil(),
  3329  		}
  3330  		sig.setPbCode(fidelpb.ScalarFuncSig_AddDateIntInt)
  3331  	case dateEvalTp == types.ETInt && intervalEvalTp == types.ETReal:
  3332  		sig = &builtinAddDateIntRealSig{
  3333  			baseBuiltinFunc:      bf,
  3334  			baseDateArithmitical: newDateArighmeticalUtil(),
  3335  		}
  3336  		sig.setPbCode(fidelpb.ScalarFuncSig_AddDateIntReal)
  3337  	case dateEvalTp == types.ETInt && intervalEvalTp == types.ETDecimal:
  3338  		sig = &builtinAddDateIntDecimalSig{
  3339  			baseBuiltinFunc:      bf,
  3340  			baseDateArithmitical: newDateArighmeticalUtil(),
  3341  		}
  3342  		sig.setPbCode(fidelpb.ScalarFuncSig_AddDateIntDecimal)
  3343  	case dateEvalTp == types.ETDatetime && intervalEvalTp == types.ETString:
  3344  		sig = &builtinAddDateDatetimeStringSig{
  3345  			baseBuiltinFunc:      bf,
  3346  			baseDateArithmitical: newDateArighmeticalUtil(),
  3347  		}
  3348  		sig.setPbCode(fidelpb.ScalarFuncSig_AddDateDatetimeString)
  3349  	case dateEvalTp == types.ETDatetime && intervalEvalTp == types.ETInt:
  3350  		sig = &builtinAddDateDatetimeIntSig{
  3351  			baseBuiltinFunc:      bf,
  3352  			baseDateArithmitical: newDateArighmeticalUtil(),
  3353  		}
  3354  		sig.setPbCode(fidelpb.ScalarFuncSig_AddDateDatetimeInt)
  3355  	case dateEvalTp == types.ETDatetime && intervalEvalTp == types.ETReal:
  3356  		sig = &builtinAddDateDatetimeRealSig{
  3357  			baseBuiltinFunc:      bf,
  3358  			baseDateArithmitical: newDateArighmeticalUtil(),
  3359  		}
  3360  		sig.setPbCode(fidelpb.ScalarFuncSig_AddDateDatetimeReal)
  3361  	case dateEvalTp == types.ETDatetime && intervalEvalTp == types.ETDecimal:
  3362  		sig = &builtinAddDateDatetimeDecimalSig{
  3363  			baseBuiltinFunc:      bf,
  3364  			baseDateArithmitical: newDateArighmeticalUtil(),
  3365  		}
  3366  		sig.setPbCode(fidelpb.ScalarFuncSig_AddDateDatetimeDecimal)
  3367  	case dateEvalTp == types.ETDuration && intervalEvalTp == types.ETString:
  3368  		sig = &builtinAddDateDurationStringSig{
  3369  			baseBuiltinFunc:      bf,
  3370  			baseDateArithmitical: newDateArighmeticalUtil(),
  3371  		}
  3372  		sig.setPbCode(fidelpb.ScalarFuncSig_AddDateDurationString)
  3373  	case dateEvalTp == types.ETDuration && intervalEvalTp == types.ETInt:
  3374  		sig = &builtinAddDateDurationIntSig{
  3375  			baseBuiltinFunc:      bf,
  3376  			baseDateArithmitical: newDateArighmeticalUtil(),
  3377  		}
  3378  		sig.setPbCode(fidelpb.ScalarFuncSig_AddDateDurationInt)
  3379  	case dateEvalTp == types.ETDuration && intervalEvalTp == types.ETReal:
  3380  		sig = &builtinAddDateDurationRealSig{
  3381  			baseBuiltinFunc:      bf,
  3382  			baseDateArithmitical: newDateArighmeticalUtil(),
  3383  		}
  3384  		sig.setPbCode(fidelpb.ScalarFuncSig_AddDateDurationReal)
  3385  	case dateEvalTp == types.ETDuration && intervalEvalTp == types.ETDecimal:
  3386  		sig = &builtinAddDateDurationDecimalSig{
  3387  			baseBuiltinFunc:      bf,
  3388  			baseDateArithmitical: newDateArighmeticalUtil(),
  3389  		}
  3390  		sig.setPbCode(fidelpb.ScalarFuncSig_AddDateDurationDecimal)
  3391  	}
  3392  	return sig, nil
  3393  }
  3394  
  3395  type builtinAddDateStringStringSig struct {
  3396  	baseBuiltinFunc
  3397  	baseDateArithmitical
  3398  }
  3399  
  3400  func (b *builtinAddDateStringStringSig) Clone() builtinFunc {
  3401  	newSig := &builtinAddDateStringStringSig{baseDateArithmitical: b.baseDateArithmitical}
  3402  	newSig.cloneFrom(&b.baseBuiltinFunc)
  3403  	return newSig
  3404  }
  3405  
  3406  // evalTime evals ADDDATE(date,INTERVAL expr unit).
  3407  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
  3408  func (b *builtinAddDateStringStringSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  3409  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  3410  	if isNull || err != nil {
  3411  		return types.ZeroTime, true, err
  3412  	}
  3413  
  3414  	date, isNull, err := b.getDateFromString(b.ctx, b.args, event, unit)
  3415  	if isNull || err != nil {
  3416  		return types.ZeroTime, true, err
  3417  	}
  3418  
  3419  	interval, isNull, err := b.getIntervalFromString(b.ctx, b.args, event, unit)
  3420  	if isNull || err != nil {
  3421  		return types.ZeroTime, true, err
  3422  	}
  3423  
  3424  	result, isNull, err := b.add(b.ctx, date, interval, unit)
  3425  	return result, isNull || err != nil, err
  3426  }
  3427  
  3428  type builtinAddDateStringIntSig struct {
  3429  	baseBuiltinFunc
  3430  	baseDateArithmitical
  3431  }
  3432  
  3433  func (b *builtinAddDateStringIntSig) Clone() builtinFunc {
  3434  	newSig := &builtinAddDateStringIntSig{baseDateArithmitical: b.baseDateArithmitical}
  3435  	newSig.cloneFrom(&b.baseBuiltinFunc)
  3436  	return newSig
  3437  }
  3438  
  3439  // evalTime evals ADDDATE(date,INTERVAL expr unit).
  3440  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
  3441  func (b *builtinAddDateStringIntSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  3442  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  3443  	if isNull || err != nil {
  3444  		return types.ZeroTime, true, err
  3445  	}
  3446  
  3447  	date, isNull, err := b.getDateFromString(b.ctx, b.args, event, unit)
  3448  	if isNull || err != nil {
  3449  		return types.ZeroTime, true, err
  3450  	}
  3451  
  3452  	interval, isNull, err := b.getIntervalFromInt(b.ctx, b.args, event, unit)
  3453  	if isNull || err != nil {
  3454  		return types.ZeroTime, true, err
  3455  	}
  3456  
  3457  	result, isNull, err := b.add(b.ctx, date, interval, unit)
  3458  	return result, isNull || err != nil, err
  3459  }
  3460  
  3461  type builtinAddDateStringRealSig struct {
  3462  	baseBuiltinFunc
  3463  	baseDateArithmitical
  3464  }
  3465  
  3466  func (b *builtinAddDateStringRealSig) Clone() builtinFunc {
  3467  	newSig := &builtinAddDateStringRealSig{baseDateArithmitical: b.baseDateArithmitical}
  3468  	newSig.cloneFrom(&b.baseBuiltinFunc)
  3469  	return newSig
  3470  }
  3471  
  3472  // evalTime evals ADDDATE(date,INTERVAL expr unit).
  3473  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
  3474  func (b *builtinAddDateStringRealSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  3475  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  3476  	if isNull || err != nil {
  3477  		return types.ZeroTime, true, err
  3478  	}
  3479  
  3480  	date, isNull, err := b.getDateFromString(b.ctx, b.args, event, unit)
  3481  	if isNull || err != nil {
  3482  		return types.ZeroTime, true, err
  3483  	}
  3484  
  3485  	interval, isNull, err := b.getIntervalFromReal(b.ctx, b.args, event, unit)
  3486  	if isNull || err != nil {
  3487  		return types.ZeroTime, true, err
  3488  	}
  3489  
  3490  	result, isNull, err := b.add(b.ctx, date, interval, unit)
  3491  	return result, isNull || err != nil, err
  3492  }
  3493  
  3494  type builtinAddDateStringDecimalSig struct {
  3495  	baseBuiltinFunc
  3496  	baseDateArithmitical
  3497  }
  3498  
  3499  func (b *builtinAddDateStringDecimalSig) Clone() builtinFunc {
  3500  	newSig := &builtinAddDateStringDecimalSig{baseDateArithmitical: b.baseDateArithmitical}
  3501  	newSig.cloneFrom(&b.baseBuiltinFunc)
  3502  	return newSig
  3503  }
  3504  
  3505  // evalTime evals ADDDATE(date,INTERVAL expr unit).
  3506  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
  3507  func (b *builtinAddDateStringDecimalSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  3508  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  3509  	if isNull || err != nil {
  3510  		return types.ZeroTime, true, err
  3511  	}
  3512  
  3513  	date, isNull, err := b.getDateFromString(b.ctx, b.args, event, unit)
  3514  	if isNull || err != nil {
  3515  		return types.ZeroTime, true, err
  3516  	}
  3517  
  3518  	interval, isNull, err := b.getIntervalFromDecimal(b.ctx, b.args, event, unit)
  3519  	if isNull || err != nil {
  3520  		return types.ZeroTime, true, err
  3521  	}
  3522  
  3523  	result, isNull, err := b.add(b.ctx, date, interval, unit)
  3524  	return result, isNull || err != nil, err
  3525  }
  3526  
  3527  type builtinAddDateIntStringSig struct {
  3528  	baseBuiltinFunc
  3529  	baseDateArithmitical
  3530  }
  3531  
  3532  func (b *builtinAddDateIntStringSig) Clone() builtinFunc {
  3533  	newSig := &builtinAddDateIntStringSig{baseDateArithmitical: b.baseDateArithmitical}
  3534  	newSig.cloneFrom(&b.baseBuiltinFunc)
  3535  	return newSig
  3536  }
  3537  
  3538  // evalTime evals ADDDATE(date,INTERVAL expr unit).
  3539  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
  3540  func (b *builtinAddDateIntStringSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  3541  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  3542  	if isNull || err != nil {
  3543  		return types.ZeroTime, true, err
  3544  	}
  3545  
  3546  	date, isNull, err := b.getDateFromInt(b.ctx, b.args, event, unit)
  3547  	if isNull || err != nil {
  3548  		return types.ZeroTime, true, err
  3549  	}
  3550  
  3551  	interval, isNull, err := b.getIntervalFromString(b.ctx, b.args, event, unit)
  3552  	if isNull || err != nil {
  3553  		return types.ZeroTime, true, err
  3554  	}
  3555  
  3556  	result, isNull, err := b.add(b.ctx, date, interval, unit)
  3557  	return result, isNull || err != nil, err
  3558  }
  3559  
  3560  type builtinAddDateIntIntSig struct {
  3561  	baseBuiltinFunc
  3562  	baseDateArithmitical
  3563  }
  3564  
  3565  func (b *builtinAddDateIntIntSig) Clone() builtinFunc {
  3566  	newSig := &builtinAddDateIntIntSig{baseDateArithmitical: b.baseDateArithmitical}
  3567  	newSig.cloneFrom(&b.baseBuiltinFunc)
  3568  	return newSig
  3569  }
  3570  
  3571  // evalTime evals ADDDATE(date,INTERVAL expr unit).
  3572  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
  3573  func (b *builtinAddDateIntIntSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  3574  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  3575  	if isNull || err != nil {
  3576  		return types.ZeroTime, true, err
  3577  	}
  3578  
  3579  	date, isNull, err := b.getDateFromInt(b.ctx, b.args, event, unit)
  3580  	if isNull || err != nil {
  3581  		return types.ZeroTime, true, err
  3582  	}
  3583  
  3584  	interval, isNull, err := b.getIntervalFromInt(b.ctx, b.args, event, unit)
  3585  	if isNull || err != nil {
  3586  		return types.ZeroTime, true, err
  3587  	}
  3588  
  3589  	result, isNull, err := b.add(b.ctx, date, interval, unit)
  3590  	return result, isNull || err != nil, err
  3591  }
  3592  
  3593  type builtinAddDateIntRealSig struct {
  3594  	baseBuiltinFunc
  3595  	baseDateArithmitical
  3596  }
  3597  
  3598  func (b *builtinAddDateIntRealSig) Clone() builtinFunc {
  3599  	newSig := &builtinAddDateIntRealSig{baseDateArithmitical: b.baseDateArithmitical}
  3600  	newSig.cloneFrom(&b.baseBuiltinFunc)
  3601  	return newSig
  3602  }
  3603  
  3604  // evalTime evals ADDDATE(date,INTERVAL expr unit).
  3605  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
  3606  func (b *builtinAddDateIntRealSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  3607  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  3608  	if isNull || err != nil {
  3609  		return types.ZeroTime, true, err
  3610  	}
  3611  
  3612  	date, isNull, err := b.getDateFromInt(b.ctx, b.args, event, unit)
  3613  	if isNull || err != nil {
  3614  		return types.ZeroTime, true, err
  3615  	}
  3616  
  3617  	interval, isNull, err := b.getIntervalFromReal(b.ctx, b.args, event, unit)
  3618  	if isNull || err != nil {
  3619  		return types.ZeroTime, true, err
  3620  	}
  3621  
  3622  	result, isNull, err := b.add(b.ctx, date, interval, unit)
  3623  	return result, isNull || err != nil, err
  3624  }
  3625  
  3626  type builtinAddDateIntDecimalSig struct {
  3627  	baseBuiltinFunc
  3628  	baseDateArithmitical
  3629  }
  3630  
  3631  func (b *builtinAddDateIntDecimalSig) Clone() builtinFunc {
  3632  	newSig := &builtinAddDateIntDecimalSig{baseDateArithmitical: b.baseDateArithmitical}
  3633  	newSig.cloneFrom(&b.baseBuiltinFunc)
  3634  	return newSig
  3635  }
  3636  
  3637  // evalTime evals ADDDATE(date,INTERVAL expr unit).
  3638  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
  3639  func (b *builtinAddDateIntDecimalSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  3640  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  3641  	if isNull || err != nil {
  3642  		return types.ZeroTime, true, err
  3643  	}
  3644  
  3645  	date, isNull, err := b.getDateFromInt(b.ctx, b.args, event, unit)
  3646  	if isNull || err != nil {
  3647  		return types.ZeroTime, true, err
  3648  	}
  3649  
  3650  	interval, isNull, err := b.getIntervalFromDecimal(b.ctx, b.args, event, unit)
  3651  	if isNull || err != nil {
  3652  		return types.ZeroTime, true, err
  3653  	}
  3654  
  3655  	result, isNull, err := b.add(b.ctx, date, interval, unit)
  3656  	return result, isNull || err != nil, err
  3657  }
  3658  
  3659  type builtinAddDateDatetimeStringSig struct {
  3660  	baseBuiltinFunc
  3661  	baseDateArithmitical
  3662  }
  3663  
  3664  func (b *builtinAddDateDatetimeStringSig) Clone() builtinFunc {
  3665  	newSig := &builtinAddDateDatetimeStringSig{baseDateArithmitical: b.baseDateArithmitical}
  3666  	newSig.cloneFrom(&b.baseBuiltinFunc)
  3667  	return newSig
  3668  }
  3669  
  3670  // evalTime evals ADDDATE(date,INTERVAL expr unit).
  3671  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
  3672  func (b *builtinAddDateDatetimeStringSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  3673  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  3674  	if isNull || err != nil {
  3675  		return types.ZeroTime, true, err
  3676  	}
  3677  
  3678  	date, isNull, err := b.getDateFromDatetime(b.ctx, b.args, event, unit)
  3679  	if isNull || err != nil {
  3680  		return types.ZeroTime, true, err
  3681  	}
  3682  
  3683  	interval, isNull, err := b.getIntervalFromString(b.ctx, b.args, event, unit)
  3684  	if isNull || err != nil {
  3685  		return types.ZeroTime, true, err
  3686  	}
  3687  
  3688  	result, isNull, err := b.add(b.ctx, date, interval, unit)
  3689  	return result, isNull || err != nil, err
  3690  }
  3691  
  3692  type builtinAddDateDatetimeIntSig struct {
  3693  	baseBuiltinFunc
  3694  	baseDateArithmitical
  3695  }
  3696  
  3697  func (b *builtinAddDateDatetimeIntSig) Clone() builtinFunc {
  3698  	newSig := &builtinAddDateDatetimeIntSig{baseDateArithmitical: b.baseDateArithmitical}
  3699  	newSig.cloneFrom(&b.baseBuiltinFunc)
  3700  	return newSig
  3701  }
  3702  
  3703  // evalTime evals ADDDATE(date,INTERVAL expr unit).
  3704  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
  3705  func (b *builtinAddDateDatetimeIntSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  3706  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  3707  	if isNull || err != nil {
  3708  		return types.ZeroTime, true, err
  3709  	}
  3710  
  3711  	date, isNull, err := b.getDateFromDatetime(b.ctx, b.args, event, unit)
  3712  	if isNull || err != nil {
  3713  		return types.ZeroTime, true, err
  3714  	}
  3715  
  3716  	interval, isNull, err := b.getIntervalFromInt(b.ctx, b.args, event, unit)
  3717  	if isNull || err != nil {
  3718  		return types.ZeroTime, true, err
  3719  	}
  3720  
  3721  	result, isNull, err := b.add(b.ctx, date, interval, unit)
  3722  	return result, isNull || err != nil, err
  3723  }
  3724  
  3725  type builtinAddDateDatetimeRealSig struct {
  3726  	baseBuiltinFunc
  3727  	baseDateArithmitical
  3728  }
  3729  
  3730  func (b *builtinAddDateDatetimeRealSig) Clone() builtinFunc {
  3731  	newSig := &builtinAddDateDatetimeRealSig{baseDateArithmitical: b.baseDateArithmitical}
  3732  	newSig.cloneFrom(&b.baseBuiltinFunc)
  3733  	return newSig
  3734  }
  3735  
  3736  // evalTime evals ADDDATE(date,INTERVAL expr unit).
  3737  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
  3738  func (b *builtinAddDateDatetimeRealSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  3739  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  3740  	if isNull || err != nil {
  3741  		return types.ZeroTime, true, err
  3742  	}
  3743  
  3744  	date, isNull, err := b.getDateFromDatetime(b.ctx, b.args, event, unit)
  3745  	if isNull || err != nil {
  3746  		return types.ZeroTime, true, err
  3747  	}
  3748  
  3749  	interval, isNull, err := b.getIntervalFromReal(b.ctx, b.args, event, unit)
  3750  	if isNull || err != nil {
  3751  		return types.ZeroTime, true, err
  3752  	}
  3753  
  3754  	result, isNull, err := b.add(b.ctx, date, interval, unit)
  3755  	return result, isNull || err != nil, err
  3756  }
  3757  
  3758  type builtinAddDateDatetimeDecimalSig struct {
  3759  	baseBuiltinFunc
  3760  	baseDateArithmitical
  3761  }
  3762  
  3763  func (b *builtinAddDateDatetimeDecimalSig) Clone() builtinFunc {
  3764  	newSig := &builtinAddDateDatetimeDecimalSig{baseDateArithmitical: b.baseDateArithmitical}
  3765  	newSig.cloneFrom(&b.baseBuiltinFunc)
  3766  	return newSig
  3767  }
  3768  
  3769  // evalTime evals ADDDATE(date,INTERVAL expr unit).
  3770  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
  3771  func (b *builtinAddDateDatetimeDecimalSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  3772  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  3773  	if isNull || err != nil {
  3774  		return types.ZeroTime, true, err
  3775  	}
  3776  
  3777  	date, isNull, err := b.getDateFromDatetime(b.ctx, b.args, event, unit)
  3778  	if isNull || err != nil {
  3779  		return types.ZeroTime, true, err
  3780  	}
  3781  
  3782  	interval, isNull, err := b.getIntervalFromDecimal(b.ctx, b.args, event, unit)
  3783  	if isNull || err != nil {
  3784  		return types.ZeroTime, true, err
  3785  	}
  3786  
  3787  	result, isNull, err := b.add(b.ctx, date, interval, unit)
  3788  	return result, isNull || err != nil, err
  3789  }
  3790  
  3791  type builtinAddDateDurationStringSig struct {
  3792  	baseBuiltinFunc
  3793  	baseDateArithmitical
  3794  }
  3795  
  3796  func (b *builtinAddDateDurationStringSig) Clone() builtinFunc {
  3797  	newSig := &builtinAddDateDurationStringSig{baseDateArithmitical: b.baseDateArithmitical}
  3798  	newSig.cloneFrom(&b.baseBuiltinFunc)
  3799  	return newSig
  3800  }
  3801  
  3802  func (b *builtinAddDateDurationStringSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  3803  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  3804  	if isNull || err != nil {
  3805  		return types.ZeroDuration, true, err
  3806  	}
  3807  
  3808  	dur, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  3809  	if isNull || err != nil {
  3810  		return types.ZeroDuration, true, err
  3811  	}
  3812  
  3813  	interval, isNull, err := b.getIntervalFromString(b.ctx, b.args, event, unit)
  3814  	if isNull || err != nil {
  3815  		return types.ZeroDuration, true, err
  3816  	}
  3817  
  3818  	result, isNull, err := b.addDuration(b.ctx, dur, interval, unit)
  3819  	return result, isNull || err != nil, err
  3820  }
  3821  
  3822  type builtinAddDateDurationIntSig struct {
  3823  	baseBuiltinFunc
  3824  	baseDateArithmitical
  3825  }
  3826  
  3827  func (b *builtinAddDateDurationIntSig) Clone() builtinFunc {
  3828  	newSig := &builtinAddDateDurationIntSig{baseDateArithmitical: b.baseDateArithmitical}
  3829  	newSig.cloneFrom(&b.baseBuiltinFunc)
  3830  	return newSig
  3831  }
  3832  
  3833  func (b *builtinAddDateDurationIntSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  3834  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  3835  	if isNull || err != nil {
  3836  		return types.ZeroDuration, true, err
  3837  	}
  3838  
  3839  	dur, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  3840  	if isNull || err != nil {
  3841  		return types.ZeroDuration, true, err
  3842  	}
  3843  	interval, isNull, err := b.getIntervalFromInt(b.ctx, b.args, event, unit)
  3844  	if isNull || err != nil {
  3845  		return types.ZeroDuration, true, err
  3846  	}
  3847  
  3848  	result, isNull, err := b.addDuration(b.ctx, dur, interval, unit)
  3849  	return result, isNull || err != nil, err
  3850  }
  3851  
  3852  type builtinAddDateDurationDecimalSig struct {
  3853  	baseBuiltinFunc
  3854  	baseDateArithmitical
  3855  }
  3856  
  3857  func (b *builtinAddDateDurationDecimalSig) Clone() builtinFunc {
  3858  	newSig := &builtinAddDateDurationDecimalSig{baseDateArithmitical: b.baseDateArithmitical}
  3859  	newSig.cloneFrom(&b.baseBuiltinFunc)
  3860  	return newSig
  3861  }
  3862  
  3863  func (b *builtinAddDateDurationDecimalSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  3864  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  3865  	if isNull || err != nil {
  3866  		return types.ZeroDuration, true, err
  3867  	}
  3868  
  3869  	dur, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  3870  	if isNull || err != nil {
  3871  		return types.ZeroDuration, true, err
  3872  	}
  3873  	interval, isNull, err := b.getIntervalFromDecimal(b.ctx, b.args, event, unit)
  3874  	if isNull || err != nil {
  3875  		return types.ZeroDuration, true, err
  3876  	}
  3877  
  3878  	result, isNull, err := b.addDuration(b.ctx, dur, interval, unit)
  3879  	return result, isNull || err != nil, err
  3880  }
  3881  
  3882  type builtinAddDateDurationRealSig struct {
  3883  	baseBuiltinFunc
  3884  	baseDateArithmitical
  3885  }
  3886  
  3887  func (b *builtinAddDateDurationRealSig) Clone() builtinFunc {
  3888  	newSig := &builtinAddDateDurationRealSig{baseDateArithmitical: b.baseDateArithmitical}
  3889  	newSig.cloneFrom(&b.baseBuiltinFunc)
  3890  	return newSig
  3891  }
  3892  
  3893  func (b *builtinAddDateDurationRealSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  3894  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  3895  	if isNull || err != nil {
  3896  		return types.ZeroDuration, true, err
  3897  	}
  3898  
  3899  	dur, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  3900  	if isNull || err != nil {
  3901  		return types.ZeroDuration, true, err
  3902  	}
  3903  	interval, isNull, err := b.getIntervalFromReal(b.ctx, b.args, event, unit)
  3904  	if isNull || err != nil {
  3905  		return types.ZeroDuration, true, err
  3906  	}
  3907  
  3908  	result, isNull, err := b.addDuration(b.ctx, dur, interval, unit)
  3909  	return result, isNull || err != nil, err
  3910  }
  3911  
  3912  type subDateFunctionClass struct {
  3913  	baseFunctionClass
  3914  }
  3915  
  3916  func (c *subDateFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) {
  3917  	if err = c.verifyArgs(args); err != nil {
  3918  		return nil, err
  3919  	}
  3920  
  3921  	dateEvalTp := args[0].GetType().EvalType()
  3922  	if dateEvalTp != types.ETString && dateEvalTp != types.ETInt && dateEvalTp != types.ETDuration {
  3923  		dateEvalTp = types.ETDatetime
  3924  	}
  3925  
  3926  	intervalEvalTp := args[1].GetType().EvalType()
  3927  	if intervalEvalTp != types.ETString && intervalEvalTp != types.ETDecimal && intervalEvalTp != types.ETReal {
  3928  		intervalEvalTp = types.ETInt
  3929  	}
  3930  
  3931  	argTps := []types.EvalType{dateEvalTp, intervalEvalTp, types.ETString}
  3932  	var bf baseBuiltinFunc
  3933  	if dateEvalTp == types.ETDuration {
  3934  		unit, _, err := args[2].EvalString(ctx, chunk.Event{})
  3935  		if err != nil {
  3936  			return nil, err
  3937  		}
  3938  		internalFsp := 0
  3939  		switch unit {
  3940  		// If the unit has micro second, then the fsp must be the MaxFsp.
  3941  		case "MICROSECOND", "SECOND_MICROSECOND", "MINUTE_MICROSECOND", "HOUR_MICROSECOND", "DAY_MICROSECOND":
  3942  			internalFsp = int(types.MaxFsp)
  3943  		// If the unit is second, the fsp is related with the arg[1]'s.
  3944  		case "SECOND":
  3945  			internalFsp = int(types.MaxFsp)
  3946  			if intervalEvalTp != types.ETString {
  3947  				internalFsp = mathutil.Min(args[1].GetType().Decimal, int(types.MaxFsp))
  3948  			}
  3949  			// Otherwise, the fsp should be 0.
  3950  		}
  3951  		bf, err = newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDuration, argTps...)
  3952  		if err != nil {
  3953  			return nil, err
  3954  		}
  3955  		arg0Dec, err := getExpressionFsp(ctx, args[0])
  3956  		if err != nil {
  3957  			return nil, err
  3958  		}
  3959  		bf.tp.Flen, bf.tp.Decimal = allegrosql.MaxDurationWidthWithFsp, mathutil.Max(arg0Dec, internalFsp)
  3960  	} else {
  3961  		bf, err = newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDatetime, argTps...)
  3962  		if err != nil {
  3963  			return nil, err
  3964  		}
  3965  		bf.tp.Flen, bf.tp.Decimal = allegrosql.MaxDatetimeFullWidth, types.UnspecifiedLength
  3966  	}
  3967  
  3968  	switch {
  3969  	case dateEvalTp == types.ETString && intervalEvalTp == types.ETString:
  3970  		sig = &builtinSubDateStringStringSig{
  3971  			baseBuiltinFunc:      bf,
  3972  			baseDateArithmitical: newDateArighmeticalUtil(),
  3973  		}
  3974  		sig.setPbCode(fidelpb.ScalarFuncSig_SubDateStringString)
  3975  	case dateEvalTp == types.ETString && intervalEvalTp == types.ETInt:
  3976  		sig = &builtinSubDateStringIntSig{
  3977  			baseBuiltinFunc:      bf,
  3978  			baseDateArithmitical: newDateArighmeticalUtil(),
  3979  		}
  3980  		sig.setPbCode(fidelpb.ScalarFuncSig_SubDateStringInt)
  3981  	case dateEvalTp == types.ETString && intervalEvalTp == types.ETReal:
  3982  		sig = &builtinSubDateStringRealSig{
  3983  			baseBuiltinFunc:      bf,
  3984  			baseDateArithmitical: newDateArighmeticalUtil(),
  3985  		}
  3986  		sig.setPbCode(fidelpb.ScalarFuncSig_SubDateStringReal)
  3987  	case dateEvalTp == types.ETString && intervalEvalTp == types.ETDecimal:
  3988  		sig = &builtinSubDateStringDecimalSig{
  3989  			baseBuiltinFunc:      bf,
  3990  			baseDateArithmitical: newDateArighmeticalUtil(),
  3991  		}
  3992  		sig.setPbCode(fidelpb.ScalarFuncSig_SubDateStringDecimal)
  3993  	case dateEvalTp == types.ETInt && intervalEvalTp == types.ETString:
  3994  		sig = &builtinSubDateIntStringSig{
  3995  			baseBuiltinFunc:      bf,
  3996  			baseDateArithmitical: newDateArighmeticalUtil(),
  3997  		}
  3998  		sig.setPbCode(fidelpb.ScalarFuncSig_SubDateIntString)
  3999  	case dateEvalTp == types.ETInt && intervalEvalTp == types.ETInt:
  4000  		sig = &builtinSubDateIntIntSig{
  4001  			baseBuiltinFunc:      bf,
  4002  			baseDateArithmitical: newDateArighmeticalUtil(),
  4003  		}
  4004  		sig.setPbCode(fidelpb.ScalarFuncSig_SubDateIntInt)
  4005  	case dateEvalTp == types.ETInt && intervalEvalTp == types.ETReal:
  4006  		sig = &builtinSubDateIntRealSig{
  4007  			baseBuiltinFunc:      bf,
  4008  			baseDateArithmitical: newDateArighmeticalUtil(),
  4009  		}
  4010  		sig.setPbCode(fidelpb.ScalarFuncSig_SubDateIntReal)
  4011  	case dateEvalTp == types.ETInt && intervalEvalTp == types.ETDecimal:
  4012  		sig = &builtinSubDateIntDecimalSig{
  4013  			baseBuiltinFunc:      bf,
  4014  			baseDateArithmitical: newDateArighmeticalUtil(),
  4015  		}
  4016  		sig.setPbCode(fidelpb.ScalarFuncSig_SubDateIntDecimal)
  4017  	case dateEvalTp == types.ETDatetime && intervalEvalTp == types.ETString:
  4018  		sig = &builtinSubDateDatetimeStringSig{
  4019  			baseBuiltinFunc:      bf,
  4020  			baseDateArithmitical: newDateArighmeticalUtil(),
  4021  		}
  4022  		sig.setPbCode(fidelpb.ScalarFuncSig_SubDateDatetimeString)
  4023  	case dateEvalTp == types.ETDatetime && intervalEvalTp == types.ETInt:
  4024  		sig = &builtinSubDateDatetimeIntSig{
  4025  			baseBuiltinFunc:      bf,
  4026  			baseDateArithmitical: newDateArighmeticalUtil(),
  4027  		}
  4028  		sig.setPbCode(fidelpb.ScalarFuncSig_SubDateDatetimeInt)
  4029  	case dateEvalTp == types.ETDatetime && intervalEvalTp == types.ETReal:
  4030  		sig = &builtinSubDateDatetimeRealSig{
  4031  			baseBuiltinFunc:      bf,
  4032  			baseDateArithmitical: newDateArighmeticalUtil(),
  4033  		}
  4034  		sig.setPbCode(fidelpb.ScalarFuncSig_SubDateDatetimeReal)
  4035  	case dateEvalTp == types.ETDatetime && intervalEvalTp == types.ETDecimal:
  4036  		sig = &builtinSubDateDatetimeDecimalSig{
  4037  			baseBuiltinFunc:      bf,
  4038  			baseDateArithmitical: newDateArighmeticalUtil(),
  4039  		}
  4040  		sig.setPbCode(fidelpb.ScalarFuncSig_SubDateDatetimeDecimal)
  4041  	case dateEvalTp == types.ETDuration && intervalEvalTp == types.ETString:
  4042  		sig = &builtinSubDateDurationStringSig{
  4043  			baseBuiltinFunc:      bf,
  4044  			baseDateArithmitical: newDateArighmeticalUtil(),
  4045  		}
  4046  		sig.setPbCode(fidelpb.ScalarFuncSig_SubDateDurationString)
  4047  	case dateEvalTp == types.ETDuration && intervalEvalTp == types.ETInt:
  4048  		sig = &builtinSubDateDurationIntSig{
  4049  			baseBuiltinFunc:      bf,
  4050  			baseDateArithmitical: newDateArighmeticalUtil(),
  4051  		}
  4052  		sig.setPbCode(fidelpb.ScalarFuncSig_SubDateDurationInt)
  4053  	case dateEvalTp == types.ETDuration && intervalEvalTp == types.ETReal:
  4054  		sig = &builtinSubDateDurationRealSig{
  4055  			baseBuiltinFunc:      bf,
  4056  			baseDateArithmitical: newDateArighmeticalUtil(),
  4057  		}
  4058  		sig.setPbCode(fidelpb.ScalarFuncSig_SubDateDurationReal)
  4059  	case dateEvalTp == types.ETDuration && intervalEvalTp == types.ETDecimal:
  4060  		sig = &builtinSubDateDurationDecimalSig{
  4061  			baseBuiltinFunc:      bf,
  4062  			baseDateArithmitical: newDateArighmeticalUtil(),
  4063  		}
  4064  		sig.setPbCode(fidelpb.ScalarFuncSig_SubDateDurationDecimal)
  4065  	}
  4066  	return sig, nil
  4067  }
  4068  
  4069  type builtinSubDateStringStringSig struct {
  4070  	baseBuiltinFunc
  4071  	baseDateArithmitical
  4072  }
  4073  
  4074  func (b *builtinSubDateStringStringSig) Clone() builtinFunc {
  4075  	newSig := &builtinSubDateStringStringSig{baseDateArithmitical: b.baseDateArithmitical}
  4076  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4077  	return newSig
  4078  }
  4079  
  4080  // evalTime evals SUBDATE(date,INTERVAL expr unit).
  4081  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
  4082  func (b *builtinSubDateStringStringSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  4083  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  4084  	if isNull || err != nil {
  4085  		return types.ZeroTime, true, err
  4086  	}
  4087  
  4088  	date, isNull, err := b.getDateFromString(b.ctx, b.args, event, unit)
  4089  	if isNull || err != nil {
  4090  		return types.ZeroTime, true, err
  4091  	}
  4092  
  4093  	interval, isNull, err := b.getIntervalFromString(b.ctx, b.args, event, unit)
  4094  	if isNull || err != nil {
  4095  		return types.ZeroTime, true, err
  4096  	}
  4097  
  4098  	result, isNull, err := b.sub(b.ctx, date, interval, unit)
  4099  	return result, isNull || err != nil, err
  4100  }
  4101  
  4102  type builtinSubDateStringIntSig struct {
  4103  	baseBuiltinFunc
  4104  	baseDateArithmitical
  4105  }
  4106  
  4107  func (b *builtinSubDateStringIntSig) Clone() builtinFunc {
  4108  	newSig := &builtinSubDateStringIntSig{baseDateArithmitical: b.baseDateArithmitical}
  4109  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4110  	return newSig
  4111  }
  4112  
  4113  // evalTime evals SUBDATE(date,INTERVAL expr unit).
  4114  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
  4115  func (b *builtinSubDateStringIntSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  4116  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  4117  	if isNull || err != nil {
  4118  		return types.ZeroTime, true, err
  4119  	}
  4120  
  4121  	date, isNull, err := b.getDateFromString(b.ctx, b.args, event, unit)
  4122  	if isNull || err != nil {
  4123  		return types.ZeroTime, true, err
  4124  	}
  4125  
  4126  	interval, isNull, err := b.getIntervalFromInt(b.ctx, b.args, event, unit)
  4127  	if isNull || err != nil {
  4128  		return types.ZeroTime, true, err
  4129  	}
  4130  
  4131  	result, isNull, err := b.sub(b.ctx, date, interval, unit)
  4132  	return result, isNull || err != nil, err
  4133  }
  4134  
  4135  type builtinSubDateStringRealSig struct {
  4136  	baseBuiltinFunc
  4137  	baseDateArithmitical
  4138  }
  4139  
  4140  func (b *builtinSubDateStringRealSig) Clone() builtinFunc {
  4141  	newSig := &builtinSubDateStringRealSig{baseDateArithmitical: b.baseDateArithmitical}
  4142  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4143  	return newSig
  4144  }
  4145  
  4146  // evalTime evals SUBDATE(date,INTERVAL expr unit).
  4147  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
  4148  func (b *builtinSubDateStringRealSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  4149  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  4150  	if isNull || err != nil {
  4151  		return types.ZeroTime, true, err
  4152  	}
  4153  
  4154  	date, isNull, err := b.getDateFromString(b.ctx, b.args, event, unit)
  4155  	if isNull || err != nil {
  4156  		return types.ZeroTime, true, err
  4157  	}
  4158  
  4159  	interval, isNull, err := b.getIntervalFromReal(b.ctx, b.args, event, unit)
  4160  	if isNull || err != nil {
  4161  		return types.ZeroTime, true, err
  4162  	}
  4163  
  4164  	result, isNull, err := b.sub(b.ctx, date, interval, unit)
  4165  	return result, isNull || err != nil, err
  4166  }
  4167  
  4168  type builtinSubDateStringDecimalSig struct {
  4169  	baseBuiltinFunc
  4170  	baseDateArithmitical
  4171  }
  4172  
  4173  func (b *builtinSubDateStringDecimalSig) Clone() builtinFunc {
  4174  	newSig := &builtinSubDateStringDecimalSig{baseDateArithmitical: b.baseDateArithmitical}
  4175  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4176  	return newSig
  4177  }
  4178  
  4179  func (b *builtinSubDateStringDecimalSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  4180  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  4181  	if isNull || err != nil {
  4182  		return types.ZeroTime, true, err
  4183  	}
  4184  
  4185  	date, isNull, err := b.getDateFromString(b.ctx, b.args, event, unit)
  4186  	if isNull || err != nil {
  4187  		return types.ZeroTime, true, err
  4188  	}
  4189  
  4190  	interval, isNull, err := b.getIntervalFromDecimal(b.ctx, b.args, event, unit)
  4191  	if isNull || err != nil {
  4192  		return types.ZeroTime, true, err
  4193  	}
  4194  
  4195  	result, isNull, err := b.sub(b.ctx, date, interval, unit)
  4196  	return result, isNull || err != nil, err
  4197  }
  4198  
  4199  type builtinSubDateIntStringSig struct {
  4200  	baseBuiltinFunc
  4201  	baseDateArithmitical
  4202  }
  4203  
  4204  func (b *builtinSubDateIntStringSig) Clone() builtinFunc {
  4205  	newSig := &builtinSubDateIntStringSig{baseDateArithmitical: b.baseDateArithmitical}
  4206  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4207  	return newSig
  4208  }
  4209  
  4210  // evalTime evals SUBDATE(date,INTERVAL expr unit).
  4211  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
  4212  func (b *builtinSubDateIntStringSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  4213  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  4214  	if isNull || err != nil {
  4215  		return types.ZeroTime, true, err
  4216  	}
  4217  
  4218  	date, isNull, err := b.getDateFromInt(b.ctx, b.args, event, unit)
  4219  	if isNull || err != nil {
  4220  		return types.ZeroTime, true, err
  4221  	}
  4222  
  4223  	interval, isNull, err := b.getIntervalFromString(b.ctx, b.args, event, unit)
  4224  	if isNull || err != nil {
  4225  		return types.ZeroTime, true, err
  4226  	}
  4227  
  4228  	result, isNull, err := b.sub(b.ctx, date, interval, unit)
  4229  	return result, isNull || err != nil, err
  4230  }
  4231  
  4232  type builtinSubDateIntIntSig struct {
  4233  	baseBuiltinFunc
  4234  	baseDateArithmitical
  4235  }
  4236  
  4237  func (b *builtinSubDateIntIntSig) Clone() builtinFunc {
  4238  	newSig := &builtinSubDateIntIntSig{baseDateArithmitical: b.baseDateArithmitical}
  4239  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4240  	return newSig
  4241  }
  4242  
  4243  // evalTime evals SUBDATE(date,INTERVAL expr unit).
  4244  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
  4245  func (b *builtinSubDateIntIntSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  4246  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  4247  	if isNull || err != nil {
  4248  		return types.ZeroTime, true, err
  4249  	}
  4250  
  4251  	date, isNull, err := b.getDateFromInt(b.ctx, b.args, event, unit)
  4252  	if isNull || err != nil {
  4253  		return types.ZeroTime, true, err
  4254  	}
  4255  
  4256  	interval, isNull, err := b.getIntervalFromInt(b.ctx, b.args, event, unit)
  4257  	if isNull || err != nil {
  4258  		return types.ZeroTime, true, err
  4259  	}
  4260  
  4261  	result, isNull, err := b.sub(b.ctx, date, interval, unit)
  4262  	return result, isNull || err != nil, err
  4263  }
  4264  
  4265  type builtinSubDateIntRealSig struct {
  4266  	baseBuiltinFunc
  4267  	baseDateArithmitical
  4268  }
  4269  
  4270  func (b *builtinSubDateIntRealSig) Clone() builtinFunc {
  4271  	newSig := &builtinSubDateIntRealSig{baseDateArithmitical: b.baseDateArithmitical}
  4272  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4273  	return newSig
  4274  }
  4275  
  4276  // evalTime evals SUBDATE(date,INTERVAL expr unit).
  4277  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
  4278  func (b *builtinSubDateIntRealSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  4279  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  4280  	if isNull || err != nil {
  4281  		return types.ZeroTime, true, err
  4282  	}
  4283  
  4284  	date, isNull, err := b.getDateFromInt(b.ctx, b.args, event, unit)
  4285  	if isNull || err != nil {
  4286  		return types.ZeroTime, true, err
  4287  	}
  4288  
  4289  	interval, isNull, err := b.getIntervalFromReal(b.ctx, b.args, event, unit)
  4290  	if isNull || err != nil {
  4291  		return types.ZeroTime, true, err
  4292  	}
  4293  
  4294  	result, isNull, err := b.sub(b.ctx, date, interval, unit)
  4295  	return result, isNull || err != nil, err
  4296  }
  4297  
  4298  type builtinSubDateDatetimeStringSig struct {
  4299  	baseBuiltinFunc
  4300  	baseDateArithmitical
  4301  }
  4302  
  4303  type builtinSubDateIntDecimalSig struct {
  4304  	baseBuiltinFunc
  4305  	baseDateArithmitical
  4306  }
  4307  
  4308  func (b *builtinSubDateIntDecimalSig) Clone() builtinFunc {
  4309  	newSig := &builtinSubDateIntDecimalSig{baseDateArithmitical: b.baseDateArithmitical}
  4310  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4311  	return newSig
  4312  }
  4313  
  4314  // evalTime evals SUBDATE(date,INTERVAL expr unit).
  4315  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
  4316  func (b *builtinSubDateIntDecimalSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  4317  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  4318  	if isNull || err != nil {
  4319  		return types.ZeroTime, true, err
  4320  	}
  4321  
  4322  	date, isNull, err := b.getDateFromInt(b.ctx, b.args, event, unit)
  4323  	if isNull || err != nil {
  4324  		return types.ZeroTime, true, err
  4325  	}
  4326  
  4327  	interval, isNull, err := b.getIntervalFromDecimal(b.ctx, b.args, event, unit)
  4328  	if isNull || err != nil {
  4329  		return types.ZeroTime, true, err
  4330  	}
  4331  
  4332  	result, isNull, err := b.sub(b.ctx, date, interval, unit)
  4333  	return result, isNull || err != nil, err
  4334  }
  4335  
  4336  func (b *builtinSubDateDatetimeStringSig) Clone() builtinFunc {
  4337  	newSig := &builtinSubDateDatetimeStringSig{baseDateArithmitical: b.baseDateArithmitical}
  4338  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4339  	return newSig
  4340  }
  4341  
  4342  // evalTime evals SUBDATE(date,INTERVAL expr unit).
  4343  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
  4344  func (b *builtinSubDateDatetimeStringSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  4345  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  4346  	if isNull || err != nil {
  4347  		return types.ZeroTime, true, err
  4348  	}
  4349  
  4350  	date, isNull, err := b.getDateFromDatetime(b.ctx, b.args, event, unit)
  4351  	if isNull || err != nil {
  4352  		return types.ZeroTime, true, err
  4353  	}
  4354  
  4355  	interval, isNull, err := b.getIntervalFromString(b.ctx, b.args, event, unit)
  4356  	if isNull || err != nil {
  4357  		return types.ZeroTime, true, err
  4358  	}
  4359  
  4360  	result, isNull, err := b.sub(b.ctx, date, interval, unit)
  4361  	return result, isNull || err != nil, err
  4362  }
  4363  
  4364  type builtinSubDateDatetimeIntSig struct {
  4365  	baseBuiltinFunc
  4366  	baseDateArithmitical
  4367  }
  4368  
  4369  func (b *builtinSubDateDatetimeIntSig) Clone() builtinFunc {
  4370  	newSig := &builtinSubDateDatetimeIntSig{baseDateArithmitical: b.baseDateArithmitical}
  4371  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4372  	return newSig
  4373  }
  4374  
  4375  // evalTime evals SUBDATE(date,INTERVAL expr unit).
  4376  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
  4377  func (b *builtinSubDateDatetimeIntSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  4378  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  4379  	if isNull || err != nil {
  4380  		return types.ZeroTime, true, err
  4381  	}
  4382  
  4383  	date, isNull, err := b.getDateFromDatetime(b.ctx, b.args, event, unit)
  4384  	if isNull || err != nil {
  4385  		return types.ZeroTime, true, err
  4386  	}
  4387  
  4388  	interval, isNull, err := b.getIntervalFromInt(b.ctx, b.args, event, unit)
  4389  	if isNull || err != nil {
  4390  		return types.ZeroTime, true, err
  4391  	}
  4392  
  4393  	result, isNull, err := b.sub(b.ctx, date, interval, unit)
  4394  	return result, isNull || err != nil, err
  4395  }
  4396  
  4397  type builtinSubDateDatetimeRealSig struct {
  4398  	baseBuiltinFunc
  4399  	baseDateArithmitical
  4400  }
  4401  
  4402  func (b *builtinSubDateDatetimeRealSig) Clone() builtinFunc {
  4403  	newSig := &builtinSubDateDatetimeRealSig{baseDateArithmitical: b.baseDateArithmitical}
  4404  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4405  	return newSig
  4406  }
  4407  
  4408  // evalTime evals SUBDATE(date,INTERVAL expr unit).
  4409  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
  4410  func (b *builtinSubDateDatetimeRealSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  4411  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  4412  	if isNull || err != nil {
  4413  		return types.ZeroTime, true, err
  4414  	}
  4415  
  4416  	date, isNull, err := b.getDateFromDatetime(b.ctx, b.args, event, unit)
  4417  	if isNull || err != nil {
  4418  		return types.ZeroTime, true, err
  4419  	}
  4420  
  4421  	interval, isNull, err := b.getIntervalFromReal(b.ctx, b.args, event, unit)
  4422  	if isNull || err != nil {
  4423  		return types.ZeroTime, true, err
  4424  	}
  4425  
  4426  	result, isNull, err := b.sub(b.ctx, date, interval, unit)
  4427  	return result, isNull || err != nil, err
  4428  }
  4429  
  4430  type builtinSubDateDatetimeDecimalSig struct {
  4431  	baseBuiltinFunc
  4432  	baseDateArithmitical
  4433  }
  4434  
  4435  func (b *builtinSubDateDatetimeDecimalSig) Clone() builtinFunc {
  4436  	newSig := &builtinSubDateDatetimeDecimalSig{baseDateArithmitical: b.baseDateArithmitical}
  4437  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4438  	return newSig
  4439  }
  4440  
  4441  // evalTime evals SUBDATE(date,INTERVAL expr unit).
  4442  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
  4443  func (b *builtinSubDateDatetimeDecimalSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  4444  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  4445  	if isNull || err != nil {
  4446  		return types.ZeroTime, true, err
  4447  	}
  4448  
  4449  	date, isNull, err := b.getDateFromDatetime(b.ctx, b.args, event, unit)
  4450  	if isNull || err != nil {
  4451  		return types.ZeroTime, true, err
  4452  	}
  4453  
  4454  	interval, isNull, err := b.getIntervalFromDecimal(b.ctx, b.args, event, unit)
  4455  	if isNull || err != nil {
  4456  		return types.ZeroTime, true, err
  4457  	}
  4458  
  4459  	result, isNull, err := b.sub(b.ctx, date, interval, unit)
  4460  	return result, isNull || err != nil, err
  4461  }
  4462  
  4463  type builtinSubDateDurationStringSig struct {
  4464  	baseBuiltinFunc
  4465  	baseDateArithmitical
  4466  }
  4467  
  4468  func (b *builtinSubDateDurationStringSig) Clone() builtinFunc {
  4469  	newSig := &builtinSubDateDurationStringSig{baseDateArithmitical: b.baseDateArithmitical}
  4470  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4471  	return newSig
  4472  }
  4473  
  4474  func (b *builtinSubDateDurationStringSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  4475  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  4476  	if isNull || err != nil {
  4477  		return types.ZeroDuration, true, err
  4478  	}
  4479  
  4480  	dur, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  4481  	if isNull || err != nil {
  4482  		return types.ZeroDuration, true, err
  4483  	}
  4484  
  4485  	interval, isNull, err := b.getIntervalFromString(b.ctx, b.args, event, unit)
  4486  	if isNull || err != nil {
  4487  		return types.ZeroDuration, true, err
  4488  	}
  4489  
  4490  	result, isNull, err := b.subDuration(b.ctx, dur, interval, unit)
  4491  	return result, isNull || err != nil, err
  4492  }
  4493  
  4494  type builtinSubDateDurationIntSig struct {
  4495  	baseBuiltinFunc
  4496  	baseDateArithmitical
  4497  }
  4498  
  4499  func (b *builtinSubDateDurationIntSig) Clone() builtinFunc {
  4500  	newSig := &builtinSubDateDurationIntSig{baseDateArithmitical: b.baseDateArithmitical}
  4501  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4502  	return newSig
  4503  }
  4504  
  4505  func (b *builtinSubDateDurationIntSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  4506  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  4507  	if isNull || err != nil {
  4508  		return types.ZeroDuration, true, err
  4509  	}
  4510  
  4511  	dur, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  4512  	if isNull || err != nil {
  4513  		return types.ZeroDuration, true, err
  4514  	}
  4515  
  4516  	interval, isNull, err := b.getIntervalFromInt(b.ctx, b.args, event, unit)
  4517  	if isNull || err != nil {
  4518  		return types.ZeroDuration, true, err
  4519  	}
  4520  
  4521  	result, isNull, err := b.subDuration(b.ctx, dur, interval, unit)
  4522  	return result, isNull || err != nil, err
  4523  }
  4524  
  4525  type builtinSubDateDurationDecimalSig struct {
  4526  	baseBuiltinFunc
  4527  	baseDateArithmitical
  4528  }
  4529  
  4530  func (b *builtinSubDateDurationDecimalSig) Clone() builtinFunc {
  4531  	newSig := &builtinSubDateDurationDecimalSig{baseDateArithmitical: b.baseDateArithmitical}
  4532  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4533  	return newSig
  4534  }
  4535  
  4536  func (b *builtinSubDateDurationDecimalSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  4537  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  4538  	if isNull || err != nil {
  4539  		return types.ZeroDuration, true, err
  4540  	}
  4541  
  4542  	dur, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  4543  	if isNull || err != nil {
  4544  		return types.ZeroDuration, true, err
  4545  	}
  4546  
  4547  	interval, isNull, err := b.getIntervalFromDecimal(b.ctx, b.args, event, unit)
  4548  	if isNull || err != nil {
  4549  		return types.ZeroDuration, true, err
  4550  	}
  4551  
  4552  	result, isNull, err := b.subDuration(b.ctx, dur, interval, unit)
  4553  	return result, isNull || err != nil, err
  4554  }
  4555  
  4556  type builtinSubDateDurationRealSig struct {
  4557  	baseBuiltinFunc
  4558  	baseDateArithmitical
  4559  }
  4560  
  4561  func (b *builtinSubDateDurationRealSig) Clone() builtinFunc {
  4562  	newSig := &builtinSubDateDurationRealSig{baseDateArithmitical: b.baseDateArithmitical}
  4563  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4564  	return newSig
  4565  }
  4566  
  4567  func (b *builtinSubDateDurationRealSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  4568  	unit, isNull, err := b.args[2].EvalString(b.ctx, event)
  4569  	if isNull || err != nil {
  4570  		return types.ZeroDuration, true, err
  4571  	}
  4572  
  4573  	dur, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  4574  	if isNull || err != nil {
  4575  		return types.ZeroDuration, true, err
  4576  	}
  4577  	interval, isNull, err := b.getIntervalFromReal(b.ctx, b.args, event, unit)
  4578  	if isNull || err != nil {
  4579  		return types.ZeroDuration, true, err
  4580  	}
  4581  
  4582  	result, isNull, err := b.subDuration(b.ctx, dur, interval, unit)
  4583  	return result, isNull || err != nil, err
  4584  }
  4585  
  4586  type timestamFIDeliffFunctionClass struct {
  4587  	baseFunctionClass
  4588  }
  4589  
  4590  func (c *timestamFIDeliffFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  4591  	if err := c.verifyArgs(args); err != nil {
  4592  		return nil, err
  4593  	}
  4594  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETString, types.ETDatetime, types.ETDatetime)
  4595  	if err != nil {
  4596  		return nil, err
  4597  	}
  4598  	sig := &builtinTimestamFIDeliffSig{bf}
  4599  	sig.setPbCode(fidelpb.ScalarFuncSig_TimestamFIDeliff)
  4600  	return sig, nil
  4601  }
  4602  
  4603  type builtinTimestamFIDeliffSig struct {
  4604  	baseBuiltinFunc
  4605  }
  4606  
  4607  func (b *builtinTimestamFIDeliffSig) Clone() builtinFunc {
  4608  	newSig := &builtinTimestamFIDeliffSig{}
  4609  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4610  	return newSig
  4611  }
  4612  
  4613  // evalInt evals a builtinTimestamFIDeliffSig.
  4614  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timestamFIDeliff
  4615  func (b *builtinTimestamFIDeliffSig) evalInt(event chunk.Event) (int64, bool, error) {
  4616  	unit, isNull, err := b.args[0].EvalString(b.ctx, event)
  4617  	if isNull || err != nil {
  4618  		return 0, isNull, err
  4619  	}
  4620  	lhs, isNull, err := b.args[1].EvalTime(b.ctx, event)
  4621  	if isNull || err != nil {
  4622  		return 0, isNull, handleInvalidTimeError(b.ctx, err)
  4623  	}
  4624  	rhs, isNull, err := b.args[2].EvalTime(b.ctx, event)
  4625  	if isNull || err != nil {
  4626  		return 0, isNull, handleInvalidTimeError(b.ctx, err)
  4627  	}
  4628  	if invalidLHS, invalidRHS := lhs.InvalidZero(), rhs.InvalidZero(); invalidLHS || invalidRHS {
  4629  		if invalidLHS {
  4630  			err = handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, lhs.String()))
  4631  		}
  4632  		if invalidRHS {
  4633  			err = handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, rhs.String()))
  4634  		}
  4635  		return 0, true, err
  4636  	}
  4637  	return types.TimestamFIDeliff(unit, lhs, rhs), false, nil
  4638  }
  4639  
  4640  type unixTimestampFunctionClass struct {
  4641  	baseFunctionClass
  4642  }
  4643  
  4644  func (c *unixTimestampFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  4645  	if err := c.verifyArgs(args); err != nil {
  4646  		return nil, err
  4647  	}
  4648  	var (
  4649  		argTps              []types.EvalType
  4650  		retTp               types.EvalType
  4651  		retFLen, retDecimal int
  4652  	)
  4653  
  4654  	if len(args) == 0 {
  4655  		retTp, retDecimal = types.ETInt, 0
  4656  	} else {
  4657  		argTps = []types.EvalType{types.ETDatetime}
  4658  		argType := args[0].GetType()
  4659  		argEvaltp := argType.EvalType()
  4660  		if argEvaltp == types.ETString {
  4661  			// Treat types.ETString as unspecified decimal.
  4662  			retDecimal = types.UnspecifiedLength
  4663  			if cnst, ok := args[0].(*Constant); ok {
  4664  				tmpStr, _, err := cnst.EvalString(ctx, chunk.Event{})
  4665  				if err != nil {
  4666  					return nil, err
  4667  				}
  4668  				retDecimal = 0
  4669  				if dotIdx := strings.LastIndex(tmpStr, "."); dotIdx >= 0 {
  4670  					retDecimal = len(tmpStr) - dotIdx - 1
  4671  				}
  4672  			}
  4673  		} else {
  4674  			retDecimal = argType.Decimal
  4675  		}
  4676  		if retDecimal > 6 || retDecimal == types.UnspecifiedLength {
  4677  			retDecimal = 6
  4678  		}
  4679  		if retDecimal == 0 {
  4680  			retTp = types.ETInt
  4681  		} else {
  4682  			retTp = types.ETDecimal
  4683  		}
  4684  	}
  4685  	if retTp == types.ETInt {
  4686  		retFLen = 11
  4687  	} else if retTp == types.ETDecimal {
  4688  		retFLen = 12 + retDecimal
  4689  	} else {
  4690  		panic("Unexpected retTp")
  4691  	}
  4692  
  4693  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, retTp, argTps...)
  4694  	if err != nil {
  4695  		return nil, err
  4696  	}
  4697  	bf.tp.Flen = retFLen
  4698  	bf.tp.Decimal = retDecimal
  4699  
  4700  	var sig builtinFunc
  4701  	if len(args) == 0 {
  4702  		sig = &builtinUnixTimestampCurrentSig{bf}
  4703  		sig.setPbCode(fidelpb.ScalarFuncSig_UnixTimestampCurrent)
  4704  	} else if retTp == types.ETInt {
  4705  		sig = &builtinUnixTimestampIntSig{bf}
  4706  		sig.setPbCode(fidelpb.ScalarFuncSig_UnixTimestampInt)
  4707  	} else if retTp == types.ETDecimal {
  4708  		sig = &builtinUnixTimestamFIDelecSig{bf}
  4709  		sig.setPbCode(fidelpb.ScalarFuncSig_UnixTimestamFIDelec)
  4710  	}
  4711  	return sig, nil
  4712  }
  4713  
  4714  // goTimeToMysqlUnixTimestamp converts go time into MyALLEGROSQL's Unix timestamp.
  4715  // MyALLEGROSQL's Unix timestamp ranges in int32. Values out of range should be rewritten to 0.
  4716  func goTimeToMysqlUnixTimestamp(t time.Time, decimal int) (*types.MyDecimal, error) {
  4717  	nanoSeconds := t.UnixNano()
  4718  	if nanoSeconds < 0 || (nanoSeconds/1e3) >= (math.MaxInt32+1)*1e6 {
  4719  		return new(types.MyDecimal), nil
  4720  	}
  4721  	dec := new(types.MyDecimal)
  4722  	// Here we don't use float to prevent precision lose.
  4723  	dec.FromInt(nanoSeconds)
  4724  	err := dec.Shift(-9)
  4725  	if err != nil {
  4726  		return nil, err
  4727  	}
  4728  
  4729  	// In MyALLEGROSQL's implementation, unix_timestamp() will truncate the result instead of rounding it.
  4730  	// Results below are from MyALLEGROSQL 5.7, which can prove it.
  4731  	//	allegrosql> select unix_timestamp(), unix_timestamp(now(0)), now(0), unix_timestamp(now(3)), now(3), now(6);
  4732  	//	+------------------+------------------------+---------------------+------------------------+-------------------------+----------------------------+
  4733  	//	| unix_timestamp() | unix_timestamp(now(0)) | now(0)              | unix_timestamp(now(3)) | now(3)                  | now(6)                     |
  4734  	//	+------------------+------------------------+---------------------+------------------------+-------------------------+----------------------------+
  4735  	//	|       1553503194 |             1553503194 | 2020-03-25 16:39:54 |         1553503194.992 | 2020-03-25 16:39:54.992 | 2020-03-25 16:39:54.992969 |
  4736  	//	+------------------+------------------------+---------------------+------------------------+-------------------------+----------------------------+
  4737  	err = dec.Round(dec, decimal, types.ModeTruncate)
  4738  	return dec, err
  4739  }
  4740  
  4741  type builtinUnixTimestampCurrentSig struct {
  4742  	baseBuiltinFunc
  4743  }
  4744  
  4745  func (b *builtinUnixTimestampCurrentSig) Clone() builtinFunc {
  4746  	newSig := &builtinUnixTimestampCurrentSig{}
  4747  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4748  	return newSig
  4749  }
  4750  
  4751  // evalInt evals a UNIX_TIMESTAMP().
  4752  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_unix-timestamp
  4753  func (b *builtinUnixTimestampCurrentSig) evalInt(event chunk.Event) (int64, bool, error) {
  4754  	nowTs, err := getStmtTimestamp(b.ctx)
  4755  	if err != nil {
  4756  		return 0, true, err
  4757  	}
  4758  	dec, err := goTimeToMysqlUnixTimestamp(nowTs, 1)
  4759  	if err != nil {
  4760  		return 0, true, err
  4761  	}
  4762  	intVal, err := dec.ToInt()
  4763  	if !terror.ErrorEqual(err, types.ErrTruncated) {
  4764  		terror.Log(err)
  4765  	}
  4766  	return intVal, false, nil
  4767  }
  4768  
  4769  type builtinUnixTimestampIntSig struct {
  4770  	baseBuiltinFunc
  4771  }
  4772  
  4773  func (b *builtinUnixTimestampIntSig) Clone() builtinFunc {
  4774  	newSig := &builtinUnixTimestampIntSig{}
  4775  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4776  	return newSig
  4777  }
  4778  
  4779  // evalInt evals a UNIX_TIMESTAMP(time).
  4780  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_unix-timestamp
  4781  func (b *builtinUnixTimestampIntSig) evalInt(event chunk.Event) (int64, bool, error) {
  4782  	return b.evalIntWithCtx(b.ctx, event)
  4783  }
  4784  
  4785  func (b *builtinUnixTimestampIntSig) evalIntWithCtx(ctx stochastikctx.Context, event chunk.Event) (int64, bool, error) {
  4786  	val, isNull, err := b.args[0].EvalTime(ctx, event)
  4787  	if err != nil && terror.ErrorEqual(types.ErrWrongValue.GenWithStackByArgs(types.TimeStr, val), err) {
  4788  		// Return 0 for invalid date time.
  4789  		return 0, false, nil
  4790  	}
  4791  	if isNull {
  4792  		return 0, true, nil
  4793  	}
  4794  
  4795  	tz := ctx.GetStochastikVars().Location()
  4796  	t, err := val.GoTime(tz)
  4797  	if err != nil {
  4798  		return 0, false, nil
  4799  	}
  4800  	dec, err := goTimeToMysqlUnixTimestamp(t, 1)
  4801  	if err != nil {
  4802  		return 0, true, err
  4803  	}
  4804  	intVal, err := dec.ToInt()
  4805  	if !terror.ErrorEqual(err, types.ErrTruncated) {
  4806  		terror.Log(err)
  4807  	}
  4808  	return intVal, false, nil
  4809  }
  4810  
  4811  type builtinUnixTimestamFIDelecSig struct {
  4812  	baseBuiltinFunc
  4813  }
  4814  
  4815  func (b *builtinUnixTimestamFIDelecSig) Clone() builtinFunc {
  4816  	newSig := &builtinUnixTimestamFIDelecSig{}
  4817  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4818  	return newSig
  4819  }
  4820  
  4821  // evalDecimal evals a UNIX_TIMESTAMP(time).
  4822  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_unix-timestamp
  4823  func (b *builtinUnixTimestamFIDelecSig) evalDecimal(event chunk.Event) (*types.MyDecimal, bool, error) {
  4824  	val, isNull, err := b.args[0].EvalTime(b.ctx, event)
  4825  	if isNull || err != nil {
  4826  		// Return 0 for invalid date time.
  4827  		return new(types.MyDecimal), isNull, nil
  4828  	}
  4829  	t, err := val.GoTime(getTimeZone(b.ctx))
  4830  	if err != nil {
  4831  		return new(types.MyDecimal), false, nil
  4832  	}
  4833  	result, err := goTimeToMysqlUnixTimestamp(t, b.tp.Decimal)
  4834  	return result, err != nil, err
  4835  }
  4836  
  4837  type timestampFunctionClass struct {
  4838  	baseFunctionClass
  4839  }
  4840  
  4841  func (c *timestampFunctionClass) getDefaultFsp(tp *types.FieldType) int8 {
  4842  	if tp.Tp == allegrosql.TypeDatetime || tp.Tp == allegrosql.TypeDate || tp.Tp == allegrosql.TypeDuration ||
  4843  		tp.Tp == allegrosql.TypeTimestamp {
  4844  		return int8(tp.Decimal)
  4845  	}
  4846  	switch cls := tp.EvalType(); cls {
  4847  	case types.ETInt:
  4848  		return types.MinFsp
  4849  	case types.ETReal, types.ETDatetime, types.ETTimestamp, types.ETDuration, types.ETJson, types.ETString:
  4850  		return types.MaxFsp
  4851  	case types.ETDecimal:
  4852  		if tp.Decimal < int(types.MaxFsp) {
  4853  			return int8(tp.Decimal)
  4854  		}
  4855  		return types.MaxFsp
  4856  	}
  4857  	return types.MaxFsp
  4858  }
  4859  
  4860  func (c *timestampFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  4861  	if err := c.verifyArgs(args); err != nil {
  4862  		return nil, err
  4863  	}
  4864  	evalTps, argLen := []types.EvalType{types.ETString}, len(args)
  4865  	if argLen == 2 {
  4866  		evalTps = append(evalTps, types.ETString)
  4867  	}
  4868  	fsp := c.getDefaultFsp(args[0].GetType())
  4869  	if argLen == 2 {
  4870  		fsp = mathutil.MaxInt8(fsp, c.getDefaultFsp(args[1].GetType()))
  4871  	}
  4872  	isFloat := false
  4873  	switch args[0].GetType().Tp {
  4874  	case allegrosql.TypeFloat, allegrosql.TypeDouble, allegrosql.TypeNewDecimal:
  4875  		isFloat = true
  4876  	}
  4877  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDatetime, evalTps...)
  4878  	if err != nil {
  4879  		return nil, err
  4880  	}
  4881  	bf.tp.Decimal, bf.tp.Flen = -1, 19
  4882  	if fsp != 0 {
  4883  		bf.tp.Flen += 1 + int(fsp)
  4884  	}
  4885  	var sig builtinFunc
  4886  	if argLen == 2 {
  4887  		sig = &builtinTimestamp2ArgsSig{bf, isFloat}
  4888  		sig.setPbCode(fidelpb.ScalarFuncSig_Timestamp2Args)
  4889  	} else {
  4890  		sig = &builtinTimestamp1ArgSig{bf, isFloat}
  4891  		sig.setPbCode(fidelpb.ScalarFuncSig_Timestamp1Arg)
  4892  	}
  4893  	return sig, nil
  4894  }
  4895  
  4896  type builtinTimestamp1ArgSig struct {
  4897  	baseBuiltinFunc
  4898  
  4899  	isFloat bool
  4900  }
  4901  
  4902  func (b *builtinTimestamp1ArgSig) Clone() builtinFunc {
  4903  	newSig := &builtinTimestamp1ArgSig{isFloat: b.isFloat}
  4904  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4905  	return newSig
  4906  }
  4907  
  4908  // evalTime evals a builtinTimestamp1ArgSig.
  4909  // See https://dev.allegrosql.com/doc/refman/5.5/en/date-and-time-functions.html#function_timestamp
  4910  func (b *builtinTimestamp1ArgSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  4911  	s, isNull, err := b.args[0].EvalString(b.ctx, event)
  4912  	if isNull || err != nil {
  4913  		return types.ZeroTime, isNull, err
  4914  	}
  4915  	var tm types.Time
  4916  	sc := b.ctx.GetStochastikVars().StmtCtx
  4917  	if b.isFloat {
  4918  		tm, err = types.ParseTimeFromFloatString(sc, s, allegrosql.TypeDatetime, types.GetFsp(s))
  4919  	} else {
  4920  		tm, err = types.ParseTime(sc, s, allegrosql.TypeDatetime, types.GetFsp(s))
  4921  	}
  4922  	if err != nil {
  4923  		return types.ZeroTime, true, handleInvalidTimeError(b.ctx, err)
  4924  	}
  4925  	return tm, false, nil
  4926  }
  4927  
  4928  type builtinTimestamp2ArgsSig struct {
  4929  	baseBuiltinFunc
  4930  
  4931  	isFloat bool
  4932  }
  4933  
  4934  func (b *builtinTimestamp2ArgsSig) Clone() builtinFunc {
  4935  	newSig := &builtinTimestamp2ArgsSig{isFloat: b.isFloat}
  4936  	newSig.cloneFrom(&b.baseBuiltinFunc)
  4937  	return newSig
  4938  }
  4939  
  4940  // evalTime evals a builtinTimestamp2ArgsSig.
  4941  // See https://dev.allegrosql.com/doc/refman/5.5/en/date-and-time-functions.html#function_timestamp
  4942  func (b *builtinTimestamp2ArgsSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  4943  	arg0, isNull, err := b.args[0].EvalString(b.ctx, event)
  4944  	if isNull || err != nil {
  4945  		return types.ZeroTime, isNull, err
  4946  	}
  4947  	var tm types.Time
  4948  	sc := b.ctx.GetStochastikVars().StmtCtx
  4949  	if b.isFloat {
  4950  		tm, err = types.ParseTimeFromFloatString(sc, arg0, allegrosql.TypeDatetime, types.GetFsp(arg0))
  4951  	} else {
  4952  		tm, err = types.ParseTime(sc, arg0, allegrosql.TypeDatetime, types.GetFsp(arg0))
  4953  	}
  4954  	if err != nil {
  4955  		return types.ZeroTime, true, handleInvalidTimeError(b.ctx, err)
  4956  	}
  4957  	arg1, isNull, err := b.args[1].EvalString(b.ctx, event)
  4958  	if isNull || err != nil {
  4959  		return types.ZeroTime, isNull, err
  4960  	}
  4961  	if !isDuration(arg1) {
  4962  		return types.ZeroTime, true, nil
  4963  	}
  4964  	duration, err := types.ParseDuration(sc, arg1, types.GetFsp(arg1))
  4965  	if err != nil {
  4966  		return types.ZeroTime, true, handleInvalidTimeError(b.ctx, err)
  4967  	}
  4968  	tmp, err := tm.Add(sc, duration)
  4969  	if err != nil {
  4970  		return types.ZeroTime, true, err
  4971  	}
  4972  	return tmp, false, nil
  4973  }
  4974  
  4975  type timestampLiteralFunctionClass struct {
  4976  	baseFunctionClass
  4977  }
  4978  
  4979  func (c *timestampLiteralFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  4980  	if err := c.verifyArgs(args); err != nil {
  4981  		return nil, err
  4982  	}
  4983  	con, ok := args[0].(*Constant)
  4984  	if !ok {
  4985  		panic("Unexpected parameter for timestamp literal")
  4986  	}
  4987  	dt, err := con.Eval(chunk.Event{})
  4988  	if err != nil {
  4989  		return nil, err
  4990  	}
  4991  	str, err := dt.ToString()
  4992  	if err != nil {
  4993  		return nil, err
  4994  	}
  4995  	if !timestampPattern.MatchString(str) {
  4996  		return nil, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, str)
  4997  	}
  4998  	tm, err := types.ParseTime(ctx.GetStochastikVars().StmtCtx, str, allegrosql.TypeTimestamp, types.GetFsp(str))
  4999  	if err != nil {
  5000  		return nil, err
  5001  	}
  5002  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, []Expression{}, types.ETDatetime)
  5003  	if err != nil {
  5004  		return nil, err
  5005  	}
  5006  	bf.tp.Flen, bf.tp.Decimal = allegrosql.MaxDatetimeWidthNoFsp, int(tm.Fsp())
  5007  	if tm.Fsp() > 0 {
  5008  		bf.tp.Flen += int(tm.Fsp()) + 1
  5009  	}
  5010  	sig := &builtinTimestampLiteralSig{bf, tm}
  5011  	return sig, nil
  5012  }
  5013  
  5014  type builtinTimestampLiteralSig struct {
  5015  	baseBuiltinFunc
  5016  	tm types.Time
  5017  }
  5018  
  5019  func (b *builtinTimestampLiteralSig) Clone() builtinFunc {
  5020  	newSig := &builtinTimestampLiteralSig{tm: b.tm}
  5021  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5022  	return newSig
  5023  }
  5024  
  5025  // evalTime evals TIMESTAMP 'stringLit'.
  5026  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-literals.html
  5027  func (b *builtinTimestampLiteralSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  5028  	return b.tm, false, nil
  5029  }
  5030  
  5031  // getFsp4TimeAddSub is used to in function 'ADDTIME' and 'SUBTIME' to evaluate `fsp` for the
  5032  // second parameter. It's used only if the second parameter is of string type. It's different
  5033  // from getFsp in that the result of getFsp4TimeAddSub is either 6 or 0.
  5034  func getFsp4TimeAddSub(s string) int8 {
  5035  	if len(s)-strings.Index(s, ".")-1 == len(s) {
  5036  		return types.MinFsp
  5037  	}
  5038  	for _, c := range s[strings.Index(s, ".")+1:] {
  5039  		if c != '0' {
  5040  			return types.MaxFsp
  5041  		}
  5042  	}
  5043  	return types.MinFsp
  5044  }
  5045  
  5046  // getBf4TimeAddSub parses input types, generates baseBuiltinFunc and set related attributes for
  5047  // builtin function 'ADDTIME' and 'SUBTIME'
  5048  func getBf4TimeAddSub(ctx stochastikctx.Context, funcName string, args []Expression) (tp1, tp2 *types.FieldType, bf baseBuiltinFunc, err error) {
  5049  	tp1, tp2 = args[0].GetType(), args[1].GetType()
  5050  	var argTp1, argTp2, retTp types.EvalType
  5051  	switch tp1.Tp {
  5052  	case allegrosql.TypeDatetime, allegrosql.TypeTimestamp:
  5053  		argTp1, retTp = types.ETDatetime, types.ETDatetime
  5054  	case allegrosql.TypeDuration:
  5055  		argTp1, retTp = types.ETDuration, types.ETDuration
  5056  	case allegrosql.TypeDate:
  5057  		argTp1, retTp = types.ETDuration, types.ETString
  5058  	default:
  5059  		argTp1, retTp = types.ETString, types.ETString
  5060  	}
  5061  	switch tp2.Tp {
  5062  	case allegrosql.TypeDatetime, allegrosql.TypeDuration:
  5063  		argTp2 = types.ETDuration
  5064  	default:
  5065  		argTp2 = types.ETString
  5066  	}
  5067  	arg0Dec, err := getExpressionFsp(ctx, args[0])
  5068  	if err != nil {
  5069  		return
  5070  	}
  5071  	arg1Dec, err := getExpressionFsp(ctx, args[1])
  5072  	if err != nil {
  5073  		return
  5074  	}
  5075  
  5076  	bf, err = newBaseBuiltinFuncWithTp(ctx, funcName, args, retTp, argTp1, argTp2)
  5077  	if err != nil {
  5078  		return
  5079  	}
  5080  	bf.tp.Decimal = mathutil.Min(mathutil.Max(arg0Dec, arg1Dec), int(types.MaxFsp))
  5081  	if retTp == types.ETString {
  5082  		bf.tp.Tp, bf.tp.Flen, bf.tp.Decimal = allegrosql.TypeString, allegrosql.MaxDatetimeWidthWithFsp, types.UnspecifiedLength
  5083  	}
  5084  	return
  5085  }
  5086  
  5087  func getTimeZone(ctx stochastikctx.Context) *time.Location {
  5088  	ret := ctx.GetStochastikVars().TimeZone
  5089  	if ret == nil {
  5090  		ret = time.Local
  5091  	}
  5092  	return ret
  5093  }
  5094  
  5095  // isDuration returns a boolean indicating whether the str matches the format of duration.
  5096  // See https://dev.allegrosql.com/doc/refman/5.7/en/time.html
  5097  func isDuration(str string) bool {
  5098  	return durationPattern.MatchString(str)
  5099  }
  5100  
  5101  // strDatetimeAddDuration adds duration to datetime string, returns a string value.
  5102  func strDatetimeAddDuration(sc *stmtctx.StatementContext, d string, arg1 types.Duration) (string, error) {
  5103  	arg0, err := types.ParseTime(sc, d, allegrosql.TypeDatetime, types.MaxFsp)
  5104  	if err != nil {
  5105  		return "", err
  5106  	}
  5107  	ret, err := arg0.Add(sc, arg1)
  5108  	if err != nil {
  5109  		return "", err
  5110  	}
  5111  	fsp := types.MaxFsp
  5112  	if ret.Microsecond() == 0 {
  5113  		fsp = types.MinFsp
  5114  	}
  5115  	ret.SetFsp(fsp)
  5116  	return ret.String(), nil
  5117  }
  5118  
  5119  // strDurationAddDuration adds duration to duration string, returns a string value.
  5120  func strDurationAddDuration(sc *stmtctx.StatementContext, d string, arg1 types.Duration) (string, error) {
  5121  	arg0, err := types.ParseDuration(sc, d, types.MaxFsp)
  5122  	if err != nil {
  5123  		return "", err
  5124  	}
  5125  	tmFIDeluration, err := arg0.Add(arg1)
  5126  	if err != nil {
  5127  		return "", err
  5128  	}
  5129  	tmFIDeluration.Fsp = types.MaxFsp
  5130  	if tmFIDeluration.MicroSecond() == 0 {
  5131  		tmFIDeluration.Fsp = types.MinFsp
  5132  	}
  5133  	return tmFIDeluration.String(), nil
  5134  }
  5135  
  5136  // strDatetimeSubDuration subtracts duration from datetime string, returns a string value.
  5137  func strDatetimeSubDuration(sc *stmtctx.StatementContext, d string, arg1 types.Duration) (string, error) {
  5138  	arg0, err := types.ParseTime(sc, d, allegrosql.TypeDatetime, types.MaxFsp)
  5139  	if err != nil {
  5140  		return "", err
  5141  	}
  5142  	arg1time, err := arg1.ConvertToTime(sc, uint8(types.GetFsp(arg1.String())))
  5143  	if err != nil {
  5144  		return "", err
  5145  	}
  5146  	tmFIDeluration := arg0.Sub(sc, &arg1time)
  5147  	fsp := types.MaxFsp
  5148  	if tmFIDeluration.MicroSecond() == 0 {
  5149  		fsp = types.MinFsp
  5150  	}
  5151  	resultDuration, err := tmFIDeluration.ConvertToTime(sc, allegrosql.TypeDatetime)
  5152  	if err != nil {
  5153  		return "", err
  5154  	}
  5155  	resultDuration.SetFsp(fsp)
  5156  	return resultDuration.String(), nil
  5157  }
  5158  
  5159  // strDurationSubDuration subtracts duration from duration string, returns a string value.
  5160  func strDurationSubDuration(sc *stmtctx.StatementContext, d string, arg1 types.Duration) (string, error) {
  5161  	arg0, err := types.ParseDuration(sc, d, types.MaxFsp)
  5162  	if err != nil {
  5163  		return "", err
  5164  	}
  5165  	tmFIDeluration, err := arg0.Sub(arg1)
  5166  	if err != nil {
  5167  		return "", err
  5168  	}
  5169  	tmFIDeluration.Fsp = types.MaxFsp
  5170  	if tmFIDeluration.MicroSecond() == 0 {
  5171  		tmFIDeluration.Fsp = types.MinFsp
  5172  	}
  5173  	return tmFIDeluration.String(), nil
  5174  }
  5175  
  5176  type addTimeFunctionClass struct {
  5177  	baseFunctionClass
  5178  }
  5179  
  5180  func (c *addTimeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) {
  5181  	if err = c.verifyArgs(args); err != nil {
  5182  		return nil, err
  5183  	}
  5184  	tp1, tp2, bf, err := getBf4TimeAddSub(ctx, c.funcName, args)
  5185  	if err != nil {
  5186  		return nil, err
  5187  	}
  5188  	switch tp1.Tp {
  5189  	case allegrosql.TypeDatetime, allegrosql.TypeTimestamp:
  5190  		switch tp2.Tp {
  5191  		case allegrosql.TypeDuration:
  5192  			sig = &builtinAddDatetimeAndDurationSig{bf}
  5193  			sig.setPbCode(fidelpb.ScalarFuncSig_AddDatetimeAndDuration)
  5194  		case allegrosql.TypeDatetime, allegrosql.TypeTimestamp:
  5195  			sig = &builtinAddTimeDateTimeNullSig{bf}
  5196  			sig.setPbCode(fidelpb.ScalarFuncSig_AddTimeDateTimeNull)
  5197  		default:
  5198  			sig = &builtinAddDatetimeAndStringSig{bf}
  5199  			sig.setPbCode(fidelpb.ScalarFuncSig_AddDatetimeAndString)
  5200  		}
  5201  	case allegrosql.TypeDate:
  5202  		bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo()
  5203  		switch tp2.Tp {
  5204  		case allegrosql.TypeDuration:
  5205  			sig = &builtinAddDateAndDurationSig{bf}
  5206  			sig.setPbCode(fidelpb.ScalarFuncSig_AddDateAndDuration)
  5207  		case allegrosql.TypeDatetime, allegrosql.TypeTimestamp:
  5208  			sig = &builtinAddTimeStringNullSig{bf}
  5209  			sig.setPbCode(fidelpb.ScalarFuncSig_AddTimeStringNull)
  5210  		default:
  5211  			sig = &builtinAddDateAndStringSig{bf}
  5212  			sig.setPbCode(fidelpb.ScalarFuncSig_AddDateAndString)
  5213  		}
  5214  	case allegrosql.TypeDuration:
  5215  		switch tp2.Tp {
  5216  		case allegrosql.TypeDuration:
  5217  			sig = &builtinAddDurationAndDurationSig{bf}
  5218  			sig.setPbCode(fidelpb.ScalarFuncSig_AddDurationAndDuration)
  5219  		case allegrosql.TypeDatetime, allegrosql.TypeTimestamp:
  5220  			sig = &builtinAddTimeDurationNullSig{bf}
  5221  			sig.setPbCode(fidelpb.ScalarFuncSig_AddTimeDurationNull)
  5222  		default:
  5223  			sig = &builtinAddDurationAndStringSig{bf}
  5224  			sig.setPbCode(fidelpb.ScalarFuncSig_AddDurationAndString)
  5225  		}
  5226  	default:
  5227  		switch tp2.Tp {
  5228  		case allegrosql.TypeDuration:
  5229  			sig = &builtinAddStringAndDurationSig{bf}
  5230  			sig.setPbCode(fidelpb.ScalarFuncSig_AddStringAndDuration)
  5231  		case allegrosql.TypeDatetime, allegrosql.TypeTimestamp:
  5232  			sig = &builtinAddTimeStringNullSig{bf}
  5233  			sig.setPbCode(fidelpb.ScalarFuncSig_AddTimeStringNull)
  5234  		default:
  5235  			sig = &builtinAddStringAndStringSig{bf}
  5236  			sig.setPbCode(fidelpb.ScalarFuncSig_AddStringAndString)
  5237  		}
  5238  	}
  5239  	return sig, nil
  5240  }
  5241  
  5242  type builtinAddTimeDateTimeNullSig struct {
  5243  	baseBuiltinFunc
  5244  }
  5245  
  5246  func (b *builtinAddTimeDateTimeNullSig) Clone() builtinFunc {
  5247  	newSig := &builtinAddTimeDateTimeNullSig{}
  5248  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5249  	return newSig
  5250  }
  5251  
  5252  // evalTime evals a builtinAddTimeDateTimeNullSig.
  5253  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_addtime
  5254  func (b *builtinAddTimeDateTimeNullSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  5255  	return types.ZeroDatetime, true, nil
  5256  }
  5257  
  5258  type builtinAddDatetimeAndDurationSig struct {
  5259  	baseBuiltinFunc
  5260  }
  5261  
  5262  func (b *builtinAddDatetimeAndDurationSig) Clone() builtinFunc {
  5263  	newSig := &builtinAddDatetimeAndDurationSig{}
  5264  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5265  	return newSig
  5266  }
  5267  
  5268  // evalTime evals a builtinAddDatetimeAndDurationSig.
  5269  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_addtime
  5270  func (b *builtinAddDatetimeAndDurationSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  5271  	arg0, isNull, err := b.args[0].EvalTime(b.ctx, event)
  5272  	if isNull || err != nil {
  5273  		return types.ZeroDatetime, isNull, err
  5274  	}
  5275  	arg1, isNull, err := b.args[1].EvalDuration(b.ctx, event)
  5276  	if isNull || err != nil {
  5277  		return types.ZeroDatetime, isNull, err
  5278  	}
  5279  	result, err := arg0.Add(b.ctx.GetStochastikVars().StmtCtx, arg1)
  5280  	return result, err != nil, err
  5281  }
  5282  
  5283  type builtinAddDatetimeAndStringSig struct {
  5284  	baseBuiltinFunc
  5285  }
  5286  
  5287  func (b *builtinAddDatetimeAndStringSig) Clone() builtinFunc {
  5288  	newSig := &builtinAddDatetimeAndStringSig{}
  5289  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5290  	return newSig
  5291  }
  5292  
  5293  // evalTime evals a builtinAddDatetimeAndStringSig.
  5294  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_addtime
  5295  func (b *builtinAddDatetimeAndStringSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  5296  	arg0, isNull, err := b.args[0].EvalTime(b.ctx, event)
  5297  	if isNull || err != nil {
  5298  		return types.ZeroDatetime, isNull, err
  5299  	}
  5300  	s, isNull, err := b.args[1].EvalString(b.ctx, event)
  5301  	if isNull || err != nil {
  5302  		return types.ZeroDatetime, isNull, err
  5303  	}
  5304  	if !isDuration(s) {
  5305  		return types.ZeroDatetime, true, nil
  5306  	}
  5307  	sc := b.ctx.GetStochastikVars().StmtCtx
  5308  	arg1, err := types.ParseDuration(sc, s, types.GetFsp(s))
  5309  	if err != nil {
  5310  		if terror.ErrorEqual(err, types.ErrTruncatedWrongVal) {
  5311  			sc.AppendWarning(err)
  5312  			return types.ZeroDatetime, true, nil
  5313  		}
  5314  		return types.ZeroDatetime, true, err
  5315  	}
  5316  	result, err := arg0.Add(sc, arg1)
  5317  	return result, err != nil, err
  5318  }
  5319  
  5320  type builtinAddTimeDurationNullSig struct {
  5321  	baseBuiltinFunc
  5322  }
  5323  
  5324  func (b *builtinAddTimeDurationNullSig) Clone() builtinFunc {
  5325  	newSig := &builtinAddTimeDurationNullSig{}
  5326  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5327  	return newSig
  5328  }
  5329  
  5330  // evalDuration evals a builtinAddTimeDurationNullSig.
  5331  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_addtime
  5332  func (b *builtinAddTimeDurationNullSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  5333  	return types.ZeroDuration, true, nil
  5334  }
  5335  
  5336  type builtinAddDurationAndDurationSig struct {
  5337  	baseBuiltinFunc
  5338  }
  5339  
  5340  func (b *builtinAddDurationAndDurationSig) Clone() builtinFunc {
  5341  	newSig := &builtinAddDurationAndDurationSig{}
  5342  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5343  	return newSig
  5344  }
  5345  
  5346  // evalDuration evals a builtinAddDurationAndDurationSig.
  5347  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_addtime
  5348  func (b *builtinAddDurationAndDurationSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  5349  	arg0, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  5350  	if isNull || err != nil {
  5351  		return types.ZeroDuration, isNull, err
  5352  	}
  5353  	arg1, isNull, err := b.args[1].EvalDuration(b.ctx, event)
  5354  	if isNull || err != nil {
  5355  		return types.ZeroDuration, isNull, err
  5356  	}
  5357  	result, err := arg0.Add(arg1)
  5358  	if err != nil {
  5359  		return types.ZeroDuration, true, err
  5360  	}
  5361  	return result, false, nil
  5362  }
  5363  
  5364  type builtinAddDurationAndStringSig struct {
  5365  	baseBuiltinFunc
  5366  }
  5367  
  5368  func (b *builtinAddDurationAndStringSig) Clone() builtinFunc {
  5369  	newSig := &builtinAddDurationAndStringSig{}
  5370  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5371  	return newSig
  5372  }
  5373  
  5374  // evalDuration evals a builtinAddDurationAndStringSig.
  5375  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_addtime
  5376  func (b *builtinAddDurationAndStringSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  5377  	arg0, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  5378  	if isNull || err != nil {
  5379  		return types.ZeroDuration, isNull, err
  5380  	}
  5381  	s, isNull, err := b.args[1].EvalString(b.ctx, event)
  5382  	if isNull || err != nil {
  5383  		return types.ZeroDuration, isNull, err
  5384  	}
  5385  	if !isDuration(s) {
  5386  		return types.ZeroDuration, true, nil
  5387  	}
  5388  	sc := b.ctx.GetStochastikVars().StmtCtx
  5389  	arg1, err := types.ParseDuration(sc, s, types.GetFsp(s))
  5390  	if err != nil {
  5391  		if terror.ErrorEqual(err, types.ErrTruncatedWrongVal) {
  5392  			sc.AppendWarning(err)
  5393  			return types.ZeroDuration, true, nil
  5394  		}
  5395  		return types.ZeroDuration, true, err
  5396  	}
  5397  	result, err := arg0.Add(arg1)
  5398  	if err != nil {
  5399  		return types.ZeroDuration, true, err
  5400  	}
  5401  	return result, false, nil
  5402  }
  5403  
  5404  type builtinAddTimeStringNullSig struct {
  5405  	baseBuiltinFunc
  5406  }
  5407  
  5408  func (b *builtinAddTimeStringNullSig) Clone() builtinFunc {
  5409  	newSig := &builtinAddTimeStringNullSig{}
  5410  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5411  	return newSig
  5412  }
  5413  
  5414  // evalString evals a builtinAddDurationAndDurationSig.
  5415  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_addtime
  5416  func (b *builtinAddTimeStringNullSig) evalString(event chunk.Event) (string, bool, error) {
  5417  	return "", true, nil
  5418  }
  5419  
  5420  type builtinAddStringAndDurationSig struct {
  5421  	baseBuiltinFunc
  5422  }
  5423  
  5424  func (b *builtinAddStringAndDurationSig) Clone() builtinFunc {
  5425  	newSig := &builtinAddStringAndDurationSig{}
  5426  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5427  	return newSig
  5428  }
  5429  
  5430  // evalString evals a builtinAddStringAndDurationSig.
  5431  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_addtime
  5432  func (b *builtinAddStringAndDurationSig) evalString(event chunk.Event) (result string, isNull bool, err error) {
  5433  	var (
  5434  		arg0 string
  5435  		arg1 types.Duration
  5436  	)
  5437  	arg0, isNull, err = b.args[0].EvalString(b.ctx, event)
  5438  	if isNull || err != nil {
  5439  		return "", isNull, err
  5440  	}
  5441  	arg1, isNull, err = b.args[1].EvalDuration(b.ctx, event)
  5442  	if isNull || err != nil {
  5443  		return "", isNull, err
  5444  	}
  5445  	sc := b.ctx.GetStochastikVars().StmtCtx
  5446  	if isDuration(arg0) {
  5447  		result, err = strDurationAddDuration(sc, arg0, arg1)
  5448  		if err != nil {
  5449  			if terror.ErrorEqual(err, types.ErrTruncatedWrongVal) {
  5450  				sc.AppendWarning(err)
  5451  				return "", true, nil
  5452  			}
  5453  			return "", true, err
  5454  		}
  5455  		return result, false, nil
  5456  	}
  5457  	result, err = strDatetimeAddDuration(sc, arg0, arg1)
  5458  	return result, err != nil, err
  5459  }
  5460  
  5461  type builtinAddStringAndStringSig struct {
  5462  	baseBuiltinFunc
  5463  }
  5464  
  5465  func (b *builtinAddStringAndStringSig) Clone() builtinFunc {
  5466  	newSig := &builtinAddStringAndStringSig{}
  5467  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5468  	return newSig
  5469  }
  5470  
  5471  // evalString evals a builtinAddStringAndStringSig.
  5472  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_addtime
  5473  func (b *builtinAddStringAndStringSig) evalString(event chunk.Event) (result string, isNull bool, err error) {
  5474  	var (
  5475  		arg0, arg1Str string
  5476  		arg1          types.Duration
  5477  	)
  5478  	arg0, isNull, err = b.args[0].EvalString(b.ctx, event)
  5479  	if isNull || err != nil {
  5480  		return "", isNull, err
  5481  	}
  5482  	arg1Type := b.args[1].GetType()
  5483  	if allegrosql.HasBinaryFlag(arg1Type.Flag) {
  5484  		return "", true, nil
  5485  	}
  5486  	arg1Str, isNull, err = b.args[1].EvalString(b.ctx, event)
  5487  	if isNull || err != nil {
  5488  		return "", isNull, err
  5489  	}
  5490  	sc := b.ctx.GetStochastikVars().StmtCtx
  5491  	arg1, err = types.ParseDuration(sc, arg1Str, getFsp4TimeAddSub(arg1Str))
  5492  	if err != nil {
  5493  		if terror.ErrorEqual(err, types.ErrTruncatedWrongVal) {
  5494  			sc.AppendWarning(err)
  5495  			return "", true, nil
  5496  		}
  5497  		return "", true, err
  5498  	}
  5499  	if isDuration(arg0) {
  5500  		result, err = strDurationAddDuration(sc, arg0, arg1)
  5501  		if err != nil {
  5502  			if terror.ErrorEqual(err, types.ErrTruncatedWrongVal) {
  5503  				sc.AppendWarning(err)
  5504  				return "", true, nil
  5505  			}
  5506  			return "", true, err
  5507  		}
  5508  		return result, false, nil
  5509  	}
  5510  	result, err = strDatetimeAddDuration(sc, arg0, arg1)
  5511  	return result, err != nil, err
  5512  }
  5513  
  5514  type builtinAddDateAndDurationSig struct {
  5515  	baseBuiltinFunc
  5516  }
  5517  
  5518  func (b *builtinAddDateAndDurationSig) Clone() builtinFunc {
  5519  	newSig := &builtinAddDateAndDurationSig{}
  5520  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5521  	return newSig
  5522  }
  5523  
  5524  // evalString evals a builtinAddDurationAndDurationSig.
  5525  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_addtime
  5526  func (b *builtinAddDateAndDurationSig) evalString(event chunk.Event) (string, bool, error) {
  5527  	arg0, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  5528  	if isNull || err != nil {
  5529  		return "", isNull, err
  5530  	}
  5531  	arg1, isNull, err := b.args[1].EvalDuration(b.ctx, event)
  5532  	if isNull || err != nil {
  5533  		return "", isNull, err
  5534  	}
  5535  	result, err := arg0.Add(arg1)
  5536  	return result.String(), err != nil, err
  5537  }
  5538  
  5539  type builtinAddDateAndStringSig struct {
  5540  	baseBuiltinFunc
  5541  }
  5542  
  5543  func (b *builtinAddDateAndStringSig) Clone() builtinFunc {
  5544  	newSig := &builtinAddDateAndStringSig{}
  5545  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5546  	return newSig
  5547  }
  5548  
  5549  // evalString evals a builtinAddDateAndStringSig.
  5550  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_addtime
  5551  func (b *builtinAddDateAndStringSig) evalString(event chunk.Event) (string, bool, error) {
  5552  	arg0, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  5553  	if isNull || err != nil {
  5554  		return "", isNull, err
  5555  	}
  5556  	s, isNull, err := b.args[1].EvalString(b.ctx, event)
  5557  	if isNull || err != nil {
  5558  		return "", isNull, err
  5559  	}
  5560  	if !isDuration(s) {
  5561  		return "", true, nil
  5562  	}
  5563  	sc := b.ctx.GetStochastikVars().StmtCtx
  5564  	arg1, err := types.ParseDuration(sc, s, getFsp4TimeAddSub(s))
  5565  	if err != nil {
  5566  		if terror.ErrorEqual(err, types.ErrTruncatedWrongVal) {
  5567  			sc.AppendWarning(err)
  5568  			return "", true, nil
  5569  		}
  5570  		return "", true, err
  5571  	}
  5572  	result, err := arg0.Add(arg1)
  5573  	return result.String(), err != nil, err
  5574  }
  5575  
  5576  type convertTzFunctionClass struct {
  5577  	baseFunctionClass
  5578  }
  5579  
  5580  func (c *convertTzFunctionClass) getDecimal(ctx stochastikctx.Context, arg Expression) int {
  5581  	decimal := int(types.MaxFsp)
  5582  	if dt, isConstant := arg.(*Constant); isConstant {
  5583  		switch arg.GetType().EvalType() {
  5584  		case types.ETInt:
  5585  			decimal = 0
  5586  		case types.ETReal, types.ETDecimal:
  5587  			decimal = arg.GetType().Decimal
  5588  		case types.ETString:
  5589  			str, isNull, err := dt.EvalString(ctx, chunk.Event{})
  5590  			if err == nil && !isNull {
  5591  				decimal = types.DateFSP(str)
  5592  			}
  5593  		}
  5594  	}
  5595  	if decimal > int(types.MaxFsp) {
  5596  		return int(types.MaxFsp)
  5597  	}
  5598  	if decimal < int(types.MinFsp) {
  5599  		return int(types.MinFsp)
  5600  	}
  5601  	return decimal
  5602  }
  5603  
  5604  func (c *convertTzFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  5605  	if err := c.verifyArgs(args); err != nil {
  5606  		return nil, err
  5607  	}
  5608  	// tzRegex holds the regex to check whether a string is a time zone.
  5609  	tzRegex, err := regexp.Compile(`(^(\+|-)(0?[0-9]|1[0-2]):[0-5]?\d$)|(^\+13:00$)`)
  5610  	if err != nil {
  5611  		return nil, err
  5612  	}
  5613  
  5614  	decimal := c.getDecimal(ctx, args[0])
  5615  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDatetime, types.ETDatetime, types.ETString, types.ETString)
  5616  	if err != nil {
  5617  		return nil, err
  5618  	}
  5619  	bf.tp.Decimal = decimal
  5620  	sig := &builtinConvertTzSig{
  5621  		baseBuiltinFunc: bf,
  5622  		timezoneRegex:   tzRegex,
  5623  	}
  5624  	sig.setPbCode(fidelpb.ScalarFuncSig_ConvertTz)
  5625  	return sig, nil
  5626  }
  5627  
  5628  type builtinConvertTzSig struct {
  5629  	baseBuiltinFunc
  5630  	timezoneRegex *regexp.Regexp
  5631  }
  5632  
  5633  func (b *builtinConvertTzSig) Clone() builtinFunc {
  5634  	newSig := &builtinConvertTzSig{timezoneRegex: b.timezoneRegex}
  5635  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5636  	return newSig
  5637  }
  5638  
  5639  // evalTime evals CONVERT_TZ(dt,from_tz,to_tz).
  5640  // `CONVERT_TZ` function returns NULL if the arguments are invalid.
  5641  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_convert-tz
  5642  func (b *builtinConvertTzSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  5643  	dt, isNull, err := b.args[0].EvalTime(b.ctx, event)
  5644  	if isNull || err != nil {
  5645  		return types.ZeroTime, true, nil
  5646  	}
  5647  
  5648  	fromTzStr, isNull, err := b.args[1].EvalString(b.ctx, event)
  5649  	if isNull || err != nil {
  5650  		return types.ZeroTime, true, nil
  5651  	}
  5652  
  5653  	toTzStr, isNull, err := b.args[2].EvalString(b.ctx, event)
  5654  	if isNull || err != nil {
  5655  		return types.ZeroTime, true, nil
  5656  	}
  5657  
  5658  	return b.convertTz(dt, fromTzStr, toTzStr)
  5659  }
  5660  
  5661  func (b *builtinConvertTzSig) convertTz(dt types.Time, fromTzStr, toTzStr string) (types.Time, bool, error) {
  5662  	if fromTzStr == "" || toTzStr == "" {
  5663  		return types.ZeroTime, true, nil
  5664  	}
  5665  	fromTzMatched := b.timezoneRegex.MatchString(fromTzStr)
  5666  	toTzMatched := b.timezoneRegex.MatchString(toTzStr)
  5667  
  5668  	if !fromTzMatched && !toTzMatched {
  5669  		fromTz, err := time.LoadLocation(fromTzStr)
  5670  		if err != nil {
  5671  			return types.ZeroTime, true, nil
  5672  		}
  5673  
  5674  		toTz, err := time.LoadLocation(toTzStr)
  5675  		if err != nil {
  5676  			return types.ZeroTime, true, nil
  5677  		}
  5678  
  5679  		t, err := dt.GoTime(fromTz)
  5680  		if err != nil {
  5681  			return types.ZeroTime, true, nil
  5682  		}
  5683  
  5684  		return types.NewTime(types.FromGoTime(t.In(toTz)), allegrosql.TypeDatetime, int8(b.tp.Decimal)), false, nil
  5685  	}
  5686  	if fromTzMatched && toTzMatched {
  5687  		t, err := dt.GoTime(time.Local)
  5688  		if err != nil {
  5689  			return types.ZeroTime, true, nil
  5690  		}
  5691  
  5692  		return types.NewTime(types.FromGoTime(t.Add(timeZone2Duration(toTzStr)-timeZone2Duration(fromTzStr))), allegrosql.TypeDatetime, int8(b.tp.Decimal)), false, nil
  5693  	}
  5694  	return types.ZeroTime, true, nil
  5695  }
  5696  
  5697  type makeDateFunctionClass struct {
  5698  	baseFunctionClass
  5699  }
  5700  
  5701  func (c *makeDateFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  5702  	if err := c.verifyArgs(args); err != nil {
  5703  		return nil, err
  5704  	}
  5705  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDatetime, types.ETInt, types.ETInt)
  5706  	if err != nil {
  5707  		return nil, err
  5708  	}
  5709  	tp := bf.tp
  5710  	tp.Tp, tp.Flen, tp.Decimal = allegrosql.TypeDate, allegrosql.MaxDateWidth, 0
  5711  	sig := &builtinMakeDateSig{bf}
  5712  	sig.setPbCode(fidelpb.ScalarFuncSig_MakeDate)
  5713  	return sig, nil
  5714  }
  5715  
  5716  type builtinMakeDateSig struct {
  5717  	baseBuiltinFunc
  5718  }
  5719  
  5720  func (b *builtinMakeDateSig) Clone() builtinFunc {
  5721  	newSig := &builtinMakeDateSig{}
  5722  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5723  	return newSig
  5724  }
  5725  
  5726  // evalTime evaluates a builtinMakeDateSig.
  5727  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_makedate
  5728  func (b *builtinMakeDateSig) evalTime(event chunk.Event) (d types.Time, isNull bool, err error) {
  5729  	args := b.getArgs()
  5730  	var year, dayOfYear int64
  5731  	year, isNull, err = args[0].EvalInt(b.ctx, event)
  5732  	if isNull || err != nil {
  5733  		return d, true, err
  5734  	}
  5735  	dayOfYear, isNull, err = args[1].EvalInt(b.ctx, event)
  5736  	if isNull || err != nil {
  5737  		return d, true, err
  5738  	}
  5739  	if dayOfYear <= 0 || year < 0 || year > 9999 {
  5740  		return d, true, nil
  5741  	}
  5742  	if year < 70 {
  5743  		year += 2000
  5744  	} else if year < 100 {
  5745  		year += 1900
  5746  	}
  5747  	startTime := types.NewTime(types.FromDate(int(year), 1, 1, 0, 0, 0, 0), allegrosql.TypeDate, 0)
  5748  	retTimestamp := types.TimestamFIDeliff("DAY", types.ZeroDate, startTime)
  5749  	if retTimestamp == 0 {
  5750  		return d, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, startTime.String()))
  5751  	}
  5752  	ret := types.TimeFromDays(retTimestamp + dayOfYear - 1)
  5753  	if ret.IsZero() || ret.Year() > 9999 {
  5754  		return d, true, nil
  5755  	}
  5756  	return ret, false, nil
  5757  }
  5758  
  5759  type makeTimeFunctionClass struct {
  5760  	baseFunctionClass
  5761  }
  5762  
  5763  func (c *makeTimeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  5764  	if err := c.verifyArgs(args); err != nil {
  5765  		return nil, err
  5766  	}
  5767  	tp, flen, decimal := args[2].GetType().EvalType(), 10, 0
  5768  	switch tp {
  5769  	case types.ETInt:
  5770  	case types.ETReal, types.ETDecimal:
  5771  		decimal = args[2].GetType().Decimal
  5772  		if decimal > 6 || decimal == types.UnspecifiedLength {
  5773  			decimal = 6
  5774  		}
  5775  		if decimal > 0 {
  5776  			flen += 1 + decimal
  5777  		}
  5778  	default:
  5779  		flen, decimal = 17, 6
  5780  	}
  5781  	// MyALLEGROSQL will cast the first and second arguments to INT, and the third argument to DECIMAL.
  5782  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDuration, types.ETInt, types.ETInt, types.ETReal)
  5783  	if err != nil {
  5784  		return nil, err
  5785  	}
  5786  	bf.tp.Flen, bf.tp.Decimal = flen, decimal
  5787  	sig := &builtinMakeTimeSig{bf}
  5788  	sig.setPbCode(fidelpb.ScalarFuncSig_MakeTime)
  5789  	return sig, nil
  5790  }
  5791  
  5792  type builtinMakeTimeSig struct {
  5793  	baseBuiltinFunc
  5794  }
  5795  
  5796  func (b *builtinMakeTimeSig) Clone() builtinFunc {
  5797  	newSig := &builtinMakeTimeSig{}
  5798  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5799  	return newSig
  5800  }
  5801  
  5802  func (b *builtinMakeTimeSig) makeTime(hour int64, minute int64, second float64, hourUnsignedFlag bool) (types.Duration, error) {
  5803  	var overflow bool
  5804  	// MyALLEGROSQL TIME datatype: https://dev.allegrosql.com/doc/refman/5.7/en/time.html
  5805  	// ranges from '-838:59:59.000000' to '838:59:59.000000'
  5806  	if hour < 0 && hourUnsignedFlag {
  5807  		hour = 838
  5808  		overflow = true
  5809  	}
  5810  	if hour < -838 {
  5811  		hour = -838
  5812  		overflow = true
  5813  	} else if hour > 838 {
  5814  		hour = 838
  5815  		overflow = true
  5816  	}
  5817  	if hour == -838 || hour == 838 {
  5818  		if second > 59 {
  5819  			second = 59
  5820  		}
  5821  	}
  5822  	if overflow {
  5823  		minute = 59
  5824  		second = 59
  5825  	}
  5826  	fsp := b.tp.Decimal
  5827  	return types.ParseDuration(b.ctx.GetStochastikVars().StmtCtx, fmt.Sprintf("%02d:%02d:%v", hour, minute, second), int8(fsp))
  5828  }
  5829  
  5830  // evalDuration evals a builtinMakeTimeIntSig.
  5831  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_maketime
  5832  func (b *builtinMakeTimeSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  5833  	dur := types.ZeroDuration
  5834  	dur.Fsp = types.MaxFsp
  5835  	hour, isNull, err := b.args[0].EvalInt(b.ctx, event)
  5836  	if isNull || err != nil {
  5837  		return dur, isNull, err
  5838  	}
  5839  	minute, isNull, err := b.args[1].EvalInt(b.ctx, event)
  5840  	if isNull || err != nil {
  5841  		return dur, isNull, err
  5842  	}
  5843  	if minute < 0 || minute >= 60 {
  5844  		return dur, true, nil
  5845  	}
  5846  	second, isNull, err := b.args[2].EvalReal(b.ctx, event)
  5847  	if isNull || err != nil {
  5848  		return dur, isNull, err
  5849  	}
  5850  	if second < 0 || second >= 60 {
  5851  		return dur, true, nil
  5852  	}
  5853  	dur, err = b.makeTime(hour, minute, second, allegrosql.HasUnsignedFlag(b.args[0].GetType().Flag))
  5854  	if err != nil {
  5855  		return dur, true, err
  5856  	}
  5857  	return dur, false, nil
  5858  }
  5859  
  5860  type periodAddFunctionClass struct {
  5861  	baseFunctionClass
  5862  }
  5863  
  5864  func (c *periodAddFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  5865  	if err := c.verifyArgs(args); err != nil {
  5866  		return nil, err
  5867  	}
  5868  
  5869  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETInt, types.ETInt)
  5870  	if err != nil {
  5871  		return nil, err
  5872  	}
  5873  	bf.tp.Flen = 6
  5874  	sig := &builtinPeriodAddSig{bf}
  5875  	return sig, nil
  5876  }
  5877  
  5878  // validPeriod checks if this period is valid, it comes from MyALLEGROSQL 8.0+.
  5879  func validPeriod(p int64) bool {
  5880  	return !(p < 0 || p%100 == 0 || p%100 > 12)
  5881  }
  5882  
  5883  // period2Month converts a period to months, in which period is represented in the format of YYMM or YYYYMM.
  5884  // Note that the period argument is not a date value.
  5885  func period2Month(period uint64) uint64 {
  5886  	if period == 0 {
  5887  		return 0
  5888  	}
  5889  
  5890  	year, month := period/100, period%100
  5891  	if year < 70 {
  5892  		year += 2000
  5893  	} else if year < 100 {
  5894  		year += 1900
  5895  	}
  5896  
  5897  	return year*12 + month - 1
  5898  }
  5899  
  5900  // month2Period converts a month to a period.
  5901  func month2Period(month uint64) uint64 {
  5902  	if month == 0 {
  5903  		return 0
  5904  	}
  5905  
  5906  	year := month / 12
  5907  	if year < 70 {
  5908  		year += 2000
  5909  	} else if year < 100 {
  5910  		year += 1900
  5911  	}
  5912  
  5913  	return year*100 + month%12 + 1
  5914  }
  5915  
  5916  type builtinPeriodAddSig struct {
  5917  	baseBuiltinFunc
  5918  }
  5919  
  5920  func (b *builtinPeriodAddSig) Clone() builtinFunc {
  5921  	newSig := &builtinPeriodAddSig{}
  5922  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5923  	return newSig
  5924  }
  5925  
  5926  // evalInt evals PERIOD_ADD(P,N).
  5927  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_period-add
  5928  func (b *builtinPeriodAddSig) evalInt(event chunk.Event) (int64, bool, error) {
  5929  	p, isNull, err := b.args[0].EvalInt(b.ctx, event)
  5930  	if isNull || err != nil {
  5931  		return 0, true, err
  5932  	}
  5933  
  5934  	n, isNull, err := b.args[1].EvalInt(b.ctx, event)
  5935  	if isNull || err != nil {
  5936  		return 0, true, err
  5937  	}
  5938  
  5939  	// in MyALLEGROSQL, if p is invalid but n is NULL, the result is NULL, so we have to check if n is NULL first.
  5940  	if !validPeriod(p) {
  5941  		return 0, false, errIncorrectArgs.GenWithStackByArgs("period_add")
  5942  	}
  5943  
  5944  	sumMonth := int64(period2Month(uint64(p))) + n
  5945  	return int64(month2Period(uint64(sumMonth))), false, nil
  5946  }
  5947  
  5948  type periodDiffFunctionClass struct {
  5949  	baseFunctionClass
  5950  }
  5951  
  5952  func (c *periodDiffFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  5953  	if err := c.verifyArgs(args); err != nil {
  5954  		return nil, err
  5955  	}
  5956  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETInt, types.ETInt)
  5957  	if err != nil {
  5958  		return nil, err
  5959  	}
  5960  	bf.tp.Flen = 6
  5961  	sig := &builtinPeriodDiffSig{bf}
  5962  	return sig, nil
  5963  }
  5964  
  5965  type builtinPeriodDiffSig struct {
  5966  	baseBuiltinFunc
  5967  }
  5968  
  5969  func (b *builtinPeriodDiffSig) Clone() builtinFunc {
  5970  	newSig := &builtinPeriodDiffSig{}
  5971  	newSig.cloneFrom(&b.baseBuiltinFunc)
  5972  	return newSig
  5973  }
  5974  
  5975  // evalInt evals PERIOD_DIFF(P1,P2).
  5976  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_period-diff
  5977  func (b *builtinPeriodDiffSig) evalInt(event chunk.Event) (int64, bool, error) {
  5978  	p1, isNull, err := b.args[0].EvalInt(b.ctx, event)
  5979  	if isNull || err != nil {
  5980  		return 0, isNull, err
  5981  	}
  5982  
  5983  	p2, isNull, err := b.args[1].EvalInt(b.ctx, event)
  5984  	if isNull || err != nil {
  5985  		return 0, isNull, err
  5986  	}
  5987  
  5988  	if !validPeriod(p1) {
  5989  		return 0, false, errIncorrectArgs.GenWithStackByArgs("period_diff")
  5990  	}
  5991  
  5992  	if !validPeriod(p2) {
  5993  		return 0, false, errIncorrectArgs.GenWithStackByArgs("period_diff")
  5994  	}
  5995  
  5996  	return int64(period2Month(uint64(p1)) - period2Month(uint64(p2))), false, nil
  5997  }
  5998  
  5999  type quarterFunctionClass struct {
  6000  	baseFunctionClass
  6001  }
  6002  
  6003  func (c *quarterFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  6004  	if err := c.verifyArgs(args); err != nil {
  6005  		return nil, err
  6006  	}
  6007  
  6008  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETDatetime)
  6009  	if err != nil {
  6010  		return nil, err
  6011  	}
  6012  	bf.tp.Flen = 1
  6013  
  6014  	sig := &builtinQuarterSig{bf}
  6015  	sig.setPbCode(fidelpb.ScalarFuncSig_Quarter)
  6016  	return sig, nil
  6017  }
  6018  
  6019  type builtinQuarterSig struct {
  6020  	baseBuiltinFunc
  6021  }
  6022  
  6023  func (b *builtinQuarterSig) Clone() builtinFunc {
  6024  	newSig := &builtinQuarterSig{}
  6025  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6026  	return newSig
  6027  }
  6028  
  6029  // evalInt evals QUARTER(date).
  6030  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_quarter
  6031  func (b *builtinQuarterSig) evalInt(event chunk.Event) (int64, bool, error) {
  6032  	date, isNull, err := b.args[0].EvalTime(b.ctx, event)
  6033  	if isNull || err != nil {
  6034  		return 0, true, handleInvalidTimeError(b.ctx, err)
  6035  	}
  6036  
  6037  	if date.IsZero() {
  6038  		// MyALLEGROSQL compatibility, #11203
  6039  		// 0 | 0.0 should be converted to 0 value (not null)
  6040  		n, err := date.ToNumber().ToInt()
  6041  		isOriginalIntOrDecimalZero := err == nil && n == 0
  6042  		// Args like "0000-00-00", "0000-00-00 00:00:00" set Fsp to 6
  6043  		isOriginalStringZero := date.Fsp() > 0
  6044  		if isOriginalIntOrDecimalZero && !isOriginalStringZero {
  6045  			return 0, false, nil
  6046  		}
  6047  		return 0, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, date.String()))
  6048  	}
  6049  
  6050  	return int64((date.Month() + 2) / 3), false, nil
  6051  }
  6052  
  6053  type secToTimeFunctionClass struct {
  6054  	baseFunctionClass
  6055  }
  6056  
  6057  func (c *secToTimeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  6058  	if err := c.verifyArgs(args); err != nil {
  6059  		return nil, err
  6060  	}
  6061  	var retFlen, retFsp int
  6062  	argType := args[0].GetType()
  6063  	argEvalTp := argType.EvalType()
  6064  	if argEvalTp == types.ETString {
  6065  		retFsp = types.UnspecifiedLength
  6066  	} else {
  6067  		retFsp = argType.Decimal
  6068  	}
  6069  	if retFsp > int(types.MaxFsp) || retFsp == int(types.UnspecifiedFsp) {
  6070  		retFsp = int(types.MaxFsp)
  6071  	} else if retFsp < int(types.MinFsp) {
  6072  		retFsp = int(types.MinFsp)
  6073  	}
  6074  	retFlen = 10
  6075  	if retFsp > 0 {
  6076  		retFlen += 1 + retFsp
  6077  	}
  6078  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDuration, types.ETReal)
  6079  	if err != nil {
  6080  		return nil, err
  6081  	}
  6082  	bf.tp.Flen, bf.tp.Decimal = retFlen, retFsp
  6083  	sig := &builtinSecToTimeSig{bf}
  6084  	sig.setPbCode(fidelpb.ScalarFuncSig_SecToTime)
  6085  	return sig, nil
  6086  }
  6087  
  6088  type builtinSecToTimeSig struct {
  6089  	baseBuiltinFunc
  6090  }
  6091  
  6092  func (b *builtinSecToTimeSig) Clone() builtinFunc {
  6093  	newSig := &builtinSecToTimeSig{}
  6094  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6095  	return newSig
  6096  }
  6097  
  6098  // evalDuration evals SEC_TO_TIME(seconds).
  6099  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_sec-to-time
  6100  func (b *builtinSecToTimeSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  6101  	secondsFloat, isNull, err := b.args[0].EvalReal(b.ctx, event)
  6102  	if isNull || err != nil {
  6103  		return types.Duration{}, isNull, err
  6104  	}
  6105  	var (
  6106  		hour          int64
  6107  		minute        int64
  6108  		second        int64
  6109  		demical       float64
  6110  		secondDemical float64
  6111  		negative      string
  6112  	)
  6113  
  6114  	if secondsFloat < 0 {
  6115  		negative = "-"
  6116  		secondsFloat = math.Abs(secondsFloat)
  6117  	}
  6118  	seconds := int64(secondsFloat)
  6119  	demical = secondsFloat - float64(seconds)
  6120  
  6121  	hour = seconds / 3600
  6122  	if hour > 838 {
  6123  		hour = 838
  6124  		minute = 59
  6125  		second = 59
  6126  	} else {
  6127  		minute = seconds % 3600 / 60
  6128  		second = seconds % 60
  6129  	}
  6130  	secondDemical = float64(second) + demical
  6131  
  6132  	var dur types.Duration
  6133  	dur, err = types.ParseDuration(b.ctx.GetStochastikVars().StmtCtx, fmt.Sprintf("%s%02d:%02d:%s", negative, hour, minute, strconv.FormatFloat(secondDemical, 'f', -1, 64)), int8(b.tp.Decimal))
  6134  	if err != nil {
  6135  		return types.Duration{}, err != nil, err
  6136  	}
  6137  	return dur, false, nil
  6138  }
  6139  
  6140  type subTimeFunctionClass struct {
  6141  	baseFunctionClass
  6142  }
  6143  
  6144  func (c *subTimeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) {
  6145  	if err = c.verifyArgs(args); err != nil {
  6146  		return nil, err
  6147  	}
  6148  	tp1, tp2, bf, err := getBf4TimeAddSub(ctx, c.funcName, args)
  6149  	if err != nil {
  6150  		return nil, err
  6151  	}
  6152  	switch tp1.Tp {
  6153  	case allegrosql.TypeDatetime, allegrosql.TypeTimestamp:
  6154  		switch tp2.Tp {
  6155  		case allegrosql.TypeDuration:
  6156  			sig = &builtinSubDatetimeAndDurationSig{bf}
  6157  			sig.setPbCode(fidelpb.ScalarFuncSig_SubDatetimeAndDuration)
  6158  		case allegrosql.TypeDatetime, allegrosql.TypeTimestamp:
  6159  			sig = &builtinSubTimeDateTimeNullSig{bf}
  6160  			sig.setPbCode(fidelpb.ScalarFuncSig_SubTimeDateTimeNull)
  6161  		default:
  6162  			sig = &builtinSubDatetimeAndStringSig{bf}
  6163  			sig.setPbCode(fidelpb.ScalarFuncSig_SubDatetimeAndString)
  6164  		}
  6165  	case allegrosql.TypeDate:
  6166  		bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo()
  6167  		switch tp2.Tp {
  6168  		case allegrosql.TypeDuration:
  6169  			sig = &builtinSubDateAndDurationSig{bf}
  6170  			sig.setPbCode(fidelpb.ScalarFuncSig_SubDateAndDuration)
  6171  		case allegrosql.TypeDatetime, allegrosql.TypeTimestamp:
  6172  			sig = &builtinSubTimeStringNullSig{bf}
  6173  			sig.setPbCode(fidelpb.ScalarFuncSig_SubTimeStringNull)
  6174  		default:
  6175  			sig = &builtinSubDateAndStringSig{bf}
  6176  			sig.setPbCode(fidelpb.ScalarFuncSig_SubDateAndString)
  6177  		}
  6178  	case allegrosql.TypeDuration:
  6179  		switch tp2.Tp {
  6180  		case allegrosql.TypeDuration:
  6181  			sig = &builtinSubDurationAndDurationSig{bf}
  6182  			sig.setPbCode(fidelpb.ScalarFuncSig_SubDurationAndDuration)
  6183  		case allegrosql.TypeDatetime, allegrosql.TypeTimestamp:
  6184  			sig = &builtinSubTimeDurationNullSig{bf}
  6185  			sig.setPbCode(fidelpb.ScalarFuncSig_SubTimeDurationNull)
  6186  		default:
  6187  			sig = &builtinSubDurationAndStringSig{bf}
  6188  			sig.setPbCode(fidelpb.ScalarFuncSig_SubDurationAndString)
  6189  		}
  6190  	default:
  6191  		switch tp2.Tp {
  6192  		case allegrosql.TypeDuration:
  6193  			sig = &builtinSubStringAndDurationSig{bf}
  6194  			sig.setPbCode(fidelpb.ScalarFuncSig_SubStringAndDuration)
  6195  		case allegrosql.TypeDatetime, allegrosql.TypeTimestamp:
  6196  			sig = &builtinSubTimeStringNullSig{bf}
  6197  			sig.setPbCode(fidelpb.ScalarFuncSig_SubTimeStringNull)
  6198  		default:
  6199  			sig = &builtinSubStringAndStringSig{bf}
  6200  			sig.setPbCode(fidelpb.ScalarFuncSig_SubStringAndString)
  6201  		}
  6202  	}
  6203  	return sig, nil
  6204  }
  6205  
  6206  type builtinSubDatetimeAndDurationSig struct {
  6207  	baseBuiltinFunc
  6208  }
  6209  
  6210  func (b *builtinSubDatetimeAndDurationSig) Clone() builtinFunc {
  6211  	newSig := &builtinSubDatetimeAndDurationSig{}
  6212  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6213  	return newSig
  6214  }
  6215  
  6216  // evalTime evals a builtinSubDatetimeAndDurationSig.
  6217  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subtime
  6218  func (b *builtinSubDatetimeAndDurationSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  6219  	arg0, isNull, err := b.args[0].EvalTime(b.ctx, event)
  6220  	if isNull || err != nil {
  6221  		return types.ZeroDatetime, isNull, err
  6222  	}
  6223  	arg1, isNull, err := b.args[1].EvalDuration(b.ctx, event)
  6224  	if isNull || err != nil {
  6225  		return types.ZeroDatetime, isNull, err
  6226  	}
  6227  	sc := b.ctx.GetStochastikVars().StmtCtx
  6228  	arg1time, err := arg1.ConvertToTime(sc, allegrosql.TypeDatetime)
  6229  	if err != nil {
  6230  		return arg1time, true, err
  6231  	}
  6232  	tmFIDeluration := arg0.Sub(sc, &arg1time)
  6233  	result, err := tmFIDeluration.ConvertToTime(sc, arg0.Type())
  6234  	return result, err != nil, err
  6235  }
  6236  
  6237  type builtinSubDatetimeAndStringSig struct {
  6238  	baseBuiltinFunc
  6239  }
  6240  
  6241  func (b *builtinSubDatetimeAndStringSig) Clone() builtinFunc {
  6242  	newSig := &builtinSubDatetimeAndStringSig{}
  6243  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6244  	return newSig
  6245  }
  6246  
  6247  // evalTime evals a builtinSubDatetimeAndStringSig.
  6248  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subtime
  6249  func (b *builtinSubDatetimeAndStringSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  6250  	arg0, isNull, err := b.args[0].EvalTime(b.ctx, event)
  6251  	if isNull || err != nil {
  6252  		return types.ZeroDatetime, isNull, err
  6253  	}
  6254  	s, isNull, err := b.args[1].EvalString(b.ctx, event)
  6255  	if isNull || err != nil {
  6256  		return types.ZeroDatetime, isNull, err
  6257  	}
  6258  	if err != nil {
  6259  		return types.ZeroDatetime, true, err
  6260  	}
  6261  	if !isDuration(s) {
  6262  		return types.ZeroDatetime, true, nil
  6263  	}
  6264  	sc := b.ctx.GetStochastikVars().StmtCtx
  6265  	arg1, err := types.ParseDuration(sc, s, types.GetFsp(s))
  6266  	if err != nil {
  6267  		if terror.ErrorEqual(err, types.ErrTruncatedWrongVal) {
  6268  			sc.AppendWarning(err)
  6269  			return types.ZeroDatetime, true, nil
  6270  		}
  6271  		return types.ZeroDatetime, true, err
  6272  	}
  6273  	arg1time, err := arg1.ConvertToTime(sc, allegrosql.TypeDatetime)
  6274  	if err != nil {
  6275  		return types.ZeroDatetime, true, err
  6276  	}
  6277  	tmFIDeluration := arg0.Sub(sc, &arg1time)
  6278  	result, err := tmFIDeluration.ConvertToTime(sc, allegrosql.TypeDatetime)
  6279  	return result, err != nil, err
  6280  }
  6281  
  6282  type builtinSubTimeDateTimeNullSig struct {
  6283  	baseBuiltinFunc
  6284  }
  6285  
  6286  func (b *builtinSubTimeDateTimeNullSig) Clone() builtinFunc {
  6287  	newSig := &builtinSubTimeDateTimeNullSig{}
  6288  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6289  	return newSig
  6290  }
  6291  
  6292  // evalTime evals a builtinSubTimeDateTimeNullSig.
  6293  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subtime
  6294  func (b *builtinSubTimeDateTimeNullSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  6295  	return types.ZeroDatetime, true, nil
  6296  }
  6297  
  6298  type builtinSubStringAndDurationSig struct {
  6299  	baseBuiltinFunc
  6300  }
  6301  
  6302  func (b *builtinSubStringAndDurationSig) Clone() builtinFunc {
  6303  	newSig := &builtinSubStringAndDurationSig{}
  6304  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6305  	return newSig
  6306  }
  6307  
  6308  // evalString evals a builtinSubStringAndDurationSig.
  6309  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subtime
  6310  func (b *builtinSubStringAndDurationSig) evalString(event chunk.Event) (result string, isNull bool, err error) {
  6311  	var (
  6312  		arg0 string
  6313  		arg1 types.Duration
  6314  	)
  6315  	arg0, isNull, err = b.args[0].EvalString(b.ctx, event)
  6316  	if isNull || err != nil {
  6317  		return "", isNull, err
  6318  	}
  6319  	arg1, isNull, err = b.args[1].EvalDuration(b.ctx, event)
  6320  	if isNull || err != nil {
  6321  		return "", isNull, err
  6322  	}
  6323  	sc := b.ctx.GetStochastikVars().StmtCtx
  6324  	if isDuration(arg0) {
  6325  		result, err = strDurationSubDuration(sc, arg0, arg1)
  6326  		if err != nil {
  6327  			if terror.ErrorEqual(err, types.ErrTruncatedWrongVal) {
  6328  				sc.AppendWarning(err)
  6329  				return "", true, nil
  6330  			}
  6331  			return "", true, err
  6332  		}
  6333  		return result, false, nil
  6334  	}
  6335  	result, err = strDatetimeSubDuration(sc, arg0, arg1)
  6336  	return result, err != nil, err
  6337  }
  6338  
  6339  type builtinSubStringAndStringSig struct {
  6340  	baseBuiltinFunc
  6341  }
  6342  
  6343  func (b *builtinSubStringAndStringSig) Clone() builtinFunc {
  6344  	newSig := &builtinSubStringAndStringSig{}
  6345  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6346  	return newSig
  6347  }
  6348  
  6349  // evalString evals a builtinSubStringAndStringSig.
  6350  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subtime
  6351  func (b *builtinSubStringAndStringSig) evalString(event chunk.Event) (result string, isNull bool, err error) {
  6352  	var (
  6353  		s, arg0 string
  6354  		arg1    types.Duration
  6355  	)
  6356  	arg0, isNull, err = b.args[0].EvalString(b.ctx, event)
  6357  	if isNull || err != nil {
  6358  		return "", isNull, err
  6359  	}
  6360  	arg1Type := b.args[1].GetType()
  6361  	if allegrosql.HasBinaryFlag(arg1Type.Flag) {
  6362  		return "", true, nil
  6363  	}
  6364  	s, isNull, err = b.args[1].EvalString(b.ctx, event)
  6365  	if isNull || err != nil {
  6366  		return "", isNull, err
  6367  	}
  6368  	sc := b.ctx.GetStochastikVars().StmtCtx
  6369  	arg1, err = types.ParseDuration(sc, s, getFsp4TimeAddSub(s))
  6370  	if err != nil {
  6371  		if terror.ErrorEqual(err, types.ErrTruncatedWrongVal) {
  6372  			sc.AppendWarning(err)
  6373  			return "", true, nil
  6374  		}
  6375  		return "", true, err
  6376  	}
  6377  	if isDuration(arg0) {
  6378  		result, err = strDurationSubDuration(sc, arg0, arg1)
  6379  		if err != nil {
  6380  			if terror.ErrorEqual(err, types.ErrTruncatedWrongVal) {
  6381  				sc.AppendWarning(err)
  6382  				return "", true, nil
  6383  			}
  6384  			return "", true, err
  6385  		}
  6386  		return result, false, nil
  6387  	}
  6388  	result, err = strDatetimeSubDuration(sc, arg0, arg1)
  6389  	return result, err != nil, err
  6390  }
  6391  
  6392  type builtinSubTimeStringNullSig struct {
  6393  	baseBuiltinFunc
  6394  }
  6395  
  6396  func (b *builtinSubTimeStringNullSig) Clone() builtinFunc {
  6397  	newSig := &builtinSubTimeStringNullSig{}
  6398  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6399  	return newSig
  6400  }
  6401  
  6402  // evalString evals a builtinSubTimeStringNullSig.
  6403  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subtime
  6404  func (b *builtinSubTimeStringNullSig) evalString(event chunk.Event) (string, bool, error) {
  6405  	return "", true, nil
  6406  }
  6407  
  6408  type builtinSubDurationAndDurationSig struct {
  6409  	baseBuiltinFunc
  6410  }
  6411  
  6412  func (b *builtinSubDurationAndDurationSig) Clone() builtinFunc {
  6413  	newSig := &builtinSubDurationAndDurationSig{}
  6414  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6415  	return newSig
  6416  }
  6417  
  6418  // evalDuration evals a builtinSubDurationAndDurationSig.
  6419  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subtime
  6420  func (b *builtinSubDurationAndDurationSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  6421  	arg0, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  6422  	if isNull || err != nil {
  6423  		return types.ZeroDuration, isNull, err
  6424  	}
  6425  	arg1, isNull, err := b.args[1].EvalDuration(b.ctx, event)
  6426  	if isNull || err != nil {
  6427  		return types.ZeroDuration, isNull, err
  6428  	}
  6429  	result, err := arg0.Sub(arg1)
  6430  	if err != nil {
  6431  		return types.ZeroDuration, true, err
  6432  	}
  6433  	return result, false, nil
  6434  }
  6435  
  6436  type builtinSubDurationAndStringSig struct {
  6437  	baseBuiltinFunc
  6438  }
  6439  
  6440  func (b *builtinSubDurationAndStringSig) Clone() builtinFunc {
  6441  	newSig := &builtinSubDurationAndStringSig{}
  6442  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6443  	return newSig
  6444  }
  6445  
  6446  // evalDuration evals a builtinSubDurationAndStringSig.
  6447  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subtime
  6448  func (b *builtinSubDurationAndStringSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  6449  	arg0, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  6450  	if isNull || err != nil {
  6451  		return types.ZeroDuration, isNull, err
  6452  	}
  6453  	s, isNull, err := b.args[1].EvalString(b.ctx, event)
  6454  	if isNull || err != nil {
  6455  		return types.ZeroDuration, isNull, err
  6456  	}
  6457  	if !isDuration(s) {
  6458  		return types.ZeroDuration, true, nil
  6459  	}
  6460  	sc := b.ctx.GetStochastikVars().StmtCtx
  6461  	arg1, err := types.ParseDuration(sc, s, types.GetFsp(s))
  6462  	if err != nil {
  6463  		if terror.ErrorEqual(err, types.ErrTruncatedWrongVal) {
  6464  			sc.AppendWarning(err)
  6465  			return types.ZeroDuration, true, nil
  6466  		}
  6467  		return types.ZeroDuration, true, err
  6468  	}
  6469  	result, err := arg0.Sub(arg1)
  6470  	return result, err != nil, err
  6471  }
  6472  
  6473  type builtinSubTimeDurationNullSig struct {
  6474  	baseBuiltinFunc
  6475  }
  6476  
  6477  func (b *builtinSubTimeDurationNullSig) Clone() builtinFunc {
  6478  	newSig := &builtinSubTimeDurationNullSig{}
  6479  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6480  	return newSig
  6481  }
  6482  
  6483  // evalDuration evals a builtinSubTimeDurationNullSig.
  6484  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subtime
  6485  func (b *builtinSubTimeDurationNullSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  6486  	return types.ZeroDuration, true, nil
  6487  }
  6488  
  6489  type builtinSubDateAndDurationSig struct {
  6490  	baseBuiltinFunc
  6491  }
  6492  
  6493  func (b *builtinSubDateAndDurationSig) Clone() builtinFunc {
  6494  	newSig := &builtinSubDateAndDurationSig{}
  6495  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6496  	return newSig
  6497  }
  6498  
  6499  // evalString evals a builtinSubDateAndDurationSig.
  6500  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subtime
  6501  func (b *builtinSubDateAndDurationSig) evalString(event chunk.Event) (string, bool, error) {
  6502  	arg0, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  6503  	if isNull || err != nil {
  6504  		return "", isNull, err
  6505  	}
  6506  	arg1, isNull, err := b.args[1].EvalDuration(b.ctx, event)
  6507  	if isNull || err != nil {
  6508  		return "", isNull, err
  6509  	}
  6510  	result, err := arg0.Sub(arg1)
  6511  	return result.String(), err != nil, err
  6512  }
  6513  
  6514  type builtinSubDateAndStringSig struct {
  6515  	baseBuiltinFunc
  6516  }
  6517  
  6518  func (b *builtinSubDateAndStringSig) Clone() builtinFunc {
  6519  	newSig := &builtinSubDateAndStringSig{}
  6520  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6521  	return newSig
  6522  }
  6523  
  6524  // evalString evals a builtinSubDateAndStringSig.
  6525  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subtime
  6526  func (b *builtinSubDateAndStringSig) evalString(event chunk.Event) (string, bool, error) {
  6527  	arg0, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  6528  	if isNull || err != nil {
  6529  		return "", isNull, err
  6530  	}
  6531  	s, isNull, err := b.args[1].EvalString(b.ctx, event)
  6532  	if isNull || err != nil {
  6533  		return "", isNull, err
  6534  	}
  6535  	if !isDuration(s) {
  6536  		return "", true, nil
  6537  	}
  6538  	sc := b.ctx.GetStochastikVars().StmtCtx
  6539  	arg1, err := types.ParseDuration(sc, s, getFsp4TimeAddSub(s))
  6540  	if err != nil {
  6541  		if terror.ErrorEqual(err, types.ErrTruncatedWrongVal) {
  6542  			sc.AppendWarning(err)
  6543  			return "", true, nil
  6544  		}
  6545  		return "", true, err
  6546  	}
  6547  	result, err := arg0.Sub(arg1)
  6548  	if err != nil {
  6549  		return "", true, err
  6550  	}
  6551  	return result.String(), false, nil
  6552  }
  6553  
  6554  type timeFormatFunctionClass struct {
  6555  	baseFunctionClass
  6556  }
  6557  
  6558  func (c *timeFormatFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  6559  	if err := c.verifyArgs(args); err != nil {
  6560  		return nil, err
  6561  	}
  6562  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETDuration, types.ETString)
  6563  	if err != nil {
  6564  		return nil, err
  6565  	}
  6566  	// worst case: formatMask=%r%r%r...%r, each %r takes 11 characters
  6567  	bf.tp.Flen = (args[1].GetType().Flen + 1) / 2 * 11
  6568  	sig := &builtinTimeFormatSig{bf}
  6569  	sig.setPbCode(fidelpb.ScalarFuncSig_TimeFormat)
  6570  	return sig, nil
  6571  }
  6572  
  6573  type builtinTimeFormatSig struct {
  6574  	baseBuiltinFunc
  6575  }
  6576  
  6577  func (b *builtinTimeFormatSig) Clone() builtinFunc {
  6578  	newSig := &builtinTimeFormatSig{}
  6579  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6580  	return newSig
  6581  }
  6582  
  6583  // evalString evals a builtinTimeFormatSig.
  6584  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_time-format
  6585  func (b *builtinTimeFormatSig) evalString(event chunk.Event) (string, bool, error) {
  6586  	dur, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  6587  	// if err != nil, then dur is ZeroDuration, outputs 00:00:00 in this case which follows the behavior of allegrosql.
  6588  	if err != nil {
  6589  		logutil.BgLogger().Warn("time_format.args[0].EvalDuration failed", zap.Error(err))
  6590  	}
  6591  	if isNull {
  6592  		return "", isNull, err
  6593  	}
  6594  	formatMask, isNull, err := b.args[1].EvalString(b.ctx, event)
  6595  	if err != nil || isNull {
  6596  		return "", isNull, err
  6597  	}
  6598  	res, err := b.formatTime(b.ctx, dur, formatMask)
  6599  	return res, isNull, err
  6600  }
  6601  
  6602  // formatTime see https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_time-format
  6603  func (b *builtinTimeFormatSig) formatTime(ctx stochastikctx.Context, t types.Duration, formatMask string) (res string, err error) {
  6604  	return t.DurationFormat(formatMask)
  6605  }
  6606  
  6607  type timeToSecFunctionClass struct {
  6608  	baseFunctionClass
  6609  }
  6610  
  6611  func (c *timeToSecFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  6612  	if err := c.verifyArgs(args); err != nil {
  6613  		return nil, err
  6614  	}
  6615  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETDuration)
  6616  	if err != nil {
  6617  		return nil, err
  6618  	}
  6619  	bf.tp.Flen = 10
  6620  	sig := &builtinTimeToSecSig{bf}
  6621  	sig.setPbCode(fidelpb.ScalarFuncSig_TimeToSec)
  6622  	return sig, nil
  6623  }
  6624  
  6625  type builtinTimeToSecSig struct {
  6626  	baseBuiltinFunc
  6627  }
  6628  
  6629  func (b *builtinTimeToSecSig) Clone() builtinFunc {
  6630  	newSig := &builtinTimeToSecSig{}
  6631  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6632  	return newSig
  6633  }
  6634  
  6635  // evalInt evals TIME_TO_SEC(time).
  6636  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_time-to-sec
  6637  func (b *builtinTimeToSecSig) evalInt(event chunk.Event) (int64, bool, error) {
  6638  	duration, isNull, err := b.args[0].EvalDuration(b.ctx, event)
  6639  	if isNull || err != nil {
  6640  		return 0, isNull, err
  6641  	}
  6642  	var sign int
  6643  	if duration.Duration >= 0 {
  6644  		sign = 1
  6645  	} else {
  6646  		sign = -1
  6647  	}
  6648  	return int64(sign * (duration.Hour()*3600 + duration.Minute()*60 + duration.Second())), false, nil
  6649  }
  6650  
  6651  type timestampAddFunctionClass struct {
  6652  	baseFunctionClass
  6653  }
  6654  
  6655  func (c *timestampAddFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  6656  	if err := c.verifyArgs(args); err != nil {
  6657  		return nil, err
  6658  	}
  6659  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString, types.ETInt, types.ETDatetime)
  6660  	if err != nil {
  6661  		return nil, err
  6662  	}
  6663  	bf.tp = &types.FieldType{Tp: allegrosql.TypeString, Flen: allegrosql.MaxDatetimeWidthNoFsp, Decimal: types.UnspecifiedLength}
  6664  	sig := &builtinTimestampAddSig{bf}
  6665  	sig.setPbCode(fidelpb.ScalarFuncSig_TimestampAdd)
  6666  	return sig, nil
  6667  
  6668  }
  6669  
  6670  type builtinTimestampAddSig struct {
  6671  	baseBuiltinFunc
  6672  }
  6673  
  6674  func (b *builtinTimestampAddSig) Clone() builtinFunc {
  6675  	newSig := &builtinTimestampAddSig{}
  6676  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6677  	return newSig
  6678  }
  6679  
  6680  // evalString evals a builtinTimestampAddSig.
  6681  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timestampadd
  6682  func (b *builtinTimestampAddSig) evalString(event chunk.Event) (string, bool, error) {
  6683  	unit, isNull, err := b.args[0].EvalString(b.ctx, event)
  6684  	if isNull || err != nil {
  6685  		return "", isNull, err
  6686  	}
  6687  	v, isNull, err := b.args[1].EvalInt(b.ctx, event)
  6688  	if isNull || err != nil {
  6689  		return "", isNull, err
  6690  	}
  6691  	arg, isNull, err := b.args[2].EvalTime(b.ctx, event)
  6692  	if isNull || err != nil {
  6693  		return "", isNull, err
  6694  	}
  6695  	tm1, err := arg.GoTime(time.Local)
  6696  	if err != nil {
  6697  		return "", isNull, err
  6698  	}
  6699  	var tb time.Time
  6700  	fsp := types.DefaultFsp
  6701  	switch unit {
  6702  	case "MICROSECOND":
  6703  		tb = tm1.Add(time.Duration(v) * time.Microsecond)
  6704  		fsp = types.MaxFsp
  6705  	case "SECOND":
  6706  		tb = tm1.Add(time.Duration(v) * time.Second)
  6707  	case "MINUTE":
  6708  		tb = tm1.Add(time.Duration(v) * time.Minute)
  6709  	case "HOUR":
  6710  		tb = tm1.Add(time.Duration(v) * time.Hour)
  6711  	case "DAY":
  6712  		tb = tm1.AddDate(0, 0, int(v))
  6713  	case "WEEK":
  6714  		tb = tm1.AddDate(0, 0, 7*int(v))
  6715  	case "MONTH":
  6716  		tb = tm1.AddDate(0, int(v), 0)
  6717  	case "QUARTER":
  6718  		tb = tm1.AddDate(0, 3*int(v), 0)
  6719  	case "YEAR":
  6720  		tb = tm1.AddDate(int(v), 0, 0)
  6721  	default:
  6722  		return "", true, types.ErrWrongValue.GenWithStackByArgs(types.TimeStr, unit)
  6723  	}
  6724  	r := types.NewTime(types.FromGoTime(tb), b.resolveType(arg.Type(), unit), fsp)
  6725  	if err = r.Check(b.ctx.GetStochastikVars().StmtCtx); err != nil {
  6726  		return "", true, handleInvalidTimeError(b.ctx, err)
  6727  	}
  6728  	return r.String(), false, nil
  6729  }
  6730  
  6731  func (b *builtinTimestampAddSig) resolveType(typ uint8, unit string) uint8 {
  6732  	// The approach below is from MyALLEGROSQL.
  6733  	// The field type for the result of an Item_date function is defined as
  6734  	// follows:
  6735  	//
  6736  	//- If first arg is a MYALLEGROSQL_TYPE_DATETIME result is MYALLEGROSQL_TYPE_DATETIME
  6737  	//- If first arg is a MYALLEGROSQL_TYPE_DATE and the interval type uses hours,
  6738  	//	minutes, seconds or microsecond then type is MYALLEGROSQL_TYPE_DATETIME.
  6739  	//- Otherwise the result is MYALLEGROSQL_TYPE_STRING
  6740  	//	(This is because you can't know if the string contains a DATE, MYALLEGROSQL_TIME
  6741  	//	or DATETIME argument)
  6742  	if typ == allegrosql.TypeDate && (unit == "HOUR" || unit == "MINUTE" || unit == "SECOND" || unit == "MICROSECOND") {
  6743  		return allegrosql.TypeDatetime
  6744  	}
  6745  	return typ
  6746  }
  6747  
  6748  type toDaysFunctionClass struct {
  6749  	baseFunctionClass
  6750  }
  6751  
  6752  func (c *toDaysFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  6753  	if err := c.verifyArgs(args); err != nil {
  6754  		return nil, err
  6755  	}
  6756  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETDatetime)
  6757  	if err != nil {
  6758  		return nil, err
  6759  	}
  6760  	sig := &builtinToDaysSig{bf}
  6761  	sig.setPbCode(fidelpb.ScalarFuncSig_ToDays)
  6762  	return sig, nil
  6763  }
  6764  
  6765  type builtinToDaysSig struct {
  6766  	baseBuiltinFunc
  6767  }
  6768  
  6769  func (b *builtinToDaysSig) Clone() builtinFunc {
  6770  	newSig := &builtinToDaysSig{}
  6771  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6772  	return newSig
  6773  }
  6774  
  6775  // evalInt evals a builtinToDaysSig.
  6776  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_to-days
  6777  func (b *builtinToDaysSig) evalInt(event chunk.Event) (int64, bool, error) {
  6778  	arg, isNull, err := b.args[0].EvalTime(b.ctx, event)
  6779  
  6780  	if isNull || err != nil {
  6781  		return 0, true, handleInvalidTimeError(b.ctx, err)
  6782  	}
  6783  	ret := types.TimestamFIDeliff("DAY", types.ZeroDate, arg)
  6784  	if ret == 0 {
  6785  		return 0, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, arg.String()))
  6786  	}
  6787  	return ret, false, nil
  6788  }
  6789  
  6790  type toSecondsFunctionClass struct {
  6791  	baseFunctionClass
  6792  }
  6793  
  6794  func (c *toSecondsFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  6795  	if err := c.verifyArgs(args); err != nil {
  6796  		return nil, err
  6797  	}
  6798  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETDatetime)
  6799  	if err != nil {
  6800  		return nil, err
  6801  	}
  6802  	sig := &builtinToSecondsSig{bf}
  6803  	sig.setPbCode(fidelpb.ScalarFuncSig_ToSeconds)
  6804  	return sig, nil
  6805  }
  6806  
  6807  type builtinToSecondsSig struct {
  6808  	baseBuiltinFunc
  6809  }
  6810  
  6811  func (b *builtinToSecondsSig) Clone() builtinFunc {
  6812  	newSig := &builtinToSecondsSig{}
  6813  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6814  	return newSig
  6815  }
  6816  
  6817  // evalInt evals a builtinToSecondsSig.
  6818  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_to-seconds
  6819  func (b *builtinToSecondsSig) evalInt(event chunk.Event) (int64, bool, error) {
  6820  	arg, isNull, err := b.args[0].EvalTime(b.ctx, event)
  6821  	if isNull || err != nil {
  6822  		return 0, true, handleInvalidTimeError(b.ctx, err)
  6823  	}
  6824  	ret := types.TimestamFIDeliff("SECOND", types.ZeroDate, arg)
  6825  	if ret == 0 {
  6826  		return 0, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, arg.String()))
  6827  	}
  6828  	return ret, false, nil
  6829  }
  6830  
  6831  type utcTimeFunctionClass struct {
  6832  	baseFunctionClass
  6833  }
  6834  
  6835  func (c *utcTimeFunctionClass) getFlenAndDecimal4UTCTime(ctx stochastikctx.Context, args []Expression) (flen, decimal int) {
  6836  	if len(args) == 0 {
  6837  		flen, decimal = 8, 0
  6838  		return
  6839  	}
  6840  	if constant, ok := args[0].(*Constant); ok {
  6841  		fsp, isNull, err := constant.EvalInt(ctx, chunk.Event{})
  6842  		if isNull || err != nil || fsp > int64(types.MaxFsp) {
  6843  			decimal = int(types.MaxFsp)
  6844  		} else if fsp < int64(types.MinFsp) {
  6845  			decimal = int(types.MinFsp)
  6846  		} else {
  6847  			decimal = int(fsp)
  6848  		}
  6849  	}
  6850  	if decimal > 0 {
  6851  		flen = 8 + 1 + decimal
  6852  	} else {
  6853  		flen = 8
  6854  	}
  6855  	return flen, decimal
  6856  }
  6857  
  6858  func (c *utcTimeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  6859  	if err := c.verifyArgs(args); err != nil {
  6860  		return nil, err
  6861  	}
  6862  	argTps := make([]types.EvalType, 0, 1)
  6863  	if len(args) == 1 {
  6864  		argTps = append(argTps, types.ETInt)
  6865  	}
  6866  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDuration, argTps...)
  6867  	if err != nil {
  6868  		return nil, err
  6869  	}
  6870  	bf.tp.Flen, bf.tp.Decimal = c.getFlenAndDecimal4UTCTime(bf.ctx, args)
  6871  
  6872  	var sig builtinFunc
  6873  	if len(args) == 1 {
  6874  		sig = &builtinUTCTimeWithArgSig{bf}
  6875  		sig.setPbCode(fidelpb.ScalarFuncSig_UTCTimeWithArg)
  6876  	} else {
  6877  		sig = &builtinUTCTimeWithoutArgSig{bf}
  6878  		sig.setPbCode(fidelpb.ScalarFuncSig_UTCTimeWithoutArg)
  6879  	}
  6880  	return sig, nil
  6881  }
  6882  
  6883  type builtinUTCTimeWithoutArgSig struct {
  6884  	baseBuiltinFunc
  6885  }
  6886  
  6887  func (b *builtinUTCTimeWithoutArgSig) Clone() builtinFunc {
  6888  	newSig := &builtinUTCTimeWithoutArgSig{}
  6889  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6890  	return newSig
  6891  }
  6892  
  6893  // evalDuration evals a builtinUTCTimeWithoutArgSig.
  6894  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_utc-time
  6895  func (b *builtinUTCTimeWithoutArgSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  6896  	nowTs, err := getStmtTimestamp(b.ctx)
  6897  	if err != nil {
  6898  		return types.Duration{}, true, err
  6899  	}
  6900  	v, err := types.ParseDuration(b.ctx.GetStochastikVars().StmtCtx, nowTs.UTC().Format(types.TimeFormat), 0)
  6901  	return v, false, err
  6902  }
  6903  
  6904  type builtinUTCTimeWithArgSig struct {
  6905  	baseBuiltinFunc
  6906  }
  6907  
  6908  func (b *builtinUTCTimeWithArgSig) Clone() builtinFunc {
  6909  	newSig := &builtinUTCTimeWithArgSig{}
  6910  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6911  	return newSig
  6912  }
  6913  
  6914  // evalDuration evals a builtinUTCTimeWithArgSig.
  6915  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_utc-time
  6916  func (b *builtinUTCTimeWithArgSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
  6917  	fsp, isNull, err := b.args[0].EvalInt(b.ctx, event)
  6918  	if isNull || err != nil {
  6919  		return types.Duration{}, isNull, err
  6920  	}
  6921  	if fsp > int64(types.MaxFsp) {
  6922  		return types.Duration{}, true, errors.Errorf("Too-big precision %v specified for 'utc_time'. Maximum is %v.", fsp, types.MaxFsp)
  6923  	}
  6924  	if fsp < int64(types.MinFsp) {
  6925  		return types.Duration{}, true, errors.Errorf("Invalid negative %d specified, must in [0, 6].", fsp)
  6926  	}
  6927  	nowTs, err := getStmtTimestamp(b.ctx)
  6928  	if err != nil {
  6929  		return types.Duration{}, true, err
  6930  	}
  6931  	v, err := types.ParseDuration(b.ctx.GetStochastikVars().StmtCtx, nowTs.UTC().Format(types.TimeFSPFormat), int8(fsp))
  6932  	return v, false, err
  6933  }
  6934  
  6935  type lastDayFunctionClass struct {
  6936  	baseFunctionClass
  6937  }
  6938  
  6939  func (c *lastDayFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  6940  	if err := c.verifyArgs(args); err != nil {
  6941  		return nil, err
  6942  	}
  6943  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETDatetime, types.ETDatetime)
  6944  	if err != nil {
  6945  		return nil, err
  6946  	}
  6947  	bf.tp.Tp, bf.tp.Flen, bf.tp.Decimal = allegrosql.TypeDate, allegrosql.MaxDateWidth, int(types.DefaultFsp)
  6948  	sig := &builtinLastDaySig{bf}
  6949  	sig.setPbCode(fidelpb.ScalarFuncSig_LastDay)
  6950  	return sig, nil
  6951  }
  6952  
  6953  type builtinLastDaySig struct {
  6954  	baseBuiltinFunc
  6955  }
  6956  
  6957  func (b *builtinLastDaySig) Clone() builtinFunc {
  6958  	newSig := &builtinLastDaySig{}
  6959  	newSig.cloneFrom(&b.baseBuiltinFunc)
  6960  	return newSig
  6961  }
  6962  
  6963  // evalTime evals a builtinLastDaySig.
  6964  // See https://dev.allegrosql.com/doc/refman/5.7/en/date-and-time-functions.html#function_last-day
  6965  func (b *builtinLastDaySig) evalTime(event chunk.Event) (types.Time, bool, error) {
  6966  	arg, isNull, err := b.args[0].EvalTime(b.ctx, event)
  6967  	if isNull || err != nil {
  6968  		return types.ZeroTime, true, handleInvalidTimeError(b.ctx, err)
  6969  	}
  6970  	tm := arg
  6971  	year, month := tm.Year(), tm.Month()
  6972  	if arg.InvalidZero() {
  6973  		return types.ZeroTime, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, arg.String()))
  6974  	}
  6975  	lastDay := types.GetLastDay(year, month)
  6976  	ret := types.NewTime(types.FromDate(year, month, lastDay, 0, 0, 0, 0), allegrosql.TypeDate, types.DefaultFsp)
  6977  	return ret, false, nil
  6978  }
  6979  
  6980  // getExpressionFsp calculates the fsp from given memex.
  6981  func getExpressionFsp(ctx stochastikctx.Context, memex Expression) (int, error) {
  6982  	constExp, isConstant := memex.(*Constant)
  6983  	if isConstant && types.IsString(memex.GetType().Tp) && !isTemporalDeferredCauset(memex) {
  6984  		str, isNil, err := constExp.EvalString(ctx, chunk.Event{})
  6985  		if isNil || err != nil {
  6986  			return 0, err
  6987  		}
  6988  		return int(types.GetFsp(str)), nil
  6989  	}
  6990  	return mathutil.Min(memex.GetType().Decimal, int(types.MaxFsp)), nil
  6991  }
  6992  
  6993  // milevadbParseTsoFunctionClass extracts physical time from a tso
  6994  type milevadbParseTsoFunctionClass struct {
  6995  	baseFunctionClass
  6996  }
  6997  
  6998  func (c *milevadbParseTsoFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  6999  	if err := c.verifyArgs(args); err != nil {
  7000  		return nil, err
  7001  	}
  7002  	argTp := args[0].GetType().EvalType()
  7003  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, argTp, types.ETInt)
  7004  	if err != nil {
  7005  		return nil, err
  7006  	}
  7007  
  7008  	bf.tp.Tp, bf.tp.Flen, bf.tp.Decimal = allegrosql.TypeDate, allegrosql.MaxDateWidth, int(types.DefaultFsp)
  7009  	sig := &builtinMilevaDBParseTsoSig{bf}
  7010  	return sig, nil
  7011  }
  7012  
  7013  type builtinMilevaDBParseTsoSig struct {
  7014  	baseBuiltinFunc
  7015  }
  7016  
  7017  func (b *builtinMilevaDBParseTsoSig) Clone() builtinFunc {
  7018  	newSig := &builtinMilevaDBParseTsoSig{}
  7019  	newSig.cloneFrom(&b.baseBuiltinFunc)
  7020  	return newSig
  7021  }
  7022  
  7023  // evalTime evals a builtinMilevaDBParseTsoSig.
  7024  func (b *builtinMilevaDBParseTsoSig) evalTime(event chunk.Event) (types.Time, bool, error) {
  7025  	arg, isNull, err := b.args[0].EvalInt(b.ctx, event)
  7026  	if isNull || err != nil || arg <= 0 {
  7027  		return types.ZeroTime, true, handleInvalidTimeError(b.ctx, err)
  7028  	}
  7029  
  7030  	t := oracle.GetTimeFromTS(uint64(arg))
  7031  	result := types.NewTime(types.FromGoTime(t), allegrosql.TypeDatetime, types.MaxFsp)
  7032  	err = result.ConvertTimeZone(time.Local, b.ctx.GetStochastikVars().Location())
  7033  	if err != nil {
  7034  		return types.ZeroTime, true, err
  7035  	}
  7036  	return result, false, nil
  7037  }