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

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package memex
    15  
    16  import (
    17  	"github.com/cznic/mathutil"
    18  	"github.com/whtcorpsinc/BerolinaSQL/charset"
    19  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    20  	"github.com/whtcorpsinc/milevadb/stochastikctx"
    21  	"github.com/whtcorpsinc/milevadb/types"
    22  	"github.com/whtcorpsinc/milevadb/types/json"
    23  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    24  	"github.com/whtcorpsinc/fidelpb/go-fidelpb"
    25  )
    26  
    27  var (
    28  	_ functionClass = &caseWhenFunctionClass{}
    29  	_ functionClass = &ifFunctionClass{}
    30  	_ functionClass = &ifNullFunctionClass{}
    31  )
    32  
    33  var (
    34  	_ builtinFunc = &builtinCaseWhenIntSig{}
    35  	_ builtinFunc = &builtinCaseWhenRealSig{}
    36  	_ builtinFunc = &builtinCaseWhenDecimalSig{}
    37  	_ builtinFunc = &builtinCaseWhenStringSig{}
    38  	_ builtinFunc = &builtinCaseWhenTimeSig{}
    39  	_ builtinFunc = &builtinCaseWhenDurationSig{}
    40  	_ builtinFunc = &builtinCaseWhenJSONSig{}
    41  	_ builtinFunc = &builtinIfNullIntSig{}
    42  	_ builtinFunc = &builtinIfNullRealSig{}
    43  	_ builtinFunc = &builtinIfNullDecimalSig{}
    44  	_ builtinFunc = &builtinIfNullStringSig{}
    45  	_ builtinFunc = &builtinIfNullTimeSig{}
    46  	_ builtinFunc = &builtinIfNullDurationSig{}
    47  	_ builtinFunc = &builtinIfNullJSONSig{}
    48  	_ builtinFunc = &builtinIfIntSig{}
    49  	_ builtinFunc = &builtinIfRealSig{}
    50  	_ builtinFunc = &builtinIfDecimalSig{}
    51  	_ builtinFunc = &builtinIfStringSig{}
    52  	_ builtinFunc = &builtinIfTimeSig{}
    53  	_ builtinFunc = &builtinIfDurationSig{}
    54  	_ builtinFunc = &builtinIfJSONSig{}
    55  )
    56  
    57  // InferType4ControlFuncs infer result type for builtin IF, IFNULL, NULLIF, LEAD and LAG.
    58  func InferType4ControlFuncs(lexp, rexp Expression) *types.FieldType {
    59  	lhs, rhs := lexp.GetType(), rexp.GetType()
    60  	resultFieldType := &types.FieldType{}
    61  	if lhs.Tp == allegrosql.TypeNull {
    62  		*resultFieldType = *rhs
    63  		// If both arguments are NULL, make resulting type BINARY(0).
    64  		if rhs.Tp == allegrosql.TypeNull {
    65  			resultFieldType.Tp = allegrosql.TypeString
    66  			resultFieldType.Flen, resultFieldType.Decimal = 0, 0
    67  			types.SetBinChsClnFlag(resultFieldType)
    68  		}
    69  	} else if rhs.Tp == allegrosql.TypeNull {
    70  		*resultFieldType = *lhs
    71  	} else {
    72  		resultFieldType = types.AggFieldType([]*types.FieldType{lhs, rhs})
    73  		evalType := types.AggregateEvalType([]*types.FieldType{lhs, rhs}, &resultFieldType.Flag)
    74  		if evalType == types.ETInt {
    75  			resultFieldType.Decimal = 0
    76  		} else {
    77  			if lhs.Decimal == types.UnspecifiedLength || rhs.Decimal == types.UnspecifiedLength {
    78  				resultFieldType.Decimal = types.UnspecifiedLength
    79  			} else {
    80  				resultFieldType.Decimal = mathutil.Max(lhs.Decimal, rhs.Decimal)
    81  			}
    82  		}
    83  		if types.IsNonBinaryStr(lhs) && !types.IsBinaryStr(rhs) {
    84  			resultFieldType.DefCauslate, resultFieldType.Charset, _, _ = inferDefCauslation(lexp, rexp)
    85  			resultFieldType.Flag = 0
    86  			if allegrosql.HasBinaryFlag(lhs.Flag) || !types.IsNonBinaryStr(rhs) {
    87  				resultFieldType.Flag |= allegrosql.BinaryFlag
    88  			}
    89  		} else if types.IsNonBinaryStr(rhs) && !types.IsBinaryStr(lhs) {
    90  			resultFieldType.DefCauslate, resultFieldType.Charset, _, _ = inferDefCauslation(lexp, rexp)
    91  			resultFieldType.Flag = 0
    92  			if allegrosql.HasBinaryFlag(rhs.Flag) || !types.IsNonBinaryStr(lhs) {
    93  				resultFieldType.Flag |= allegrosql.BinaryFlag
    94  			}
    95  		} else if types.IsBinaryStr(lhs) || types.IsBinaryStr(rhs) || !evalType.IsStringHoTT() {
    96  			types.SetBinChsClnFlag(resultFieldType)
    97  		} else {
    98  			resultFieldType.Charset, resultFieldType.DefCauslate, resultFieldType.Flag = allegrosql.DefaultCharset, allegrosql.DefaultDefCauslationName, 0
    99  		}
   100  		if evalType == types.ETDecimal || evalType == types.ETInt {
   101  			lhsUnsignedFlag, rhsUnsignedFlag := allegrosql.HasUnsignedFlag(lhs.Flag), allegrosql.HasUnsignedFlag(rhs.Flag)
   102  			lhsFlagLen, rhsFlagLen := 0, 0
   103  			if !lhsUnsignedFlag {
   104  				lhsFlagLen = 1
   105  			}
   106  			if !rhsUnsignedFlag {
   107  				rhsFlagLen = 1
   108  			}
   109  			lhsFlen := lhs.Flen - lhsFlagLen
   110  			rhsFlen := rhs.Flen - rhsFlagLen
   111  			if lhs.Decimal != types.UnspecifiedLength {
   112  				lhsFlen -= lhs.Decimal
   113  			}
   114  			if lhs.Decimal != types.UnspecifiedLength {
   115  				rhsFlen -= rhs.Decimal
   116  			}
   117  			resultFieldType.Flen = mathutil.Max(lhsFlen, rhsFlen) + resultFieldType.Decimal + 1
   118  		} else {
   119  			resultFieldType.Flen = mathutil.Max(lhs.Flen, rhs.Flen)
   120  		}
   121  	}
   122  	// Fix decimal for int and string.
   123  	resultEvalType := resultFieldType.EvalType()
   124  	if resultEvalType == types.ETInt {
   125  		resultFieldType.Decimal = 0
   126  	} else if resultEvalType == types.ETString {
   127  		if lhs.Tp != allegrosql.TypeNull || rhs.Tp != allegrosql.TypeNull {
   128  			resultFieldType.Decimal = types.UnspecifiedLength
   129  		}
   130  	}
   131  	return resultFieldType
   132  }
   133  
   134  type caseWhenFunctionClass struct {
   135  	baseFunctionClass
   136  }
   137  
   138  func (c *caseWhenFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) {
   139  	if err = c.verifyArgs(args); err != nil {
   140  		return nil, err
   141  	}
   142  	l := len(args)
   143  	// Fill in each 'THEN' clause parameter type.
   144  	fieldTps := make([]*types.FieldType, 0, (l+1)/2)
   145  	decimal, flen, isBinaryStr, isBinaryFlag := args[1].GetType().Decimal, 0, false, false
   146  	for i := 1; i < l; i += 2 {
   147  		fieldTps = append(fieldTps, args[i].GetType())
   148  		decimal = mathutil.Max(decimal, args[i].GetType().Decimal)
   149  		if args[i].GetType().Flen == -1 {
   150  			flen = -1
   151  		} else if flen != -1 {
   152  			flen = mathutil.Max(flen, args[i].GetType().Flen)
   153  		}
   154  		isBinaryStr = isBinaryStr || types.IsBinaryStr(args[i].GetType())
   155  		isBinaryFlag = isBinaryFlag || !types.IsNonBinaryStr(args[i].GetType())
   156  	}
   157  	if l%2 == 1 {
   158  		fieldTps = append(fieldTps, args[l-1].GetType())
   159  		decimal = mathutil.Max(decimal, args[l-1].GetType().Decimal)
   160  		if args[l-1].GetType().Flen == -1 {
   161  			flen = -1
   162  		} else if flen != -1 {
   163  			flen = mathutil.Max(flen, args[l-1].GetType().Flen)
   164  		}
   165  		isBinaryStr = isBinaryStr || types.IsBinaryStr(args[l-1].GetType())
   166  		isBinaryFlag = isBinaryFlag || !types.IsNonBinaryStr(args[l-1].GetType())
   167  	}
   168  
   169  	fieldTp := types.AggFieldType(fieldTps)
   170  	tp := fieldTp.EvalType()
   171  
   172  	if tp == types.ETInt {
   173  		decimal = 0
   174  	}
   175  	fieldTp.Decimal, fieldTp.Flen = decimal, flen
   176  	if fieldTp.EvalType().IsStringHoTT() && !isBinaryStr {
   177  		fieldTp.Charset, fieldTp.DefCauslate = charset.CharsetUTF8MB4, charset.DefCauslationUTF8MB4
   178  	}
   179  	if isBinaryFlag {
   180  		fieldTp.Flag |= allegrosql.BinaryFlag
   181  	}
   182  	// Set retType to BINARY(0) if all arguments are of type NULL.
   183  	if fieldTp.Tp == allegrosql.TypeNull {
   184  		fieldTp.Flen, fieldTp.Decimal = 0, types.UnspecifiedLength
   185  		types.SetBinChsClnFlag(fieldTp)
   186  	}
   187  	argTps := make([]types.EvalType, 0, l)
   188  	for i := 0; i < l-1; i += 2 {
   189  		if args[i], err = wrapWithIsTrue(ctx, true, args[i], false); err != nil {
   190  			return nil, err
   191  		}
   192  		argTps = append(argTps, types.ETInt, tp)
   193  	}
   194  	if l%2 == 1 {
   195  		argTps = append(argTps, tp)
   196  	}
   197  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, tp, argTps...)
   198  	if err != nil {
   199  		return nil, err
   200  	}
   201  	bf.tp = fieldTp
   202  
   203  	switch tp {
   204  	case types.ETInt:
   205  		bf.tp.Decimal = 0
   206  		sig = &builtinCaseWhenIntSig{bf}
   207  		sig.setPbCode(fidelpb.ScalarFuncSig_CaseWhenInt)
   208  	case types.ETReal:
   209  		sig = &builtinCaseWhenRealSig{bf}
   210  		sig.setPbCode(fidelpb.ScalarFuncSig_CaseWhenReal)
   211  	case types.ETDecimal:
   212  		sig = &builtinCaseWhenDecimalSig{bf}
   213  		sig.setPbCode(fidelpb.ScalarFuncSig_CaseWhenDecimal)
   214  	case types.ETString:
   215  		bf.tp.Decimal = types.UnspecifiedLength
   216  		sig = &builtinCaseWhenStringSig{bf}
   217  		sig.setPbCode(fidelpb.ScalarFuncSig_CaseWhenString)
   218  	case types.ETDatetime, types.ETTimestamp:
   219  		sig = &builtinCaseWhenTimeSig{bf}
   220  		sig.setPbCode(fidelpb.ScalarFuncSig_CaseWhenTime)
   221  	case types.ETDuration:
   222  		sig = &builtinCaseWhenDurationSig{bf}
   223  		sig.setPbCode(fidelpb.ScalarFuncSig_CaseWhenDuration)
   224  	case types.ETJson:
   225  		sig = &builtinCaseWhenJSONSig{bf}
   226  		sig.setPbCode(fidelpb.ScalarFuncSig_CaseWhenJson)
   227  	}
   228  	return sig, nil
   229  }
   230  
   231  type builtinCaseWhenIntSig struct {
   232  	baseBuiltinFunc
   233  }
   234  
   235  func (b *builtinCaseWhenIntSig) Clone() builtinFunc {
   236  	newSig := &builtinCaseWhenIntSig{}
   237  	newSig.cloneFrom(&b.baseBuiltinFunc)
   238  	return newSig
   239  }
   240  
   241  // evalInt evals a builtinCaseWhenIntSig.
   242  // See https://dev.allegrosql.com/doc/refman/5.7/en/control-flow-functions.html#operator_case
   243  func (b *builtinCaseWhenIntSig) evalInt(event chunk.Event) (ret int64, isNull bool, err error) {
   244  	var condition int64
   245  	args, l := b.getArgs(), len(b.getArgs())
   246  	for i := 0; i < l-1; i += 2 {
   247  		condition, isNull, err = args[i].EvalInt(b.ctx, event)
   248  		if err != nil {
   249  			return 0, isNull, err
   250  		}
   251  		if isNull || condition == 0 {
   252  			continue
   253  		}
   254  		ret, isNull, err = args[i+1].EvalInt(b.ctx, event)
   255  		return ret, isNull, err
   256  	}
   257  	// when clause(condition, result) -> args[i], args[i+1]; (i >= 0 && i+1 < l-1)
   258  	// else clause -> args[l-1]
   259  	// If case clause has else clause, l%2 == 1.
   260  	if l%2 == 1 {
   261  		ret, isNull, err = args[l-1].EvalInt(b.ctx, event)
   262  		return ret, isNull, err
   263  	}
   264  	return ret, true, nil
   265  }
   266  
   267  type builtinCaseWhenRealSig struct {
   268  	baseBuiltinFunc
   269  }
   270  
   271  func (b *builtinCaseWhenRealSig) Clone() builtinFunc {
   272  	newSig := &builtinCaseWhenRealSig{}
   273  	newSig.cloneFrom(&b.baseBuiltinFunc)
   274  	return newSig
   275  }
   276  
   277  // evalReal evals a builtinCaseWhenRealSig.
   278  // See https://dev.allegrosql.com/doc/refman/5.7/en/control-flow-functions.html#operator_case
   279  func (b *builtinCaseWhenRealSig) evalReal(event chunk.Event) (ret float64, isNull bool, err error) {
   280  	var condition int64
   281  	args, l := b.getArgs(), len(b.getArgs())
   282  	for i := 0; i < l-1; i += 2 {
   283  		condition, isNull, err = args[i].EvalInt(b.ctx, event)
   284  		if err != nil {
   285  			return 0, isNull, err
   286  		}
   287  		if isNull || condition == 0 {
   288  			continue
   289  		}
   290  		ret, isNull, err = args[i+1].EvalReal(b.ctx, event)
   291  		return ret, isNull, err
   292  	}
   293  	// when clause(condition, result) -> args[i], args[i+1]; (i >= 0 && i+1 < l-1)
   294  	// else clause -> args[l-1]
   295  	// If case clause has else clause, l%2 == 1.
   296  	if l%2 == 1 {
   297  		ret, isNull, err = args[l-1].EvalReal(b.ctx, event)
   298  		return ret, isNull, err
   299  	}
   300  	return ret, true, nil
   301  }
   302  
   303  type builtinCaseWhenDecimalSig struct {
   304  	baseBuiltinFunc
   305  }
   306  
   307  func (b *builtinCaseWhenDecimalSig) Clone() builtinFunc {
   308  	newSig := &builtinCaseWhenDecimalSig{}
   309  	newSig.cloneFrom(&b.baseBuiltinFunc)
   310  	return newSig
   311  }
   312  
   313  // evalDecimal evals a builtinCaseWhenDecimalSig.
   314  // See https://dev.allegrosql.com/doc/refman/5.7/en/control-flow-functions.html#operator_case
   315  func (b *builtinCaseWhenDecimalSig) evalDecimal(event chunk.Event) (ret *types.MyDecimal, isNull bool, err error) {
   316  	var condition int64
   317  	args, l := b.getArgs(), len(b.getArgs())
   318  	for i := 0; i < l-1; i += 2 {
   319  		condition, isNull, err = args[i].EvalInt(b.ctx, event)
   320  		if err != nil {
   321  			return nil, isNull, err
   322  		}
   323  		if isNull || condition == 0 {
   324  			continue
   325  		}
   326  		ret, isNull, err = args[i+1].EvalDecimal(b.ctx, event)
   327  		return ret, isNull, err
   328  	}
   329  	// when clause(condition, result) -> args[i], args[i+1]; (i >= 0 && i+1 < l-1)
   330  	// else clause -> args[l-1]
   331  	// If case clause has else clause, l%2 == 1.
   332  	if l%2 == 1 {
   333  		ret, isNull, err = args[l-1].EvalDecimal(b.ctx, event)
   334  		return ret, isNull, err
   335  	}
   336  	return ret, true, nil
   337  }
   338  
   339  type builtinCaseWhenStringSig struct {
   340  	baseBuiltinFunc
   341  }
   342  
   343  func (b *builtinCaseWhenStringSig) Clone() builtinFunc {
   344  	newSig := &builtinCaseWhenStringSig{}
   345  	newSig.cloneFrom(&b.baseBuiltinFunc)
   346  	return newSig
   347  }
   348  
   349  // evalString evals a builtinCaseWhenStringSig.
   350  // See https://dev.allegrosql.com/doc/refman/5.7/en/control-flow-functions.html#operator_case
   351  func (b *builtinCaseWhenStringSig) evalString(event chunk.Event) (ret string, isNull bool, err error) {
   352  	var condition int64
   353  	args, l := b.getArgs(), len(b.getArgs())
   354  	for i := 0; i < l-1; i += 2 {
   355  		condition, isNull, err = args[i].EvalInt(b.ctx, event)
   356  		if err != nil {
   357  			return "", isNull, err
   358  		}
   359  		if isNull || condition == 0 {
   360  			continue
   361  		}
   362  		ret, isNull, err = args[i+1].EvalString(b.ctx, event)
   363  		return ret, isNull, err
   364  	}
   365  	// when clause(condition, result) -> args[i], args[i+1]; (i >= 0 && i+1 < l-1)
   366  	// else clause -> args[l-1]
   367  	// If case clause has else clause, l%2 == 1.
   368  	if l%2 == 1 {
   369  		ret, isNull, err = args[l-1].EvalString(b.ctx, event)
   370  		return ret, isNull, err
   371  	}
   372  	return ret, true, nil
   373  }
   374  
   375  type builtinCaseWhenTimeSig struct {
   376  	baseBuiltinFunc
   377  }
   378  
   379  func (b *builtinCaseWhenTimeSig) Clone() builtinFunc {
   380  	newSig := &builtinCaseWhenTimeSig{}
   381  	newSig.cloneFrom(&b.baseBuiltinFunc)
   382  	return newSig
   383  }
   384  
   385  // evalTime evals a builtinCaseWhenTimeSig.
   386  // See https://dev.allegrosql.com/doc/refman/5.7/en/control-flow-functions.html#operator_case
   387  func (b *builtinCaseWhenTimeSig) evalTime(event chunk.Event) (ret types.Time, isNull bool, err error) {
   388  	var condition int64
   389  	args, l := b.getArgs(), len(b.getArgs())
   390  	for i := 0; i < l-1; i += 2 {
   391  		condition, isNull, err = args[i].EvalInt(b.ctx, event)
   392  		if err != nil {
   393  			return ret, isNull, err
   394  		}
   395  		if isNull || condition == 0 {
   396  			continue
   397  		}
   398  		ret, isNull, err = args[i+1].EvalTime(b.ctx, event)
   399  		return ret, isNull, err
   400  	}
   401  	// when clause(condition, result) -> args[i], args[i+1]; (i >= 0 && i+1 < l-1)
   402  	// else clause -> args[l-1]
   403  	// If case clause has else clause, l%2 == 1.
   404  	if l%2 == 1 {
   405  		ret, isNull, err = args[l-1].EvalTime(b.ctx, event)
   406  		return ret, isNull, err
   407  	}
   408  	return ret, true, nil
   409  }
   410  
   411  type builtinCaseWhenDurationSig struct {
   412  	baseBuiltinFunc
   413  }
   414  
   415  func (b *builtinCaseWhenDurationSig) Clone() builtinFunc {
   416  	newSig := &builtinCaseWhenDurationSig{}
   417  	newSig.cloneFrom(&b.baseBuiltinFunc)
   418  	return newSig
   419  }
   420  
   421  // evalDuration evals a builtinCaseWhenDurationSig.
   422  // See https://dev.allegrosql.com/doc/refman/5.7/en/control-flow-functions.html#operator_case
   423  func (b *builtinCaseWhenDurationSig) evalDuration(event chunk.Event) (ret types.Duration, isNull bool, err error) {
   424  	var condition int64
   425  	args, l := b.getArgs(), len(b.getArgs())
   426  	for i := 0; i < l-1; i += 2 {
   427  		condition, isNull, err = args[i].EvalInt(b.ctx, event)
   428  		if err != nil {
   429  			return ret, true, err
   430  		}
   431  		if isNull || condition == 0 {
   432  			continue
   433  		}
   434  		ret, isNull, err = args[i+1].EvalDuration(b.ctx, event)
   435  		return ret, isNull, err
   436  	}
   437  	// when clause(condition, result) -> args[i], args[i+1]; (i >= 0 && i+1 < l-1)
   438  	// else clause -> args[l-1]
   439  	// If case clause has else clause, l%2 == 1.
   440  	if l%2 == 1 {
   441  		ret, isNull, err = args[l-1].EvalDuration(b.ctx, event)
   442  		return ret, isNull, err
   443  	}
   444  	return ret, true, nil
   445  }
   446  
   447  type builtinCaseWhenJSONSig struct {
   448  	baseBuiltinFunc
   449  }
   450  
   451  func (b *builtinCaseWhenJSONSig) Clone() builtinFunc {
   452  	newSig := &builtinCaseWhenJSONSig{}
   453  	newSig.cloneFrom(&b.baseBuiltinFunc)
   454  	return newSig
   455  }
   456  
   457  // evalJSON evals a builtinCaseWhenJSONSig.
   458  // See https://dev.allegrosql.com/doc/refman/5.7/en/control-flow-functions.html#operator_case
   459  func (b *builtinCaseWhenJSONSig) evalJSON(event chunk.Event) (ret json.BinaryJSON, isNull bool, err error) {
   460  	var condition int64
   461  	args, l := b.getArgs(), len(b.getArgs())
   462  	for i := 0; i < l-1; i += 2 {
   463  		condition, isNull, err = args[i].EvalInt(b.ctx, event)
   464  		if err != nil {
   465  			return
   466  		}
   467  		if isNull || condition == 0 {
   468  			continue
   469  		}
   470  		return args[i+1].EvalJSON(b.ctx, event)
   471  	}
   472  	// when clause(condition, result) -> args[i], args[i+1]; (i >= 0 && i+1 < l-1)
   473  	// else clause -> args[l-1]
   474  	// If case clause has else clause, l%2 == 1.
   475  	if l%2 == 1 {
   476  		return args[l-1].EvalJSON(b.ctx, event)
   477  	}
   478  	return ret, true, nil
   479  }
   480  
   481  type ifFunctionClass struct {
   482  	baseFunctionClass
   483  }
   484  
   485  // getFunction see https://dev.allegrosql.com/doc/refman/5.7/en/control-flow-functions.html#function_if
   486  func (c *ifFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) {
   487  	if err = c.verifyArgs(args); err != nil {
   488  		return nil, err
   489  	}
   490  	retTp := InferType4ControlFuncs(args[1], args[2])
   491  	evalTps := retTp.EvalType()
   492  	args[0], err = wrapWithIsTrue(ctx, true, args[0], false)
   493  	if err != nil {
   494  		return nil, err
   495  	}
   496  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, evalTps, types.ETInt, evalTps, evalTps)
   497  	if err != nil {
   498  		return nil, err
   499  	}
   500  	retTp.Flag |= bf.tp.Flag
   501  	bf.tp = retTp
   502  	switch evalTps {
   503  	case types.ETInt:
   504  		sig = &builtinIfIntSig{bf}
   505  		sig.setPbCode(fidelpb.ScalarFuncSig_IfInt)
   506  	case types.ETReal:
   507  		sig = &builtinIfRealSig{bf}
   508  		sig.setPbCode(fidelpb.ScalarFuncSig_IfReal)
   509  	case types.ETDecimal:
   510  		sig = &builtinIfDecimalSig{bf}
   511  		sig.setPbCode(fidelpb.ScalarFuncSig_IfDecimal)
   512  	case types.ETString:
   513  		sig = &builtinIfStringSig{bf}
   514  		sig.setPbCode(fidelpb.ScalarFuncSig_IfString)
   515  	case types.ETDatetime, types.ETTimestamp:
   516  		sig = &builtinIfTimeSig{bf}
   517  		sig.setPbCode(fidelpb.ScalarFuncSig_IfTime)
   518  	case types.ETDuration:
   519  		sig = &builtinIfDurationSig{bf}
   520  		sig.setPbCode(fidelpb.ScalarFuncSig_IfDuration)
   521  	case types.ETJson:
   522  		sig = &builtinIfJSONSig{bf}
   523  		sig.setPbCode(fidelpb.ScalarFuncSig_IfJson)
   524  	}
   525  	return sig, nil
   526  }
   527  
   528  type builtinIfIntSig struct {
   529  	baseBuiltinFunc
   530  }
   531  
   532  func (b *builtinIfIntSig) Clone() builtinFunc {
   533  	newSig := &builtinIfIntSig{}
   534  	newSig.cloneFrom(&b.baseBuiltinFunc)
   535  	return newSig
   536  }
   537  
   538  func (b *builtinIfIntSig) evalInt(event chunk.Event) (ret int64, isNull bool, err error) {
   539  	arg0, isNull0, err := b.args[0].EvalInt(b.ctx, event)
   540  	if err != nil {
   541  		return 0, true, err
   542  	}
   543  	if !isNull0 && arg0 != 0 {
   544  		return b.args[1].EvalInt(b.ctx, event)
   545  	}
   546  	return b.args[2].EvalInt(b.ctx, event)
   547  }
   548  
   549  type builtinIfRealSig struct {
   550  	baseBuiltinFunc
   551  }
   552  
   553  func (b *builtinIfRealSig) Clone() builtinFunc {
   554  	newSig := &builtinIfRealSig{}
   555  	newSig.cloneFrom(&b.baseBuiltinFunc)
   556  	return newSig
   557  }
   558  
   559  func (b *builtinIfRealSig) evalReal(event chunk.Event) (ret float64, isNull bool, err error) {
   560  	arg0, isNull0, err := b.args[0].EvalInt(b.ctx, event)
   561  	if err != nil {
   562  		return 0, true, err
   563  	}
   564  	if !isNull0 && arg0 != 0 {
   565  		return b.args[1].EvalReal(b.ctx, event)
   566  	}
   567  	return b.args[2].EvalReal(b.ctx, event)
   568  }
   569  
   570  type builtinIfDecimalSig struct {
   571  	baseBuiltinFunc
   572  }
   573  
   574  func (b *builtinIfDecimalSig) Clone() builtinFunc {
   575  	newSig := &builtinIfDecimalSig{}
   576  	newSig.cloneFrom(&b.baseBuiltinFunc)
   577  	return newSig
   578  }
   579  
   580  func (b *builtinIfDecimalSig) evalDecimal(event chunk.Event) (ret *types.MyDecimal, isNull bool, err error) {
   581  	arg0, isNull0, err := b.args[0].EvalInt(b.ctx, event)
   582  	if err != nil {
   583  		return nil, true, err
   584  	}
   585  	if !isNull0 && arg0 != 0 {
   586  		return b.args[1].EvalDecimal(b.ctx, event)
   587  	}
   588  	return b.args[2].EvalDecimal(b.ctx, event)
   589  }
   590  
   591  type builtinIfStringSig struct {
   592  	baseBuiltinFunc
   593  }
   594  
   595  func (b *builtinIfStringSig) Clone() builtinFunc {
   596  	newSig := &builtinIfStringSig{}
   597  	newSig.cloneFrom(&b.baseBuiltinFunc)
   598  	return newSig
   599  }
   600  
   601  func (b *builtinIfStringSig) evalString(event chunk.Event) (ret string, isNull bool, err error) {
   602  	arg0, isNull0, err := b.args[0].EvalInt(b.ctx, event)
   603  	if err != nil {
   604  		return "", true, err
   605  	}
   606  	if !isNull0 && arg0 != 0 {
   607  		return b.args[1].EvalString(b.ctx, event)
   608  	}
   609  	return b.args[2].EvalString(b.ctx, event)
   610  }
   611  
   612  type builtinIfTimeSig struct {
   613  	baseBuiltinFunc
   614  }
   615  
   616  func (b *builtinIfTimeSig) Clone() builtinFunc {
   617  	newSig := &builtinIfTimeSig{}
   618  	newSig.cloneFrom(&b.baseBuiltinFunc)
   619  	return newSig
   620  }
   621  
   622  func (b *builtinIfTimeSig) evalTime(event chunk.Event) (ret types.Time, isNull bool, err error) {
   623  	arg0, isNull0, err := b.args[0].EvalInt(b.ctx, event)
   624  	if err != nil {
   625  		return ret, true, err
   626  	}
   627  	if !isNull0 && arg0 != 0 {
   628  		return b.args[1].EvalTime(b.ctx, event)
   629  	}
   630  	return b.args[2].EvalTime(b.ctx, event)
   631  }
   632  
   633  type builtinIfDurationSig struct {
   634  	baseBuiltinFunc
   635  }
   636  
   637  func (b *builtinIfDurationSig) Clone() builtinFunc {
   638  	newSig := &builtinIfDurationSig{}
   639  	newSig.cloneFrom(&b.baseBuiltinFunc)
   640  	return newSig
   641  }
   642  
   643  func (b *builtinIfDurationSig) evalDuration(event chunk.Event) (ret types.Duration, isNull bool, err error) {
   644  	arg0, isNull0, err := b.args[0].EvalInt(b.ctx, event)
   645  	if err != nil {
   646  		return ret, true, err
   647  	}
   648  	if !isNull0 && arg0 != 0 {
   649  		return b.args[1].EvalDuration(b.ctx, event)
   650  	}
   651  	return b.args[2].EvalDuration(b.ctx, event)
   652  }
   653  
   654  type builtinIfJSONSig struct {
   655  	baseBuiltinFunc
   656  }
   657  
   658  func (b *builtinIfJSONSig) Clone() builtinFunc {
   659  	newSig := &builtinIfJSONSig{}
   660  	newSig.cloneFrom(&b.baseBuiltinFunc)
   661  	return newSig
   662  }
   663  
   664  func (b *builtinIfJSONSig) evalJSON(event chunk.Event) (ret json.BinaryJSON, isNull bool, err error) {
   665  	arg0, isNull0, err := b.args[0].EvalInt(b.ctx, event)
   666  	if err != nil {
   667  		return ret, true, err
   668  	}
   669  	if !isNull0 && arg0 != 0 {
   670  		return b.args[1].EvalJSON(b.ctx, event)
   671  	}
   672  	return b.args[2].EvalJSON(b.ctx, event)
   673  }
   674  
   675  type ifNullFunctionClass struct {
   676  	baseFunctionClass
   677  }
   678  
   679  func (c *ifNullFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) {
   680  	if err = c.verifyArgs(args); err != nil {
   681  		return nil, err
   682  	}
   683  	lhs, rhs := args[0].GetType(), args[1].GetType()
   684  	retTp := InferType4ControlFuncs(args[0], args[1])
   685  	retTp.Flag |= (lhs.Flag & allegrosql.NotNullFlag) | (rhs.Flag & allegrosql.NotNullFlag)
   686  	if lhs.Tp == allegrosql.TypeNull && rhs.Tp == allegrosql.TypeNull {
   687  		retTp.Tp = allegrosql.TypeNull
   688  		retTp.Flen, retTp.Decimal = 0, -1
   689  		types.SetBinChsClnFlag(retTp)
   690  	}
   691  	evalTps := retTp.EvalType()
   692  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, evalTps, evalTps, evalTps)
   693  	if err != nil {
   694  		return nil, err
   695  	}
   696  	bf.tp = retTp
   697  	switch evalTps {
   698  	case types.ETInt:
   699  		sig = &builtinIfNullIntSig{bf}
   700  		sig.setPbCode(fidelpb.ScalarFuncSig_IfNullInt)
   701  	case types.ETReal:
   702  		sig = &builtinIfNullRealSig{bf}
   703  		sig.setPbCode(fidelpb.ScalarFuncSig_IfNullReal)
   704  	case types.ETDecimal:
   705  		sig = &builtinIfNullDecimalSig{bf}
   706  		sig.setPbCode(fidelpb.ScalarFuncSig_IfNullDecimal)
   707  	case types.ETString:
   708  		sig = &builtinIfNullStringSig{bf}
   709  		sig.setPbCode(fidelpb.ScalarFuncSig_IfNullString)
   710  	case types.ETDatetime, types.ETTimestamp:
   711  		sig = &builtinIfNullTimeSig{bf}
   712  		sig.setPbCode(fidelpb.ScalarFuncSig_IfNullTime)
   713  	case types.ETDuration:
   714  		sig = &builtinIfNullDurationSig{bf}
   715  		sig.setPbCode(fidelpb.ScalarFuncSig_IfNullDuration)
   716  	case types.ETJson:
   717  		sig = &builtinIfNullJSONSig{bf}
   718  		sig.setPbCode(fidelpb.ScalarFuncSig_IfNullJson)
   719  	}
   720  	return sig, nil
   721  }
   722  
   723  type builtinIfNullIntSig struct {
   724  	baseBuiltinFunc
   725  }
   726  
   727  func (b *builtinIfNullIntSig) Clone() builtinFunc {
   728  	newSig := &builtinIfNullIntSig{}
   729  	newSig.cloneFrom(&b.baseBuiltinFunc)
   730  	return newSig
   731  }
   732  
   733  func (b *builtinIfNullIntSig) evalInt(event chunk.Event) (int64, bool, error) {
   734  	arg0, isNull, err := b.args[0].EvalInt(b.ctx, event)
   735  	if !isNull || err != nil {
   736  		return arg0, err != nil, err
   737  	}
   738  	arg1, isNull, err := b.args[1].EvalInt(b.ctx, event)
   739  	return arg1, isNull || err != nil, err
   740  }
   741  
   742  type builtinIfNullRealSig struct {
   743  	baseBuiltinFunc
   744  }
   745  
   746  func (b *builtinIfNullRealSig) Clone() builtinFunc {
   747  	newSig := &builtinIfNullRealSig{}
   748  	newSig.cloneFrom(&b.baseBuiltinFunc)
   749  	return newSig
   750  }
   751  
   752  func (b *builtinIfNullRealSig) evalReal(event chunk.Event) (float64, bool, error) {
   753  	arg0, isNull, err := b.args[0].EvalReal(b.ctx, event)
   754  	if !isNull || err != nil {
   755  		return arg0, err != nil, err
   756  	}
   757  	arg1, isNull, err := b.args[1].EvalReal(b.ctx, event)
   758  	return arg1, isNull || err != nil, err
   759  }
   760  
   761  type builtinIfNullDecimalSig struct {
   762  	baseBuiltinFunc
   763  }
   764  
   765  func (b *builtinIfNullDecimalSig) Clone() builtinFunc {
   766  	newSig := &builtinIfNullDecimalSig{}
   767  	newSig.cloneFrom(&b.baseBuiltinFunc)
   768  	return newSig
   769  }
   770  
   771  func (b *builtinIfNullDecimalSig) evalDecimal(event chunk.Event) (*types.MyDecimal, bool, error) {
   772  	arg0, isNull, err := b.args[0].EvalDecimal(b.ctx, event)
   773  	if !isNull || err != nil {
   774  		return arg0, err != nil, err
   775  	}
   776  	arg1, isNull, err := b.args[1].EvalDecimal(b.ctx, event)
   777  	return arg1, isNull || err != nil, err
   778  }
   779  
   780  type builtinIfNullStringSig struct {
   781  	baseBuiltinFunc
   782  }
   783  
   784  func (b *builtinIfNullStringSig) Clone() builtinFunc {
   785  	newSig := &builtinIfNullStringSig{}
   786  	newSig.cloneFrom(&b.baseBuiltinFunc)
   787  	return newSig
   788  }
   789  
   790  func (b *builtinIfNullStringSig) evalString(event chunk.Event) (string, bool, error) {
   791  	arg0, isNull, err := b.args[0].EvalString(b.ctx, event)
   792  	if !isNull || err != nil {
   793  		return arg0, err != nil, err
   794  	}
   795  	arg1, isNull, err := b.args[1].EvalString(b.ctx, event)
   796  	return arg1, isNull || err != nil, err
   797  }
   798  
   799  type builtinIfNullTimeSig struct {
   800  	baseBuiltinFunc
   801  }
   802  
   803  func (b *builtinIfNullTimeSig) Clone() builtinFunc {
   804  	newSig := &builtinIfNullTimeSig{}
   805  	newSig.cloneFrom(&b.baseBuiltinFunc)
   806  	return newSig
   807  }
   808  
   809  func (b *builtinIfNullTimeSig) evalTime(event chunk.Event) (types.Time, bool, error) {
   810  	arg0, isNull, err := b.args[0].EvalTime(b.ctx, event)
   811  	if !isNull || err != nil {
   812  		return arg0, err != nil, err
   813  	}
   814  	arg1, isNull, err := b.args[1].EvalTime(b.ctx, event)
   815  	return arg1, isNull || err != nil, err
   816  }
   817  
   818  type builtinIfNullDurationSig struct {
   819  	baseBuiltinFunc
   820  }
   821  
   822  func (b *builtinIfNullDurationSig) Clone() builtinFunc {
   823  	newSig := &builtinIfNullDurationSig{}
   824  	newSig.cloneFrom(&b.baseBuiltinFunc)
   825  	return newSig
   826  }
   827  
   828  func (b *builtinIfNullDurationSig) evalDuration(event chunk.Event) (types.Duration, bool, error) {
   829  	arg0, isNull, err := b.args[0].EvalDuration(b.ctx, event)
   830  	if !isNull || err != nil {
   831  		return arg0, err != nil, err
   832  	}
   833  	arg1, isNull, err := b.args[1].EvalDuration(b.ctx, event)
   834  	return arg1, isNull || err != nil, err
   835  }
   836  
   837  type builtinIfNullJSONSig struct {
   838  	baseBuiltinFunc
   839  }
   840  
   841  func (b *builtinIfNullJSONSig) Clone() builtinFunc {
   842  	newSig := &builtinIfNullJSONSig{}
   843  	newSig.cloneFrom(&b.baseBuiltinFunc)
   844  	return newSig
   845  }
   846  
   847  func (b *builtinIfNullJSONSig) evalJSON(event chunk.Event) (json.BinaryJSON, bool, error) {
   848  	arg0, isNull, err := b.args[0].EvalJSON(b.ctx, event)
   849  	if !isNull {
   850  		return arg0, err != nil, err
   851  	}
   852  	arg1, isNull, err := b.args[1].EvalJSON(b.ctx, event)
   853  	return arg1, isNull || err != nil, err
   854  }