github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_info.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  	"encoding/hex"
    22  	"sort"
    23  	"strconv"
    24  	"strings"
    25  
    26  	"github.com/whtcorpsinc/errors"
    27  	"github.com/whtcorpsinc/BerolinaSQL/perceptron"
    28  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    29  	"github.com/whtcorpsinc/milevadb/privilege"
    30  	"github.com/whtcorpsinc/milevadb/stochastikctx"
    31  	"github.com/whtcorpsinc/milevadb/blockcodec"
    32  	"github.com/whtcorpsinc/milevadb/types"
    33  	"github.com/whtcorpsinc/milevadb/soliton"
    34  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    35  	"github.com/whtcorpsinc/milevadb/soliton/codec"
    36  	"github.com/whtcorpsinc/milevadb/soliton/plancodec"
    37  	"github.com/whtcorpsinc/milevadb/soliton/printer"
    38  	"github.com/whtcorpsinc/fidelpb/go-fidelpb"
    39  )
    40  
    41  var (
    42  	_ functionClass = &databaseFunctionClass{}
    43  	_ functionClass = &foundEventsFunctionClass{}
    44  	_ functionClass = &currentUserFunctionClass{}
    45  	_ functionClass = &currentRoleFunctionClass{}
    46  	_ functionClass = &userFunctionClass{}
    47  	_ functionClass = &connectionIDFunctionClass{}
    48  	_ functionClass = &lastInsertIDFunctionClass{}
    49  	_ functionClass = &versionFunctionClass{}
    50  	_ functionClass = &benchmarkFunctionClass{}
    51  	_ functionClass = &charsetFunctionClass{}
    52  	_ functionClass = &coercibilityFunctionClass{}
    53  	_ functionClass = &defCauslationFunctionClass{}
    54  	_ functionClass = &rowCountFunctionClass{}
    55  	_ functionClass = &milevadbVersionFunctionClass{}
    56  	_ functionClass = &milevadbIsDBSTenantFunctionClass{}
    57  	_ functionClass = &milevadbDecodeCausetFunctionClass{}
    58  	_ functionClass = &milevadbDecodeKeyFunctionClass{}
    59  	_ functionClass = &nextValFunctionClass{}
    60  	_ functionClass = &lastValFunctionClass{}
    61  	_ functionClass = &setValFunctionClass{}
    62  	_ functionClass = &formatBytesFunctionClass{}
    63  	_ functionClass = &formatNanoTimeFunctionClass{}
    64  )
    65  
    66  var (
    67  	_ builtinFunc = &builtinDatabaseSig{}
    68  	_ builtinFunc = &builtinFoundEventsSig{}
    69  	_ builtinFunc = &builtinCurrentUserSig{}
    70  	_ builtinFunc = &builtinUserSig{}
    71  	_ builtinFunc = &builtinConnectionIDSig{}
    72  	_ builtinFunc = &builtinLastInsertIDSig{}
    73  	_ builtinFunc = &builtinLastInsertIDWithIDSig{}
    74  	_ builtinFunc = &builtinVersionSig{}
    75  	_ builtinFunc = &builtinMilevaDBVersionSig{}
    76  	_ builtinFunc = &builtinEventCountSig{}
    77  	_ builtinFunc = &builtinMilevaDBDecodeKeySig{}
    78  	_ builtinFunc = &builtinNextValSig{}
    79  	_ builtinFunc = &builtinLastValSig{}
    80  	_ builtinFunc = &builtinSetValSig{}
    81  	_ builtinFunc = &builtinFormatBytesSig{}
    82  	_ builtinFunc = &builtinFormatNanoTimeSig{}
    83  )
    84  
    85  type databaseFunctionClass struct {
    86  	baseFunctionClass
    87  }
    88  
    89  func (c *databaseFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
    90  	if err := c.verifyArgs(args); err != nil {
    91  		return nil, err
    92  	}
    93  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString)
    94  	if err != nil {
    95  		return nil, err
    96  	}
    97  	bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo()
    98  	bf.tp.Flen = 64
    99  	sig := &builtinDatabaseSig{bf}
   100  	return sig, nil
   101  }
   102  
   103  type builtinDatabaseSig struct {
   104  	baseBuiltinFunc
   105  }
   106  
   107  func (b *builtinDatabaseSig) Clone() builtinFunc {
   108  	newSig := &builtinDatabaseSig{}
   109  	newSig.cloneFrom(&b.baseBuiltinFunc)
   110  	return newSig
   111  }
   112  
   113  // evalString evals a builtinDatabaseSig.
   114  // See https://dev.allegrosql.com/doc/refman/5.7/en/information-functions.html
   115  func (b *builtinDatabaseSig) evalString(event chunk.Event) (string, bool, error) {
   116  	currentDB := b.ctx.GetStochastikVars().CurrentDB
   117  	return currentDB, currentDB == "", nil
   118  }
   119  
   120  type foundEventsFunctionClass struct {
   121  	baseFunctionClass
   122  }
   123  
   124  func (c *foundEventsFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   125  	if err := c.verifyArgs(args); err != nil {
   126  		return nil, err
   127  	}
   128  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt)
   129  	if err != nil {
   130  		return nil, err
   131  	}
   132  	bf.tp.Flag |= allegrosql.UnsignedFlag
   133  	sig := &builtinFoundEventsSig{bf}
   134  	return sig, nil
   135  }
   136  
   137  type builtinFoundEventsSig struct {
   138  	baseBuiltinFunc
   139  }
   140  
   141  func (b *builtinFoundEventsSig) Clone() builtinFunc {
   142  	newSig := &builtinFoundEventsSig{}
   143  	newSig.cloneFrom(&b.baseBuiltinFunc)
   144  	return newSig
   145  }
   146  
   147  // evalInt evals a builtinFoundEventsSig.
   148  // See https://dev.allegrosql.com/doc/refman/5.7/en/information-functions.html#function_found-rows
   149  // TODO: ALLEGROSQL_CALC_FOUND_ROWS and LIMIT not support for now, We will finish in another PR.
   150  func (b *builtinFoundEventsSig) evalInt(event chunk.Event) (int64, bool, error) {
   151  	data := b.ctx.GetStochastikVars()
   152  	if data == nil {
   153  		return 0, true, errors.Errorf("Missing stochastik variable when eval builtin")
   154  	}
   155  	return int64(data.LastFoundEvents), false, nil
   156  }
   157  
   158  type currentUserFunctionClass struct {
   159  	baseFunctionClass
   160  }
   161  
   162  func (c *currentUserFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   163  	if err := c.verifyArgs(args); err != nil {
   164  		return nil, err
   165  	}
   166  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString)
   167  	if err != nil {
   168  		return nil, err
   169  	}
   170  	bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo()
   171  	bf.tp.Flen = 64
   172  	sig := &builtinCurrentUserSig{bf}
   173  	return sig, nil
   174  }
   175  
   176  type builtinCurrentUserSig struct {
   177  	baseBuiltinFunc
   178  }
   179  
   180  func (b *builtinCurrentUserSig) Clone() builtinFunc {
   181  	newSig := &builtinCurrentUserSig{}
   182  	newSig.cloneFrom(&b.baseBuiltinFunc)
   183  	return newSig
   184  }
   185  
   186  // evalString evals a builtinCurrentUserSig.
   187  // See https://dev.allegrosql.com/doc/refman/5.7/en/information-functions.html#function_current-user
   188  func (b *builtinCurrentUserSig) evalString(event chunk.Event) (string, bool, error) {
   189  	data := b.ctx.GetStochastikVars()
   190  	if data == nil || data.User == nil {
   191  		return "", true, errors.Errorf("Missing stochastik variable when eval builtin")
   192  	}
   193  	return data.User.AuthIdentityString(), false, nil
   194  }
   195  
   196  type currentRoleFunctionClass struct {
   197  	baseFunctionClass
   198  }
   199  
   200  func (c *currentRoleFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   201  	if err := c.verifyArgs(args); err != nil {
   202  		return nil, err
   203  	}
   204  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString)
   205  	if err != nil {
   206  		return nil, err
   207  	}
   208  	bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo()
   209  	bf.tp.Flen = 64
   210  	sig := &builtinCurrentRoleSig{bf}
   211  	return sig, nil
   212  }
   213  
   214  type builtinCurrentRoleSig struct {
   215  	baseBuiltinFunc
   216  }
   217  
   218  func (b *builtinCurrentRoleSig) Clone() builtinFunc {
   219  	newSig := &builtinCurrentRoleSig{}
   220  	newSig.cloneFrom(&b.baseBuiltinFunc)
   221  	return newSig
   222  }
   223  
   224  // evalString evals a builtinCurrentUserSig.
   225  // See https://dev.allegrosql.com/doc/refman/5.7/en/information-functions.html#function_current-user
   226  func (b *builtinCurrentRoleSig) evalString(event chunk.Event) (string, bool, error) {
   227  	data := b.ctx.GetStochastikVars()
   228  	if data == nil || data.ActiveRoles == nil {
   229  		return "", true, errors.Errorf("Missing stochastik variable when eval builtin")
   230  	}
   231  	if len(data.ActiveRoles) == 0 {
   232  		return "", false, nil
   233  	}
   234  	res := ""
   235  	sortedRes := make([]string, 0, 10)
   236  	for _, r := range data.ActiveRoles {
   237  		sortedRes = append(sortedRes, r.String())
   238  	}
   239  	sort.Strings(sortedRes)
   240  	for i, r := range sortedRes {
   241  		res += r
   242  		if i != len(data.ActiveRoles)-1 {
   243  			res += ","
   244  		}
   245  	}
   246  	return res, false, nil
   247  }
   248  
   249  type userFunctionClass struct {
   250  	baseFunctionClass
   251  }
   252  
   253  func (c *userFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   254  	if err := c.verifyArgs(args); err != nil {
   255  		return nil, err
   256  	}
   257  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString)
   258  	if err != nil {
   259  		return nil, err
   260  	}
   261  	bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo()
   262  	bf.tp.Flen = 64
   263  	sig := &builtinUserSig{bf}
   264  	return sig, nil
   265  }
   266  
   267  type builtinUserSig struct {
   268  	baseBuiltinFunc
   269  }
   270  
   271  func (b *builtinUserSig) Clone() builtinFunc {
   272  	newSig := &builtinUserSig{}
   273  	newSig.cloneFrom(&b.baseBuiltinFunc)
   274  	return newSig
   275  }
   276  
   277  // evalString evals a builtinUserSig.
   278  // See https://dev.allegrosql.com/doc/refman/5.7/en/information-functions.html#function_user
   279  func (b *builtinUserSig) evalString(event chunk.Event) (string, bool, error) {
   280  	data := b.ctx.GetStochastikVars()
   281  	if data == nil || data.User == nil {
   282  		return "", true, errors.Errorf("Missing stochastik variable when eval builtin")
   283  	}
   284  
   285  	return data.User.String(), false, nil
   286  }
   287  
   288  type connectionIDFunctionClass struct {
   289  	baseFunctionClass
   290  }
   291  
   292  func (c *connectionIDFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   293  	if err := c.verifyArgs(args); err != nil {
   294  		return nil, err
   295  	}
   296  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt)
   297  	if err != nil {
   298  		return nil, err
   299  	}
   300  	bf.tp.Flag |= allegrosql.UnsignedFlag
   301  	sig := &builtinConnectionIDSig{bf}
   302  	return sig, nil
   303  }
   304  
   305  type builtinConnectionIDSig struct {
   306  	baseBuiltinFunc
   307  }
   308  
   309  func (b *builtinConnectionIDSig) Clone() builtinFunc {
   310  	newSig := &builtinConnectionIDSig{}
   311  	newSig.cloneFrom(&b.baseBuiltinFunc)
   312  	return newSig
   313  }
   314  
   315  func (b *builtinConnectionIDSig) evalInt(_ chunk.Event) (int64, bool, error) {
   316  	data := b.ctx.GetStochastikVars()
   317  	if data == nil {
   318  		return 0, true, errors.Errorf("Missing stochastik variable `builtinConnectionIDSig.evalInt`")
   319  	}
   320  	return int64(data.ConnectionID), false, nil
   321  }
   322  
   323  type lastInsertIDFunctionClass struct {
   324  	baseFunctionClass
   325  }
   326  
   327  func (c *lastInsertIDFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) {
   328  	if err = c.verifyArgs(args); err != nil {
   329  		return nil, err
   330  	}
   331  
   332  	var argsTp []types.EvalType
   333  	if len(args) == 1 {
   334  		argsTp = append(argsTp, types.ETInt)
   335  	}
   336  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, argsTp...)
   337  	if err != nil {
   338  		return nil, err
   339  	}
   340  	bf.tp.Flag |= allegrosql.UnsignedFlag
   341  
   342  	if len(args) == 1 {
   343  		sig = &builtinLastInsertIDWithIDSig{bf}
   344  		sig.setPbCode(fidelpb.ScalarFuncSig_LastInsertIDWithID)
   345  	} else {
   346  		sig = &builtinLastInsertIDSig{bf}
   347  		sig.setPbCode(fidelpb.ScalarFuncSig_LastInsertID)
   348  	}
   349  	return sig, err
   350  }
   351  
   352  type builtinLastInsertIDSig struct {
   353  	baseBuiltinFunc
   354  }
   355  
   356  func (b *builtinLastInsertIDSig) Clone() builtinFunc {
   357  	newSig := &builtinLastInsertIDSig{}
   358  	newSig.cloneFrom(&b.baseBuiltinFunc)
   359  	return newSig
   360  }
   361  
   362  // evalInt evals LAST_INSERT_ID().
   363  // See https://dev.allegrosql.com/doc/refman/5.7/en/information-functions.html#function_last-insert-id.
   364  func (b *builtinLastInsertIDSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) {
   365  	res = int64(b.ctx.GetStochastikVars().StmtCtx.PrevLastInsertID)
   366  	return res, false, nil
   367  }
   368  
   369  type builtinLastInsertIDWithIDSig struct {
   370  	baseBuiltinFunc
   371  }
   372  
   373  func (b *builtinLastInsertIDWithIDSig) Clone() builtinFunc {
   374  	newSig := &builtinLastInsertIDWithIDSig{}
   375  	newSig.cloneFrom(&b.baseBuiltinFunc)
   376  	return newSig
   377  }
   378  
   379  // evalInt evals LAST_INSERT_ID(expr).
   380  // See https://dev.allegrosql.com/doc/refman/5.7/en/information-functions.html#function_last-insert-id.
   381  func (b *builtinLastInsertIDWithIDSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) {
   382  	res, isNull, err = b.args[0].EvalInt(b.ctx, event)
   383  	if isNull || err != nil {
   384  		return res, isNull, err
   385  	}
   386  
   387  	b.ctx.GetStochastikVars().SetLastInsertID(uint64(res))
   388  	return res, false, nil
   389  }
   390  
   391  type versionFunctionClass struct {
   392  	baseFunctionClass
   393  }
   394  
   395  func (c *versionFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   396  	if err := c.verifyArgs(args); err != nil {
   397  		return nil, err
   398  	}
   399  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString)
   400  	if err != nil {
   401  		return nil, err
   402  	}
   403  	bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo()
   404  	bf.tp.Flen = 64
   405  	sig := &builtinVersionSig{bf}
   406  	return sig, nil
   407  }
   408  
   409  type builtinVersionSig struct {
   410  	baseBuiltinFunc
   411  }
   412  
   413  func (b *builtinVersionSig) Clone() builtinFunc {
   414  	newSig := &builtinVersionSig{}
   415  	newSig.cloneFrom(&b.baseBuiltinFunc)
   416  	return newSig
   417  }
   418  
   419  // evalString evals a builtinVersionSig.
   420  // See https://dev.allegrosql.com/doc/refman/5.7/en/information-functions.html#function_version
   421  func (b *builtinVersionSig) evalString(event chunk.Event) (string, bool, error) {
   422  	return allegrosql.ServerVersion, false, nil
   423  }
   424  
   425  type milevadbVersionFunctionClass struct {
   426  	baseFunctionClass
   427  }
   428  
   429  func (c *milevadbVersionFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   430  	if err := c.verifyArgs(args); err != nil {
   431  		return nil, err
   432  	}
   433  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString)
   434  	if err != nil {
   435  		return nil, err
   436  	}
   437  	bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo()
   438  	bf.tp.Flen = len(printer.GetMilevaDBInfo())
   439  	sig := &builtinMilevaDBVersionSig{bf}
   440  	return sig, nil
   441  }
   442  
   443  type builtinMilevaDBVersionSig struct {
   444  	baseBuiltinFunc
   445  }
   446  
   447  func (b *builtinMilevaDBVersionSig) Clone() builtinFunc {
   448  	newSig := &builtinMilevaDBVersionSig{}
   449  	newSig.cloneFrom(&b.baseBuiltinFunc)
   450  	return newSig
   451  }
   452  
   453  // evalString evals a builtinMilevaDBVersionSig.
   454  // This will show git hash and build time for milevadb-server.
   455  func (b *builtinMilevaDBVersionSig) evalString(_ chunk.Event) (string, bool, error) {
   456  	return printer.GetMilevaDBInfo(), false, nil
   457  }
   458  
   459  type milevadbIsDBSTenantFunctionClass struct {
   460  	baseFunctionClass
   461  }
   462  
   463  func (c *milevadbIsDBSTenantFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   464  	if err := c.verifyArgs(args); err != nil {
   465  		return nil, err
   466  	}
   467  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt)
   468  	if err != nil {
   469  		return nil, err
   470  	}
   471  	sig := &builtinMilevaDBIsDBSTenantSig{bf}
   472  	return sig, nil
   473  }
   474  
   475  type builtinMilevaDBIsDBSTenantSig struct {
   476  	baseBuiltinFunc
   477  }
   478  
   479  func (b *builtinMilevaDBIsDBSTenantSig) Clone() builtinFunc {
   480  	newSig := &builtinMilevaDBIsDBSTenantSig{}
   481  	newSig.cloneFrom(&b.baseBuiltinFunc)
   482  	return newSig
   483  }
   484  
   485  // evalInt evals a builtinMilevaDBIsDBSTenantSig.
   486  func (b *builtinMilevaDBIsDBSTenantSig) evalInt(_ chunk.Event) (res int64, isNull bool, err error) {
   487  	dbsTenantChecker := b.ctx.DBSTenantChecker()
   488  	if dbsTenantChecker.IsTenant() {
   489  		res = 1
   490  	}
   491  
   492  	return res, false, nil
   493  }
   494  
   495  type benchmarkFunctionClass struct {
   496  	baseFunctionClass
   497  }
   498  
   499  func (c *benchmarkFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   500  	if err := c.verifyArgs(args); err != nil {
   501  		return nil, err
   502  	}
   503  
   504  	// Syntax: BENCHMARK(loop_count, memex)
   505  	// Define with same eval type of input arg to avoid unnecessary cast function.
   506  	sameEvalType := args[1].GetType().EvalType()
   507  	// constLoopCount is used by VecEvalInt
   508  	// since non-constant loop count would be different between rows, and cannot be vectorized.
   509  	var constLoopCount int64
   510  	con, ok := args[0].(*Constant)
   511  	if ok && con.Value.HoTT() == types.HoTTInt64 {
   512  		if lc, isNull, err := con.EvalInt(ctx, chunk.Event{}); err == nil && !isNull {
   513  			constLoopCount = lc
   514  		}
   515  	}
   516  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETInt, sameEvalType)
   517  	if err != nil {
   518  		return nil, err
   519  	}
   520  	sig := &builtinBenchmarkSig{bf, constLoopCount}
   521  	return sig, nil
   522  }
   523  
   524  type builtinBenchmarkSig struct {
   525  	baseBuiltinFunc
   526  	constLoopCount int64
   527  }
   528  
   529  func (b *builtinBenchmarkSig) Clone() builtinFunc {
   530  	newSig := &builtinBenchmarkSig{constLoopCount: b.constLoopCount}
   531  	newSig.cloneFrom(&b.baseBuiltinFunc)
   532  	return newSig
   533  }
   534  
   535  // evalInt evals a builtinBenchmarkSig. It will execute memex repeatedly count times.
   536  // See https://dev.allegrosql.com/doc/refman/5.7/en/information-functions.html#function_benchmark
   537  func (b *builtinBenchmarkSig) evalInt(event chunk.Event) (int64, bool, error) {
   538  	// Get loop count.
   539  	var loopCount int64
   540  	var isNull bool
   541  	var err error
   542  	if b.constLoopCount > 0 {
   543  		loopCount = b.constLoopCount
   544  	} else {
   545  		loopCount, isNull, err = b.args[0].EvalInt(b.ctx, event)
   546  		if isNull || err != nil {
   547  			return 0, isNull, err
   548  		}
   549  	}
   550  
   551  	// BENCHMARK() will return NULL if loop count < 0,
   552  	// behavior observed on MyALLEGROSQL 5.7.24.
   553  	if loopCount < 0 {
   554  		return 0, true, nil
   555  	}
   556  
   557  	// Eval loop count times based on arg type.
   558  	// BENCHMARK() will pass-through the eval error,
   559  	// behavior observed on MyALLEGROSQL 5.7.24.
   560  	var i int64
   561  	arg, ctx := b.args[1], b.ctx
   562  	switch evalType := arg.GetType().EvalType(); evalType {
   563  	case types.ETInt:
   564  		for ; i < loopCount; i++ {
   565  			_, isNull, err = arg.EvalInt(ctx, event)
   566  			if err != nil {
   567  				return 0, isNull, err
   568  			}
   569  		}
   570  	case types.ETReal:
   571  		for ; i < loopCount; i++ {
   572  			_, isNull, err = arg.EvalReal(ctx, event)
   573  			if err != nil {
   574  				return 0, isNull, err
   575  			}
   576  		}
   577  	case types.ETDecimal:
   578  		for ; i < loopCount; i++ {
   579  			_, isNull, err = arg.EvalDecimal(ctx, event)
   580  			if err != nil {
   581  				return 0, isNull, err
   582  			}
   583  		}
   584  	case types.ETString:
   585  		for ; i < loopCount; i++ {
   586  			_, isNull, err = arg.EvalString(ctx, event)
   587  			if err != nil {
   588  				return 0, isNull, err
   589  			}
   590  		}
   591  	case types.ETDatetime, types.ETTimestamp:
   592  		for ; i < loopCount; i++ {
   593  			_, isNull, err = arg.EvalTime(ctx, event)
   594  			if err != nil {
   595  				return 0, isNull, err
   596  			}
   597  		}
   598  	case types.ETDuration:
   599  		for ; i < loopCount; i++ {
   600  			_, isNull, err = arg.EvalDuration(ctx, event)
   601  			if err != nil {
   602  				return 0, isNull, err
   603  			}
   604  		}
   605  	case types.ETJson:
   606  		for ; i < loopCount; i++ {
   607  			_, isNull, err = arg.EvalJSON(ctx, event)
   608  			if err != nil {
   609  				return 0, isNull, err
   610  			}
   611  		}
   612  	default: // Should never go into here.
   613  		return 0, true, errors.Errorf("EvalType %v not implemented for builtin BENCHMARK()", evalType)
   614  	}
   615  
   616  	// Return value of BENCHMARK() is always 0.
   617  	return 0, false, nil
   618  }
   619  
   620  type charsetFunctionClass struct {
   621  	baseFunctionClass
   622  }
   623  
   624  func (c *charsetFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   625  	return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "CHARSET")
   626  }
   627  
   628  type coercibilityFunctionClass struct {
   629  	baseFunctionClass
   630  }
   631  
   632  func (c *coercibilityFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   633  	if err := c.verifyArgs(args); err != nil {
   634  		return nil, err
   635  	}
   636  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, args[0].GetType().EvalType())
   637  	if err != nil {
   638  		return nil, err
   639  	}
   640  	sig := &builtinCoercibilitySig{bf}
   641  	sig.setPbCode(fidelpb.ScalarFuncSig_Unspecified)
   642  	return sig, nil
   643  }
   644  
   645  type builtinCoercibilitySig struct {
   646  	baseBuiltinFunc
   647  }
   648  
   649  func (c *builtinCoercibilitySig) evalInt(_ chunk.Event) (res int64, isNull bool, err error) {
   650  	return int64(c.args[0].Coercibility()), false, nil
   651  }
   652  
   653  func (c *builtinCoercibilitySig) Clone() builtinFunc {
   654  	newSig := &builtinCoercibilitySig{}
   655  	newSig.cloneFrom(&c.baseBuiltinFunc)
   656  	return newSig
   657  }
   658  
   659  type defCauslationFunctionClass struct {
   660  	baseFunctionClass
   661  }
   662  
   663  func (c *defCauslationFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   664  	if err := c.verifyArgs(args); err != nil {
   665  		return nil, err
   666  	}
   667  	argsTps := make([]types.EvalType, 0, len(args))
   668  	for _, arg := range args {
   669  		argsTps = append(argsTps, arg.GetType().EvalType())
   670  	}
   671  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, argsTps...)
   672  	if err != nil {
   673  		return nil, err
   674  	}
   675  	bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo()
   676  	sig := &builtinDefCauslationSig{bf}
   677  	return sig, nil
   678  }
   679  
   680  type builtinDefCauslationSig struct {
   681  	baseBuiltinFunc
   682  }
   683  
   684  func (b *builtinDefCauslationSig) Clone() builtinFunc {
   685  	newSig := &builtinDefCauslationSig{}
   686  	newSig.cloneFrom(&b.baseBuiltinFunc)
   687  	return newSig
   688  }
   689  
   690  func (b *builtinDefCauslationSig) evalString(_ chunk.Event) (string, bool, error) {
   691  	return b.args[0].GetType().DefCauslate, false, nil
   692  }
   693  
   694  type rowCountFunctionClass struct {
   695  	baseFunctionClass
   696  }
   697  
   698  func (c *rowCountFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) {
   699  	if err = c.verifyArgs(args); err != nil {
   700  		return nil, err
   701  	}
   702  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt)
   703  	if err != nil {
   704  		return nil, err
   705  	}
   706  	sig = &builtinEventCountSig{bf}
   707  	sig.setPbCode(fidelpb.ScalarFuncSig_EventCount)
   708  	return sig, nil
   709  }
   710  
   711  type builtinEventCountSig struct {
   712  	baseBuiltinFunc
   713  }
   714  
   715  func (b *builtinEventCountSig) Clone() builtinFunc {
   716  	newSig := &builtinEventCountSig{}
   717  	newSig.cloneFrom(&b.baseBuiltinFunc)
   718  	return newSig
   719  }
   720  
   721  // evalInt evals ROW_COUNT().
   722  // See https://dev.allegrosql.com/doc/refman/5.7/en/information-functions.html#function_row-count.
   723  func (b *builtinEventCountSig) evalInt(_ chunk.Event) (res int64, isNull bool, err error) {
   724  	res = b.ctx.GetStochastikVars().StmtCtx.PrevAffectedEvents
   725  	return res, false, nil
   726  }
   727  
   728  type milevadbDecodeKeyFunctionClass struct {
   729  	baseFunctionClass
   730  }
   731  
   732  func (c *milevadbDecodeKeyFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   733  	if err := c.verifyArgs(args); err != nil {
   734  		return nil, err
   735  	}
   736  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString)
   737  	if err != nil {
   738  		return nil, err
   739  	}
   740  	sig := &builtinMilevaDBDecodeKeySig{bf}
   741  	return sig, nil
   742  }
   743  
   744  type builtinMilevaDBDecodeKeySig struct {
   745  	baseBuiltinFunc
   746  }
   747  
   748  func (b *builtinMilevaDBDecodeKeySig) Clone() builtinFunc {
   749  	newSig := &builtinMilevaDBDecodeKeySig{}
   750  	newSig.cloneFrom(&b.baseBuiltinFunc)
   751  	return newSig
   752  }
   753  
   754  // evalInt evals a builtinMilevaDBIsDBSTenantSig.
   755  func (b *builtinMilevaDBDecodeKeySig) evalString(event chunk.Event) (string, bool, error) {
   756  	s, isNull, err := b.args[0].EvalString(b.ctx, event)
   757  	if isNull || err != nil {
   758  		return "", isNull, err
   759  	}
   760  	return decodeKey(b.ctx, s), false, nil
   761  }
   762  
   763  func decodeKey(ctx stochastikctx.Context, s string) string {
   764  	key, err := hex.DecodeString(s)
   765  	if err != nil {
   766  		ctx.GetStochastikVars().StmtCtx.AppendWarning(errors.Errorf("invalid record/index key: %X", key))
   767  		return s
   768  	}
   769  	// Auto decode byte if needed.
   770  	_, bs, err := codec.DecodeBytes(key, nil)
   771  	if err == nil {
   772  		key = bs
   773  	}
   774  	// Try to decode it as a record key.
   775  	blockID, handle, err := blockcodec.DecodeRecordKey(key)
   776  	if err == nil {
   777  		if handle.IsInt() {
   778  			return "blockID=" + strconv.FormatInt(blockID, 10) + ", _milevadb_rowid=" + strconv.FormatInt(handle.IntValue(), 10)
   779  		}
   780  		return "blockID=" + strconv.FormatInt(blockID, 10) + ", clusterHandle=" + handle.String()
   781  	}
   782  	// Try decode as causet index key.
   783  	blockID, indexID, indexValues, err := blockcodec.DecodeIndexKey(key)
   784  	if err == nil {
   785  		return "blockID=" + strconv.FormatInt(blockID, 10) + ", indexID=" + strconv.FormatInt(indexID, 10) + ", indexValues=" + strings.Join(indexValues, ",")
   786  	}
   787  	// TODO: try to decode other type key.
   788  	ctx.GetStochastikVars().StmtCtx.AppendWarning(errors.Errorf("invalid record/index key: %X", key))
   789  	return s
   790  }
   791  
   792  type milevadbDecodeCausetFunctionClass struct {
   793  	baseFunctionClass
   794  }
   795  
   796  func (c *milevadbDecodeCausetFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   797  	if err := c.verifyArgs(args); err != nil {
   798  		return nil, err
   799  	}
   800  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString)
   801  	if err != nil {
   802  		return nil, err
   803  	}
   804  	sig := &builtinMilevaDBDecodeCausetSig{bf}
   805  	return sig, nil
   806  }
   807  
   808  type builtinMilevaDBDecodeCausetSig struct {
   809  	baseBuiltinFunc
   810  }
   811  
   812  func (b *builtinMilevaDBDecodeCausetSig) Clone() builtinFunc {
   813  	newSig := &builtinMilevaDBDecodeCausetSig{}
   814  	newSig.cloneFrom(&b.baseBuiltinFunc)
   815  	return newSig
   816  }
   817  
   818  func (b *builtinMilevaDBDecodeCausetSig) evalString(event chunk.Event) (string, bool, error) {
   819  	planString, isNull, err := b.args[0].EvalString(b.ctx, event)
   820  	if isNull || err != nil {
   821  		return "", isNull, err
   822  	}
   823  	planTree, err := plancodec.DecodeCauset(planString)
   824  	return planTree, false, err
   825  }
   826  
   827  type nextValFunctionClass struct {
   828  	baseFunctionClass
   829  }
   830  
   831  func (c *nextValFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   832  	if err := c.verifyArgs(args); err != nil {
   833  		return nil, err
   834  	}
   835  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETString)
   836  	if err != nil {
   837  		return nil, err
   838  	}
   839  	sig := &builtinNextValSig{bf}
   840  	bf.tp.Flen = 10
   841  	return sig, nil
   842  }
   843  
   844  type builtinNextValSig struct {
   845  	baseBuiltinFunc
   846  }
   847  
   848  func (b *builtinNextValSig) Clone() builtinFunc {
   849  	newSig := &builtinNextValSig{}
   850  	newSig.cloneFrom(&b.baseBuiltinFunc)
   851  	return newSig
   852  }
   853  
   854  func (b *builtinNextValSig) evalInt(event chunk.Event) (int64, bool, error) {
   855  	sequenceName, isNull, err := b.args[0].EvalString(b.ctx, event)
   856  	if isNull || err != nil {
   857  		return 0, isNull, err
   858  	}
   859  	EDB, seq := getSchemaAndSequence(sequenceName)
   860  	if len(EDB) == 0 {
   861  		EDB = b.ctx.GetStochastikVars().CurrentDB
   862  	}
   863  	// Check the blockName valid.
   864  	sequence, err := b.ctx.GetStochastikVars().TxnCtx.SchemaReplicant.(soliton.SequenceSchema).SequenceByName(perceptron.NewCIStr(EDB), perceptron.NewCIStr(seq))
   865  	if err != nil {
   866  		return 0, false, err
   867  	}
   868  	// Do the privilege check.
   869  	checker := privilege.GetPrivilegeManager(b.ctx)
   870  	user := b.ctx.GetStochastikVars().User
   871  	if checker != nil && !checker.RequestVerification(b.ctx.GetStochastikVars().ActiveRoles, EDB, seq, "", allegrosql.InsertPriv) {
   872  		return 0, false, errSequenceAccessDenied.GenWithStackByArgs("INSERT", user.AuthUsername, user.AuthHostname, seq)
   873  	}
   874  	nextVal, err := sequence.GetSequenceNextVal(b.ctx, EDB, seq)
   875  	if err != nil {
   876  		return 0, false, err
   877  	}
   878  	// uFIDelate the sequenceState.
   879  	b.ctx.GetStochastikVars().SequenceState.UFIDelateState(sequence.GetSequenceID(), nextVal)
   880  	return nextVal, false, nil
   881  }
   882  
   883  type lastValFunctionClass struct {
   884  	baseFunctionClass
   885  }
   886  
   887  func (c *lastValFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   888  	if err := c.verifyArgs(args); err != nil {
   889  		return nil, err
   890  	}
   891  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETString)
   892  	if err != nil {
   893  		return nil, err
   894  	}
   895  	sig := &builtinLastValSig{bf}
   896  	bf.tp.Flen = 10
   897  	return sig, nil
   898  }
   899  
   900  type builtinLastValSig struct {
   901  	baseBuiltinFunc
   902  }
   903  
   904  func (b *builtinLastValSig) Clone() builtinFunc {
   905  	newSig := &builtinLastValSig{}
   906  	newSig.cloneFrom(&b.baseBuiltinFunc)
   907  	return newSig
   908  }
   909  
   910  func (b *builtinLastValSig) evalInt(event chunk.Event) (int64, bool, error) {
   911  	sequenceName, isNull, err := b.args[0].EvalString(b.ctx, event)
   912  	if isNull || err != nil {
   913  		return 0, isNull, err
   914  	}
   915  	EDB, seq := getSchemaAndSequence(sequenceName)
   916  	if len(EDB) == 0 {
   917  		EDB = b.ctx.GetStochastikVars().CurrentDB
   918  	}
   919  	// Check the blockName valid.
   920  	sequence, err := b.ctx.GetStochastikVars().TxnCtx.SchemaReplicant.(soliton.SequenceSchema).SequenceByName(perceptron.NewCIStr(EDB), perceptron.NewCIStr(seq))
   921  	if err != nil {
   922  		return 0, false, err
   923  	}
   924  	// Do the privilege check.
   925  	checker := privilege.GetPrivilegeManager(b.ctx)
   926  	user := b.ctx.GetStochastikVars().User
   927  	if checker != nil && !checker.RequestVerification(b.ctx.GetStochastikVars().ActiveRoles, EDB, seq, "", allegrosql.SelectPriv) {
   928  		return 0, false, errSequenceAccessDenied.GenWithStackByArgs("SELECT", user.AuthUsername, user.AuthHostname, seq)
   929  	}
   930  	return b.ctx.GetStochastikVars().SequenceState.GetLastValue(sequence.GetSequenceID())
   931  }
   932  
   933  type setValFunctionClass struct {
   934  	baseFunctionClass
   935  }
   936  
   937  func (c *setValFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   938  	if err := c.verifyArgs(args); err != nil {
   939  		return nil, err
   940  	}
   941  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETString, types.ETInt)
   942  	if err != nil {
   943  		return nil, err
   944  	}
   945  	sig := &builtinSetValSig{bf}
   946  	bf.tp.Flen = args[1].GetType().Flen
   947  	return sig, nil
   948  }
   949  
   950  type builtinSetValSig struct {
   951  	baseBuiltinFunc
   952  }
   953  
   954  func (b *builtinSetValSig) Clone() builtinFunc {
   955  	newSig := &builtinSetValSig{}
   956  	newSig.cloneFrom(&b.baseBuiltinFunc)
   957  	return newSig
   958  }
   959  
   960  func (b *builtinSetValSig) evalInt(event chunk.Event) (int64, bool, error) {
   961  	sequenceName, isNull, err := b.args[0].EvalString(b.ctx, event)
   962  	if isNull || err != nil {
   963  		return 0, isNull, err
   964  	}
   965  	EDB, seq := getSchemaAndSequence(sequenceName)
   966  	if len(EDB) == 0 {
   967  		EDB = b.ctx.GetStochastikVars().CurrentDB
   968  	}
   969  	// Check the blockName valid.
   970  	sequence, err := b.ctx.GetStochastikVars().TxnCtx.SchemaReplicant.(soliton.SequenceSchema).SequenceByName(perceptron.NewCIStr(EDB), perceptron.NewCIStr(seq))
   971  	if err != nil {
   972  		return 0, false, err
   973  	}
   974  	// Do the privilege check.
   975  	checker := privilege.GetPrivilegeManager(b.ctx)
   976  	user := b.ctx.GetStochastikVars().User
   977  	if checker != nil && !checker.RequestVerification(b.ctx.GetStochastikVars().ActiveRoles, EDB, seq, "", allegrosql.InsertPriv) {
   978  		return 0, false, errSequenceAccessDenied.GenWithStackByArgs("INSERT", user.AuthUsername, user.AuthHostname, seq)
   979  	}
   980  	setValue, isNull, err := b.args[1].EvalInt(b.ctx, event)
   981  	if isNull || err != nil {
   982  		return 0, isNull, err
   983  	}
   984  	return sequence.SetSequenceVal(b.ctx, setValue, EDB, seq)
   985  }
   986  
   987  func getSchemaAndSequence(sequenceName string) (string, string) {
   988  	res := strings.Split(sequenceName, ".")
   989  	if len(res) == 1 {
   990  		return "", res[0]
   991  	}
   992  	return res[0], res[1]
   993  }
   994  
   995  type formatBytesFunctionClass struct {
   996  	baseFunctionClass
   997  }
   998  
   999  func (c *formatBytesFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1000  	if err := c.verifyArgs(args); err != nil {
  1001  		return nil, err
  1002  	}
  1003  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETReal)
  1004  	if err != nil {
  1005  		return nil, err
  1006  	}
  1007  	bf.tp.Flag |= allegrosql.UnsignedFlag
  1008  	sig := &builtinFormatBytesSig{bf}
  1009  	return sig, nil
  1010  }
  1011  
  1012  type builtinFormatBytesSig struct {
  1013  	baseBuiltinFunc
  1014  }
  1015  
  1016  func (b *builtinFormatBytesSig) Clone() builtinFunc {
  1017  	newSig := &builtinFormatBytesSig{}
  1018  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1019  	return newSig
  1020  }
  1021  
  1022  // formatBytes evals a builtinFormatBytesSig.
  1023  // See https://dev.allegrosql.com/doc/refman/8.0/en/performance-schemaReplicant-functions.html#function_format-bytes
  1024  func (b *builtinFormatBytesSig) evalString(event chunk.Event) (string, bool, error) {
  1025  	val, isNull, err := b.args[0].EvalReal(b.ctx, event)
  1026  	if isNull || err != nil {
  1027  		return "", isNull, err
  1028  	}
  1029  	return GetFormatBytes(val), false, nil
  1030  }
  1031  
  1032  type formatNanoTimeFunctionClass struct {
  1033  	baseFunctionClass
  1034  }
  1035  
  1036  func (c *formatNanoTimeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1037  	if err := c.verifyArgs(args); err != nil {
  1038  		return nil, err
  1039  	}
  1040  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETReal)
  1041  	if err != nil {
  1042  		return nil, err
  1043  	}
  1044  	bf.tp.Flag |= allegrosql.UnsignedFlag
  1045  	sig := &builtinFormatNanoTimeSig{bf}
  1046  	return sig, nil
  1047  }
  1048  
  1049  type builtinFormatNanoTimeSig struct {
  1050  	baseBuiltinFunc
  1051  }
  1052  
  1053  func (b *builtinFormatNanoTimeSig) Clone() builtinFunc {
  1054  	newSig := &builtinFormatNanoTimeSig{}
  1055  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1056  	return newSig
  1057  }
  1058  
  1059  // formatNanoTime evals a builtinFormatNanoTimeSig, as time unit in MilevaDB is always nanosecond, not picosecond.
  1060  // See https://dev.allegrosql.com/doc/refman/8.0/en/performance-schemaReplicant-functions.html#function_format-pico-time
  1061  func (b *builtinFormatNanoTimeSig) evalString(event chunk.Event) (string, bool, error) {
  1062  	val, isNull, err := b.args[0].EvalReal(b.ctx, event)
  1063  	if isNull || err != nil {
  1064  		return "", isNull, err
  1065  	}
  1066  	return GetFormatNanoTime(val), false, nil
  1067  }