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 }