github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_compare.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package memex 15 16 import ( 17 "math" 18 19 "github.com/whtcorpsinc/BerolinaSQL/ast" 20 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 21 "github.com/whtcorpsinc/BerolinaSQL/opcode" 22 "github.com/whtcorpsinc/BerolinaSQL/terror" 23 "github.com/whtcorpsinc/milevadb/stochastikctx" 24 "github.com/whtcorpsinc/milevadb/types" 25 "github.com/whtcorpsinc/milevadb/types/json" 26 "github.com/whtcorpsinc/milevadb/soliton/chunk" 27 "github.com/whtcorpsinc/fidelpb/go-fidelpb" 28 ) 29 30 var ( 31 _ functionClass = &coalesceFunctionClass{} 32 _ functionClass = &greatestFunctionClass{} 33 _ functionClass = &leastFunctionClass{} 34 _ functionClass = &intervalFunctionClass{} 35 _ functionClass = &compareFunctionClass{} 36 ) 37 38 var ( 39 _ builtinFunc = &builtinCoalesceIntSig{} 40 _ builtinFunc = &builtinCoalesceRealSig{} 41 _ builtinFunc = &builtinCoalesceDecimalSig{} 42 _ builtinFunc = &builtinCoalesceStringSig{} 43 _ builtinFunc = &builtinCoalesceTimeSig{} 44 _ builtinFunc = &builtinCoalesceDurationSig{} 45 46 _ builtinFunc = &builtinGreatestIntSig{} 47 _ builtinFunc = &builtinGreatestRealSig{} 48 _ builtinFunc = &builtinGreatestDecimalSig{} 49 _ builtinFunc = &builtinGreatestStringSig{} 50 _ builtinFunc = &builtinGreatestTimeSig{} 51 _ builtinFunc = &builtinLeastIntSig{} 52 _ builtinFunc = &builtinLeastRealSig{} 53 _ builtinFunc = &builtinLeastDecimalSig{} 54 _ builtinFunc = &builtinLeastStringSig{} 55 _ builtinFunc = &builtinLeastTimeSig{} 56 _ builtinFunc = &builtinIntervalIntSig{} 57 _ builtinFunc = &builtinIntervalRealSig{} 58 59 _ builtinFunc = &builtinLTIntSig{} 60 _ builtinFunc = &builtinLTRealSig{} 61 _ builtinFunc = &builtinLTDecimalSig{} 62 _ builtinFunc = &builtinLTStringSig{} 63 _ builtinFunc = &builtinLTDurationSig{} 64 _ builtinFunc = &builtinLTTimeSig{} 65 66 _ builtinFunc = &builtinLEIntSig{} 67 _ builtinFunc = &builtinLERealSig{} 68 _ builtinFunc = &builtinLEDecimalSig{} 69 _ builtinFunc = &builtinLEStringSig{} 70 _ builtinFunc = &builtinLEDurationSig{} 71 _ builtinFunc = &builtinLETimeSig{} 72 73 _ builtinFunc = &builtinGTIntSig{} 74 _ builtinFunc = &builtinGTRealSig{} 75 _ builtinFunc = &builtinGTDecimalSig{} 76 _ builtinFunc = &builtinGTStringSig{} 77 _ builtinFunc = &builtinGTTimeSig{} 78 _ builtinFunc = &builtinGTDurationSig{} 79 80 _ builtinFunc = &builtinGEIntSig{} 81 _ builtinFunc = &builtinGERealSig{} 82 _ builtinFunc = &builtinGEDecimalSig{} 83 _ builtinFunc = &builtinGEStringSig{} 84 _ builtinFunc = &builtinGETimeSig{} 85 _ builtinFunc = &builtinGEDurationSig{} 86 87 _ builtinFunc = &builtinNEIntSig{} 88 _ builtinFunc = &builtinNERealSig{} 89 _ builtinFunc = &builtinNEDecimalSig{} 90 _ builtinFunc = &builtinNEStringSig{} 91 _ builtinFunc = &builtinNETimeSig{} 92 _ builtinFunc = &builtinNEDurationSig{} 93 94 _ builtinFunc = &builtinNullEQIntSig{} 95 _ builtinFunc = &builtinNullEQRealSig{} 96 _ builtinFunc = &builtinNullEQDecimalSig{} 97 _ builtinFunc = &builtinNullEQStringSig{} 98 _ builtinFunc = &builtinNullEQTimeSig{} 99 _ builtinFunc = &builtinNullEQDurationSig{} 100 ) 101 102 // coalesceFunctionClass returns the first non-NULL value in the list, 103 // or NULL if there are no non-NULL values. 104 type coalesceFunctionClass struct { 105 baseFunctionClass 106 } 107 108 func (c *coalesceFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) { 109 if err = c.verifyArgs(args); err != nil { 110 return nil, err 111 } 112 113 fieldTps := make([]*types.FieldType, 0, len(args)) 114 for _, arg := range args { 115 fieldTps = append(fieldTps, arg.GetType()) 116 } 117 118 // Use the aggregated field type as retType. 119 resultFieldType := types.AggFieldType(fieldTps) 120 resultEvalType := types.AggregateEvalType(fieldTps, &resultFieldType.Flag) 121 retEvalTp := resultFieldType.EvalType() 122 123 fieldEvalTps := make([]types.EvalType, 0, len(args)) 124 for range args { 125 fieldEvalTps = append(fieldEvalTps, retEvalTp) 126 } 127 128 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, retEvalTp, fieldEvalTps...) 129 if err != nil { 130 return nil, err 131 } 132 133 bf.tp.Flag |= resultFieldType.Flag 134 resultFieldType.Flen, resultFieldType.Decimal = 0, types.UnspecifiedLength 135 136 // Set retType to BINARY(0) if all arguments are of type NULL. 137 if resultFieldType.Tp == allegrosql.TypeNull { 138 types.SetBinChsClnFlag(bf.tp) 139 } else { 140 maxIntLen := 0 141 maxFlen := 0 142 143 // Find the max length of field in `maxFlen`, 144 // and max integer-part length in `maxIntLen`. 145 for _, argTp := range fieldTps { 146 if argTp.Decimal > resultFieldType.Decimal { 147 resultFieldType.Decimal = argTp.Decimal 148 } 149 argIntLen := argTp.Flen 150 if argTp.Decimal > 0 { 151 argIntLen -= argTp.Decimal + 1 152 } 153 154 // Reduce the sign bit if it is a signed integer/decimal 155 if !allegrosql.HasUnsignedFlag(argTp.Flag) { 156 argIntLen-- 157 } 158 if argIntLen > maxIntLen { 159 maxIntLen = argIntLen 160 } 161 if argTp.Flen > maxFlen || argTp.Flen == types.UnspecifiedLength { 162 maxFlen = argTp.Flen 163 } 164 } 165 // For integer, field length = maxIntLen + (1/0 for sign bit) 166 // For decimal, field length = maxIntLen + maxDecimal + (1/0 for sign bit) 167 if resultEvalType == types.ETInt || resultEvalType == types.ETDecimal { 168 resultFieldType.Flen = maxIntLen + resultFieldType.Decimal 169 if resultFieldType.Decimal > 0 { 170 resultFieldType.Flen++ 171 } 172 if !allegrosql.HasUnsignedFlag(resultFieldType.Flag) { 173 resultFieldType.Flen++ 174 } 175 bf.tp = resultFieldType 176 } else { 177 bf.tp.Flen = maxFlen 178 } 179 // Set the field length to maxFlen for other types. 180 if bf.tp.Flen > allegrosql.MaxDecimalWidth { 181 bf.tp.Flen = allegrosql.MaxDecimalWidth 182 } 183 } 184 185 switch retEvalTp { 186 case types.ETInt: 187 sig = &builtinCoalesceIntSig{bf} 188 sig.setPbCode(fidelpb.ScalarFuncSig_CoalesceInt) 189 case types.ETReal: 190 sig = &builtinCoalesceRealSig{bf} 191 sig.setPbCode(fidelpb.ScalarFuncSig_CoalesceReal) 192 case types.ETDecimal: 193 sig = &builtinCoalesceDecimalSig{bf} 194 sig.setPbCode(fidelpb.ScalarFuncSig_CoalesceDecimal) 195 case types.ETString: 196 sig = &builtinCoalesceStringSig{bf} 197 sig.setPbCode(fidelpb.ScalarFuncSig_CoalesceString) 198 case types.ETDatetime, types.ETTimestamp: 199 sig = &builtinCoalesceTimeSig{bf} 200 sig.setPbCode(fidelpb.ScalarFuncSig_CoalesceTime) 201 case types.ETDuration: 202 bf.tp.Decimal, err = getExpressionFsp(ctx, args[0]) 203 if err != nil { 204 return nil, err 205 } 206 sig = &builtinCoalesceDurationSig{bf} 207 sig.setPbCode(fidelpb.ScalarFuncSig_CoalesceDuration) 208 case types.ETJson: 209 sig = &builtinCoalesceJSONSig{bf} 210 sig.setPbCode(fidelpb.ScalarFuncSig_CoalesceJson) 211 } 212 213 return sig, nil 214 } 215 216 // builtinCoalesceIntSig is builtin function coalesce signature which return type int 217 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#function_coalesce 218 type builtinCoalesceIntSig struct { 219 baseBuiltinFunc 220 } 221 222 func (b *builtinCoalesceIntSig) Clone() builtinFunc { 223 newSig := &builtinCoalesceIntSig{} 224 newSig.cloneFrom(&b.baseBuiltinFunc) 225 return newSig 226 } 227 228 func (b *builtinCoalesceIntSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) { 229 for _, a := range b.getArgs() { 230 res, isNull, err = a.EvalInt(b.ctx, event) 231 if err != nil || !isNull { 232 break 233 } 234 } 235 return res, isNull, err 236 } 237 238 // builtinCoalesceRealSig is builtin function coalesce signature which return type real 239 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#function_coalesce 240 type builtinCoalesceRealSig struct { 241 baseBuiltinFunc 242 } 243 244 func (b *builtinCoalesceRealSig) Clone() builtinFunc { 245 newSig := &builtinCoalesceRealSig{} 246 newSig.cloneFrom(&b.baseBuiltinFunc) 247 return newSig 248 } 249 250 func (b *builtinCoalesceRealSig) evalReal(event chunk.Event) (res float64, isNull bool, err error) { 251 for _, a := range b.getArgs() { 252 res, isNull, err = a.EvalReal(b.ctx, event) 253 if err != nil || !isNull { 254 break 255 } 256 } 257 return res, isNull, err 258 } 259 260 // builtinCoalesceDecimalSig is builtin function coalesce signature which return type Decimal 261 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#function_coalesce 262 type builtinCoalesceDecimalSig struct { 263 baseBuiltinFunc 264 } 265 266 func (b *builtinCoalesceDecimalSig) Clone() builtinFunc { 267 newSig := &builtinCoalesceDecimalSig{} 268 newSig.cloneFrom(&b.baseBuiltinFunc) 269 return newSig 270 } 271 272 func (b *builtinCoalesceDecimalSig) evalDecimal(event chunk.Event) (res *types.MyDecimal, isNull bool, err error) { 273 for _, a := range b.getArgs() { 274 res, isNull, err = a.EvalDecimal(b.ctx, event) 275 if err != nil || !isNull { 276 break 277 } 278 } 279 return res, isNull, err 280 } 281 282 // builtinCoalesceStringSig is builtin function coalesce signature which return type string 283 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#function_coalesce 284 type builtinCoalesceStringSig struct { 285 baseBuiltinFunc 286 } 287 288 func (b *builtinCoalesceStringSig) Clone() builtinFunc { 289 newSig := &builtinCoalesceStringSig{} 290 newSig.cloneFrom(&b.baseBuiltinFunc) 291 return newSig 292 } 293 294 func (b *builtinCoalesceStringSig) evalString(event chunk.Event) (res string, isNull bool, err error) { 295 for _, a := range b.getArgs() { 296 res, isNull, err = a.EvalString(b.ctx, event) 297 if err != nil || !isNull { 298 break 299 } 300 } 301 return res, isNull, err 302 } 303 304 // builtinCoalesceTimeSig is builtin function coalesce signature which return type time 305 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#function_coalesce 306 type builtinCoalesceTimeSig struct { 307 baseBuiltinFunc 308 } 309 310 func (b *builtinCoalesceTimeSig) Clone() builtinFunc { 311 newSig := &builtinCoalesceTimeSig{} 312 newSig.cloneFrom(&b.baseBuiltinFunc) 313 return newSig 314 } 315 316 func (b *builtinCoalesceTimeSig) evalTime(event chunk.Event) (res types.Time, isNull bool, err error) { 317 for _, a := range b.getArgs() { 318 res, isNull, err = a.EvalTime(b.ctx, event) 319 if err != nil || !isNull { 320 break 321 } 322 } 323 return res, isNull, err 324 } 325 326 // builtinCoalesceDurationSig is builtin function coalesce signature which return type duration 327 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#function_coalesce 328 type builtinCoalesceDurationSig struct { 329 baseBuiltinFunc 330 } 331 332 func (b *builtinCoalesceDurationSig) Clone() builtinFunc { 333 newSig := &builtinCoalesceDurationSig{} 334 newSig.cloneFrom(&b.baseBuiltinFunc) 335 return newSig 336 } 337 338 func (b *builtinCoalesceDurationSig) evalDuration(event chunk.Event) (res types.Duration, isNull bool, err error) { 339 for _, a := range b.getArgs() { 340 res, isNull, err = a.EvalDuration(b.ctx, event) 341 if err != nil || !isNull { 342 break 343 } 344 } 345 return res, isNull, err 346 } 347 348 // builtinCoalesceJSONSig is builtin function coalesce signature which return type json. 349 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#function_coalesce 350 type builtinCoalesceJSONSig struct { 351 baseBuiltinFunc 352 } 353 354 func (b *builtinCoalesceJSONSig) Clone() builtinFunc { 355 newSig := &builtinCoalesceJSONSig{} 356 newSig.cloneFrom(&b.baseBuiltinFunc) 357 return newSig 358 } 359 360 func (b *builtinCoalesceJSONSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) { 361 for _, a := range b.getArgs() { 362 res, isNull, err = a.EvalJSON(b.ctx, event) 363 if err != nil || !isNull { 364 break 365 } 366 } 367 return res, isNull, err 368 } 369 370 // temporalWithDateAsNumEvalType makes DATE, DATETIME, TIMESTAMP pretend to be numbers rather than strings. 371 func temporalWithDateAsNumEvalType(argTp *types.FieldType) (argEvalType types.EvalType, isStr bool, isTemporalWithDate bool) { 372 argEvalType = argTp.EvalType() 373 isStr, isTemporalWithDate = argEvalType.IsStringHoTT(), types.IsTemporalWithDate(argTp.Tp) 374 if !isTemporalWithDate { 375 return 376 } 377 if argTp.Decimal > 0 { 378 argEvalType = types.ETDecimal 379 } else { 380 argEvalType = types.ETInt 381 } 382 return 383 } 384 385 // GetCmpTp4MinMax gets compare type for GREATEST and LEAST and BETWEEN (mainly for datetime). 386 func GetCmpTp4MinMax(args []Expression) (argTp types.EvalType) { 387 datetimeFound, isAllStr := false, true 388 cmpEvalType, isStr, isTemporalWithDate := temporalWithDateAsNumEvalType(args[0].GetType()) 389 if !isStr { 390 isAllStr = false 391 } 392 if isTemporalWithDate { 393 datetimeFound = true 394 } 395 lft := args[0].GetType() 396 for i := range args { 397 rft := args[i].GetType() 398 var tp types.EvalType 399 tp, isStr, isTemporalWithDate = temporalWithDateAsNumEvalType(rft) 400 if isTemporalWithDate { 401 datetimeFound = true 402 } 403 if !isStr { 404 isAllStr = false 405 } 406 cmpEvalType = getBaseCmpType(cmpEvalType, tp, lft, rft) 407 lft = rft 408 } 409 argTp = cmpEvalType 410 if cmpEvalType.IsStringHoTT() { 411 argTp = types.ETString 412 } 413 if isAllStr && datetimeFound { 414 argTp = types.ETDatetime 415 } 416 return argTp 417 } 418 419 type greatestFunctionClass struct { 420 baseFunctionClass 421 } 422 423 func (c *greatestFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) { 424 if err = c.verifyArgs(args); err != nil { 425 return nil, err 426 } 427 tp, cmpAsDatetime := GetCmpTp4MinMax(args), false 428 if tp == types.ETDatetime { 429 cmpAsDatetime = true 430 tp = types.ETString 431 } 432 argTps := make([]types.EvalType, len(args)) 433 for i := range args { 434 argTps[i] = tp 435 } 436 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, tp, argTps...) 437 if err != nil { 438 return nil, err 439 } 440 if cmpAsDatetime { 441 tp = types.ETDatetime 442 } 443 switch tp { 444 case types.ETInt: 445 sig = &builtinGreatestIntSig{bf} 446 sig.setPbCode(fidelpb.ScalarFuncSig_GreatestInt) 447 case types.ETReal: 448 sig = &builtinGreatestRealSig{bf} 449 sig.setPbCode(fidelpb.ScalarFuncSig_GreatestReal) 450 case types.ETDecimal: 451 sig = &builtinGreatestDecimalSig{bf} 452 sig.setPbCode(fidelpb.ScalarFuncSig_GreatestDecimal) 453 case types.ETString: 454 sig = &builtinGreatestStringSig{bf} 455 sig.setPbCode(fidelpb.ScalarFuncSig_GreatestString) 456 case types.ETDatetime: 457 sig = &builtinGreatestTimeSig{bf} 458 sig.setPbCode(fidelpb.ScalarFuncSig_GreatestTime) 459 } 460 return sig, nil 461 } 462 463 type builtinGreatestIntSig struct { 464 baseBuiltinFunc 465 } 466 467 func (b *builtinGreatestIntSig) Clone() builtinFunc { 468 newSig := &builtinGreatestIntSig{} 469 newSig.cloneFrom(&b.baseBuiltinFunc) 470 return newSig 471 } 472 473 // evalInt evals a builtinGreatestIntSig. 474 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#function_greatest 475 func (b *builtinGreatestIntSig) evalInt(event chunk.Event) (max int64, isNull bool, err error) { 476 max, isNull, err = b.args[0].EvalInt(b.ctx, event) 477 if isNull || err != nil { 478 return max, isNull, err 479 } 480 for i := 1; i < len(b.args); i++ { 481 var v int64 482 v, isNull, err = b.args[i].EvalInt(b.ctx, event) 483 if isNull || err != nil { 484 return max, isNull, err 485 } 486 if v > max { 487 max = v 488 } 489 } 490 return 491 } 492 493 type builtinGreatestRealSig struct { 494 baseBuiltinFunc 495 } 496 497 func (b *builtinGreatestRealSig) Clone() builtinFunc { 498 newSig := &builtinGreatestRealSig{} 499 newSig.cloneFrom(&b.baseBuiltinFunc) 500 return newSig 501 } 502 503 // evalReal evals a builtinGreatestRealSig. 504 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#function_greatest 505 func (b *builtinGreatestRealSig) evalReal(event chunk.Event) (max float64, isNull bool, err error) { 506 max, isNull, err = b.args[0].EvalReal(b.ctx, event) 507 if isNull || err != nil { 508 return max, isNull, err 509 } 510 for i := 1; i < len(b.args); i++ { 511 var v float64 512 v, isNull, err = b.args[i].EvalReal(b.ctx, event) 513 if isNull || err != nil { 514 return max, isNull, err 515 } 516 if v > max { 517 max = v 518 } 519 } 520 return 521 } 522 523 type builtinGreatestDecimalSig struct { 524 baseBuiltinFunc 525 } 526 527 func (b *builtinGreatestDecimalSig) Clone() builtinFunc { 528 newSig := &builtinGreatestDecimalSig{} 529 newSig.cloneFrom(&b.baseBuiltinFunc) 530 return newSig 531 } 532 533 // evalDecimal evals a builtinGreatestDecimalSig. 534 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#function_greatest 535 func (b *builtinGreatestDecimalSig) evalDecimal(event chunk.Event) (max *types.MyDecimal, isNull bool, err error) { 536 max, isNull, err = b.args[0].EvalDecimal(b.ctx, event) 537 if isNull || err != nil { 538 return max, isNull, err 539 } 540 for i := 1; i < len(b.args); i++ { 541 var v *types.MyDecimal 542 v, isNull, err = b.args[i].EvalDecimal(b.ctx, event) 543 if isNull || err != nil { 544 return max, isNull, err 545 } 546 if v.Compare(max) > 0 { 547 max = v 548 } 549 } 550 return 551 } 552 553 type builtinGreatestStringSig struct { 554 baseBuiltinFunc 555 } 556 557 func (b *builtinGreatestStringSig) Clone() builtinFunc { 558 newSig := &builtinGreatestStringSig{} 559 newSig.cloneFrom(&b.baseBuiltinFunc) 560 return newSig 561 } 562 563 // evalString evals a builtinGreatestStringSig. 564 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#function_greatest 565 func (b *builtinGreatestStringSig) evalString(event chunk.Event) (max string, isNull bool, err error) { 566 max, isNull, err = b.args[0].EvalString(b.ctx, event) 567 if isNull || err != nil { 568 return max, isNull, err 569 } 570 for i := 1; i < len(b.args); i++ { 571 var v string 572 v, isNull, err = b.args[i].EvalString(b.ctx, event) 573 if isNull || err != nil { 574 return max, isNull, err 575 } 576 if types.CompareString(v, max, b.defCauslation) > 0 { 577 max = v 578 } 579 } 580 return 581 } 582 583 type builtinGreatestTimeSig struct { 584 baseBuiltinFunc 585 } 586 587 func (b *builtinGreatestTimeSig) Clone() builtinFunc { 588 newSig := &builtinGreatestTimeSig{} 589 newSig.cloneFrom(&b.baseBuiltinFunc) 590 return newSig 591 } 592 593 // evalString evals a builtinGreatestTimeSig. 594 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#function_greatest 595 func (b *builtinGreatestTimeSig) evalString(event chunk.Event) (_ string, isNull bool, err error) { 596 var ( 597 v string 598 t types.Time 599 ) 600 max := types.ZeroDatetime 601 sc := b.ctx.GetStochastikVars().StmtCtx 602 for i := 0; i < len(b.args); i++ { 603 v, isNull, err = b.args[i].EvalString(b.ctx, event) 604 if isNull || err != nil { 605 return "", true, err 606 } 607 t, err = types.ParseDatetime(sc, v) 608 if err != nil { 609 if err = handleInvalidTimeError(b.ctx, err); err != nil { 610 return v, true, err 611 } 612 continue 613 } 614 if t.Compare(max) > 0 { 615 max = t 616 } 617 } 618 return max.String(), false, nil 619 } 620 621 type leastFunctionClass struct { 622 baseFunctionClass 623 } 624 625 func (c *leastFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) { 626 if err = c.verifyArgs(args); err != nil { 627 return nil, err 628 } 629 tp, cmpAsDatetime := GetCmpTp4MinMax(args), false 630 if tp == types.ETDatetime { 631 cmpAsDatetime = true 632 tp = types.ETString 633 } 634 argTps := make([]types.EvalType, len(args)) 635 for i := range args { 636 argTps[i] = tp 637 } 638 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, tp, argTps...) 639 if err != nil { 640 return nil, err 641 } 642 if cmpAsDatetime { 643 tp = types.ETDatetime 644 } 645 switch tp { 646 case types.ETInt: 647 sig = &builtinLeastIntSig{bf} 648 sig.setPbCode(fidelpb.ScalarFuncSig_LeastInt) 649 case types.ETReal: 650 sig = &builtinLeastRealSig{bf} 651 sig.setPbCode(fidelpb.ScalarFuncSig_LeastReal) 652 case types.ETDecimal: 653 sig = &builtinLeastDecimalSig{bf} 654 sig.setPbCode(fidelpb.ScalarFuncSig_LeastDecimal) 655 case types.ETString: 656 sig = &builtinLeastStringSig{bf} 657 sig.setPbCode(fidelpb.ScalarFuncSig_LeastString) 658 case types.ETDatetime: 659 sig = &builtinLeastTimeSig{bf} 660 sig.setPbCode(fidelpb.ScalarFuncSig_LeastTime) 661 } 662 return sig, nil 663 } 664 665 type builtinLeastIntSig struct { 666 baseBuiltinFunc 667 } 668 669 func (b *builtinLeastIntSig) Clone() builtinFunc { 670 newSig := &builtinLeastIntSig{} 671 newSig.cloneFrom(&b.baseBuiltinFunc) 672 return newSig 673 } 674 675 // evalInt evals a builtinLeastIntSig. 676 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#function_least 677 func (b *builtinLeastIntSig) evalInt(event chunk.Event) (min int64, isNull bool, err error) { 678 min, isNull, err = b.args[0].EvalInt(b.ctx, event) 679 if isNull || err != nil { 680 return min, isNull, err 681 } 682 for i := 1; i < len(b.args); i++ { 683 var v int64 684 v, isNull, err = b.args[i].EvalInt(b.ctx, event) 685 if isNull || err != nil { 686 return min, isNull, err 687 } 688 if v < min { 689 min = v 690 } 691 } 692 return 693 } 694 695 type builtinLeastRealSig struct { 696 baseBuiltinFunc 697 } 698 699 func (b *builtinLeastRealSig) Clone() builtinFunc { 700 newSig := &builtinLeastRealSig{} 701 newSig.cloneFrom(&b.baseBuiltinFunc) 702 return newSig 703 } 704 705 // evalReal evals a builtinLeastRealSig. 706 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#functionleast 707 func (b *builtinLeastRealSig) evalReal(event chunk.Event) (min float64, isNull bool, err error) { 708 min, isNull, err = b.args[0].EvalReal(b.ctx, event) 709 if isNull || err != nil { 710 return min, isNull, err 711 } 712 for i := 1; i < len(b.args); i++ { 713 var v float64 714 v, isNull, err = b.args[i].EvalReal(b.ctx, event) 715 if isNull || err != nil { 716 return min, isNull, err 717 } 718 if v < min { 719 min = v 720 } 721 } 722 return 723 } 724 725 type builtinLeastDecimalSig struct { 726 baseBuiltinFunc 727 } 728 729 func (b *builtinLeastDecimalSig) Clone() builtinFunc { 730 newSig := &builtinLeastDecimalSig{} 731 newSig.cloneFrom(&b.baseBuiltinFunc) 732 return newSig 733 } 734 735 // evalDecimal evals a builtinLeastDecimalSig. 736 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#functionleast 737 func (b *builtinLeastDecimalSig) evalDecimal(event chunk.Event) (min *types.MyDecimal, isNull bool, err error) { 738 min, isNull, err = b.args[0].EvalDecimal(b.ctx, event) 739 if isNull || err != nil { 740 return min, isNull, err 741 } 742 for i := 1; i < len(b.args); i++ { 743 var v *types.MyDecimal 744 v, isNull, err = b.args[i].EvalDecimal(b.ctx, event) 745 if isNull || err != nil { 746 return min, isNull, err 747 } 748 if v.Compare(min) < 0 { 749 min = v 750 } 751 } 752 return 753 } 754 755 type builtinLeastStringSig struct { 756 baseBuiltinFunc 757 } 758 759 func (b *builtinLeastStringSig) Clone() builtinFunc { 760 newSig := &builtinLeastStringSig{} 761 newSig.cloneFrom(&b.baseBuiltinFunc) 762 return newSig 763 } 764 765 // evalString evals a builtinLeastStringSig. 766 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#functionleast 767 func (b *builtinLeastStringSig) evalString(event chunk.Event) (min string, isNull bool, err error) { 768 min, isNull, err = b.args[0].EvalString(b.ctx, event) 769 if isNull || err != nil { 770 return min, isNull, err 771 } 772 for i := 1; i < len(b.args); i++ { 773 var v string 774 v, isNull, err = b.args[i].EvalString(b.ctx, event) 775 if isNull || err != nil { 776 return min, isNull, err 777 } 778 if types.CompareString(v, min, b.defCauslation) < 0 { 779 min = v 780 } 781 } 782 return 783 } 784 785 type builtinLeastTimeSig struct { 786 baseBuiltinFunc 787 } 788 789 func (b *builtinLeastTimeSig) Clone() builtinFunc { 790 newSig := &builtinLeastTimeSig{} 791 newSig.cloneFrom(&b.baseBuiltinFunc) 792 return newSig 793 } 794 795 // evalString evals a builtinLeastTimeSig. 796 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#functionleast 797 func (b *builtinLeastTimeSig) evalString(event chunk.Event) (res string, isNull bool, err error) { 798 var ( 799 v string 800 t types.Time 801 ) 802 min := types.NewTime(types.MaxDatetime, allegrosql.TypeDatetime, types.MaxFsp) 803 findInvalidTime := false 804 sc := b.ctx.GetStochastikVars().StmtCtx 805 for i := 0; i < len(b.args); i++ { 806 v, isNull, err = b.args[i].EvalString(b.ctx, event) 807 if isNull || err != nil { 808 return "", true, err 809 } 810 t, err = types.ParseDatetime(sc, v) 811 if err != nil { 812 if err = handleInvalidTimeError(b.ctx, err); err != nil { 813 return v, true, err 814 } else if !findInvalidTime { 815 res = v 816 findInvalidTime = true 817 } 818 } 819 if t.Compare(min) < 0 { 820 min = t 821 } 822 } 823 if !findInvalidTime { 824 res = min.String() 825 } 826 return res, false, nil 827 } 828 829 type intervalFunctionClass struct { 830 baseFunctionClass 831 } 832 833 func (c *intervalFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) { 834 if err := c.verifyArgs(args); err != nil { 835 return nil, err 836 } 837 838 allInt := true 839 hasNullable := false 840 // if we have nullable defCausumns in the argument list, we won't do a binary search, instead we will linearly scan the arguments. 841 // this behavior is in line with MyALLEGROSQL's, see MyALLEGROSQL's source code here: 842 // https://github.com/allegrosql/allegrosql-server/blob/f8cdce86448a211511e8a039c62580ae16cb96f5/allegrosql/item_cmpfunc.cc#L2713-L2788 843 // https://github.com/allegrosql/allegrosql-server/blob/f8cdce86448a211511e8a039c62580ae16cb96f5/allegrosql/item_cmpfunc.cc#L2632-L2686 844 for i := range args { 845 tp := args[i].GetType() 846 if tp.EvalType() != types.ETInt { 847 allInt = false 848 } 849 if !allegrosql.HasNotNullFlag(tp.Flag) { 850 hasNullable = true 851 } 852 } 853 854 argTps, argTp := make([]types.EvalType, 0, len(args)), types.ETReal 855 if allInt { 856 argTp = types.ETInt 857 } 858 for range args { 859 argTps = append(argTps, argTp) 860 } 861 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, argTps...) 862 if err != nil { 863 return nil, err 864 } 865 var sig builtinFunc 866 if allInt { 867 sig = &builtinIntervalIntSig{bf, hasNullable} 868 sig.setPbCode(fidelpb.ScalarFuncSig_IntervalInt) 869 } else { 870 sig = &builtinIntervalRealSig{bf, hasNullable} 871 sig.setPbCode(fidelpb.ScalarFuncSig_IntervalReal) 872 } 873 return sig, nil 874 } 875 876 type builtinIntervalIntSig struct { 877 baseBuiltinFunc 878 hasNullable bool 879 } 880 881 func (b *builtinIntervalIntSig) Clone() builtinFunc { 882 newSig := &builtinIntervalIntSig{} 883 newSig.cloneFrom(&b.baseBuiltinFunc) 884 return newSig 885 } 886 887 // evalInt evals a builtinIntervalIntSig. 888 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#function_interval 889 func (b *builtinIntervalIntSig) evalInt(event chunk.Event) (int64, bool, error) { 890 arg0, isNull, err := b.args[0].EvalInt(b.ctx, event) 891 if err != nil { 892 return 0, true, err 893 } 894 if isNull { 895 return -1, false, nil 896 } 897 isUint1 := allegrosql.HasUnsignedFlag(b.args[0].GetType().Flag) 898 var idx int 899 if b.hasNullable { 900 idx, err = b.linearSearch(arg0, isUint1, b.args[1:], event) 901 } else { 902 idx, err = b.binSearch(arg0, isUint1, b.args[1:], event) 903 } 904 return int64(idx), err != nil, err 905 } 906 907 // linearSearch linearly scans the argument least to find the position of the first value that is larger than the given target. 908 func (b *builtinIntervalIntSig) linearSearch(target int64, isUint1 bool, args []Expression, event chunk.Event) (i int, err error) { 909 i = 0 910 for ; i < len(args); i++ { 911 isUint2 := allegrosql.HasUnsignedFlag(args[i].GetType().Flag) 912 arg, isNull, err := args[i].EvalInt(b.ctx, event) 913 if err != nil { 914 return 0, err 915 } 916 var less bool 917 if !isNull { 918 switch { 919 case !isUint1 && !isUint2: 920 less = target < arg 921 case isUint1 && isUint2: 922 less = uint64(target) < uint64(arg) 923 case !isUint1 && isUint2: 924 less = target < 0 || uint64(target) < uint64(arg) 925 case isUint1 && !isUint2: 926 less = arg > 0 && uint64(target) < uint64(arg) 927 } 928 } 929 if less { 930 break 931 } 932 } 933 return i, nil 934 } 935 936 // binSearch is a binary search method. 937 // All arguments are treated as integers. 938 // It is required that arg[0] < args[1] < args[2] < ... < args[n] for this function to work correctly. 939 // This is because a binary search is used (very fast). 940 func (b *builtinIntervalIntSig) binSearch(target int64, isUint1 bool, args []Expression, event chunk.Event) (_ int, err error) { 941 i, j, cmp := 0, len(args), false 942 for i < j { 943 mid := i + (j-i)/2 944 v, isNull, err1 := args[mid].EvalInt(b.ctx, event) 945 if err1 != nil { 946 err = err1 947 break 948 } 949 if isNull { 950 v = target 951 } 952 isUint2 := allegrosql.HasUnsignedFlag(args[mid].GetType().Flag) 953 switch { 954 case !isUint1 && !isUint2: 955 cmp = target < v 956 case isUint1 && isUint2: 957 cmp = uint64(target) < uint64(v) 958 case !isUint1 && isUint2: 959 cmp = target < 0 || uint64(target) < uint64(v) 960 case isUint1 && !isUint2: 961 cmp = v > 0 && uint64(target) < uint64(v) 962 } 963 if !cmp { 964 i = mid + 1 965 } else { 966 j = mid 967 } 968 } 969 return i, err 970 } 971 972 type builtinIntervalRealSig struct { 973 baseBuiltinFunc 974 hasNullable bool 975 } 976 977 func (b *builtinIntervalRealSig) Clone() builtinFunc { 978 newSig := &builtinIntervalRealSig{} 979 newSig.cloneFrom(&b.baseBuiltinFunc) 980 newSig.hasNullable = b.hasNullable 981 return newSig 982 } 983 984 // evalInt evals a builtinIntervalRealSig. 985 // See http://dev.allegrosql.com/doc/refman/5.7/en/comparison-operators.html#function_interval 986 func (b *builtinIntervalRealSig) evalInt(event chunk.Event) (int64, bool, error) { 987 arg0, isNull, err := b.args[0].EvalReal(b.ctx, event) 988 if err != nil { 989 return 0, true, err 990 } 991 if isNull { 992 return -1, false, nil 993 } 994 var idx int 995 if b.hasNullable { 996 idx, err = b.linearSearch(arg0, b.args[1:], event) 997 } else { 998 idx, err = b.binSearch(arg0, b.args[1:], event) 999 } 1000 return int64(idx), err != nil, err 1001 } 1002 1003 func (b *builtinIntervalRealSig) linearSearch(target float64, args []Expression, event chunk.Event) (i int, err error) { 1004 i = 0 1005 for ; i < len(args); i++ { 1006 arg, isNull, err := args[i].EvalReal(b.ctx, event) 1007 if err != nil { 1008 return 0, err 1009 } 1010 if !isNull && target < arg { 1011 break 1012 } 1013 } 1014 return i, nil 1015 } 1016 1017 func (b *builtinIntervalRealSig) binSearch(target float64, args []Expression, event chunk.Event) (_ int, err error) { 1018 i, j := 0, len(args) 1019 for i < j { 1020 mid := i + (j-i)/2 1021 v, isNull, err1 := args[mid].EvalReal(b.ctx, event) 1022 if err1 != nil { 1023 err = err1 1024 break 1025 } 1026 if isNull { 1027 i = mid + 1 1028 } else if cmp := target < v; !cmp { 1029 i = mid + 1 1030 } else { 1031 j = mid 1032 } 1033 } 1034 return i, err 1035 } 1036 1037 type compareFunctionClass struct { 1038 baseFunctionClass 1039 1040 op opcode.Op 1041 } 1042 1043 // getBaseCmpType gets the EvalType that the two args will be treated as when comparing. 1044 func getBaseCmpType(lhs, rhs types.EvalType, lft, rft *types.FieldType) types.EvalType { 1045 if lft.Tp == allegrosql.TypeUnspecified || rft.Tp == allegrosql.TypeUnspecified { 1046 if lft.Tp == rft.Tp { 1047 return types.ETString 1048 } 1049 if lft.Tp == allegrosql.TypeUnspecified { 1050 lhs = rhs 1051 } else { 1052 rhs = lhs 1053 } 1054 } 1055 if lhs.IsStringHoTT() && rhs.IsStringHoTT() { 1056 return types.ETString 1057 } else if (lhs == types.ETInt || lft.Hybrid()) && (rhs == types.ETInt || rft.Hybrid()) { 1058 return types.ETInt 1059 } else if ((lhs == types.ETInt || lft.Hybrid()) || lhs == types.ETDecimal) && 1060 ((rhs == types.ETInt || rft.Hybrid()) || rhs == types.ETDecimal) { 1061 return types.ETDecimal 1062 } 1063 return types.ETReal 1064 } 1065 1066 // GetAccurateCmpType uses a more complex logic to decide the EvalType of the two args when compare with each other than 1067 // getBaseCmpType does. 1068 func GetAccurateCmpType(lhs, rhs Expression) types.EvalType { 1069 lhsFieldType, rhsFieldType := lhs.GetType(), rhs.GetType() 1070 lhsEvalType, rhsEvalType := lhsFieldType.EvalType(), rhsFieldType.EvalType() 1071 cmpType := getBaseCmpType(lhsEvalType, rhsEvalType, lhsFieldType, rhsFieldType) 1072 if (lhsEvalType.IsStringHoTT() && rhsFieldType.Tp == allegrosql.TypeJSON) || 1073 (lhsFieldType.Tp == allegrosql.TypeJSON && rhsEvalType.IsStringHoTT()) { 1074 cmpType = types.ETJson 1075 } else if cmpType == types.ETString && (types.IsTypeTime(lhsFieldType.Tp) || types.IsTypeTime(rhsFieldType.Tp)) { 1076 // date[time] <cmp> date[time] 1077 // string <cmp> date[time] 1078 // compare as time 1079 if lhsFieldType.Tp == rhsFieldType.Tp { 1080 cmpType = lhsFieldType.EvalType() 1081 } else { 1082 cmpType = types.ETDatetime 1083 } 1084 } else if lhsFieldType.Tp == allegrosql.TypeDuration && rhsFieldType.Tp == allegrosql.TypeDuration { 1085 // duration <cmp> duration 1086 // compare as duration 1087 cmpType = types.ETDuration 1088 } else if cmpType == types.ETReal || cmpType == types.ETString { 1089 _, isLHSConst := lhs.(*Constant) 1090 _, isRHSConst := rhs.(*Constant) 1091 if (lhsEvalType == types.ETDecimal && !isLHSConst && rhsEvalType.IsStringHoTT() && isRHSConst) || 1092 (rhsEvalType == types.ETDecimal && !isRHSConst && lhsEvalType.IsStringHoTT() && isLHSConst) { 1093 /* 1094 <non-const decimal memex> <cmp> <const string memex> 1095 or 1096 <const string memex> <cmp> <non-const decimal memex> 1097 1098 Do comparison as decimal rather than float, in order not to lose precision. 1099 )*/ 1100 cmpType = types.ETDecimal 1101 } else if isTemporalDeferredCauset(lhs) && isRHSConst || 1102 isTemporalDeferredCauset(rhs) && isLHSConst { 1103 /* 1104 <temporal defCausumn> <cmp> <non-temporal constant> 1105 or 1106 <non-temporal constant> <cmp> <temporal defCausumn> 1107 1108 Convert the constant to temporal type. 1109 */ 1110 defCaus, isLHSDeferredCauset := lhs.(*DeferredCauset) 1111 if !isLHSDeferredCauset { 1112 defCaus = rhs.(*DeferredCauset) 1113 } 1114 if defCaus.GetType().Tp == allegrosql.TypeDuration { 1115 cmpType = types.ETDuration 1116 } else { 1117 cmpType = types.ETDatetime 1118 } 1119 } 1120 } 1121 return cmpType 1122 } 1123 1124 // GetCmpFunction get the compare function according to two arguments. 1125 func GetCmpFunction(ctx stochastikctx.Context, lhs, rhs Expression) CompareFunc { 1126 switch GetAccurateCmpType(lhs, rhs) { 1127 case types.ETInt: 1128 return CompareInt 1129 case types.ETReal: 1130 return CompareReal 1131 case types.ETDecimal: 1132 return CompareDecimal 1133 case types.ETString: 1134 _, dstDefCauslation := DeriveDefCauslationFromExprs(ctx, lhs, rhs) 1135 return genCompareString(dstDefCauslation) 1136 case types.ETDuration: 1137 return CompareDuration 1138 case types.ETDatetime, types.ETTimestamp: 1139 return CompareTime 1140 case types.ETJson: 1141 return CompareJSON 1142 } 1143 return nil 1144 } 1145 1146 // isTemporalDeferredCauset checks if a memex is a temporal defCausumn, 1147 // temporal defCausumn indicates time defCausumn or duration defCausumn. 1148 func isTemporalDeferredCauset(expr Expression) bool { 1149 ft := expr.GetType() 1150 if _, isDefCaus := expr.(*DeferredCauset); !isDefCaus { 1151 return false 1152 } 1153 if !types.IsTypeTime(ft.Tp) && ft.Tp != allegrosql.TypeDuration { 1154 return false 1155 } 1156 return true 1157 } 1158 1159 // tryToConvertConstantInt tries to convert a constant with other type to a int constant. 1160 // isExceptional indicates whether the 'int defCausumn [cmp] const' might be true/false. 1161 // If isExceptional is true, InterDircptionalVal is returned. Or, CorrectVal is returned. 1162 // CorrectVal: The computed result. If the constant can be converted to int without exception, return the val. Else return 'con'(the input). 1163 // ExceptionalVal : It is used to get more information to check whether 'int defCausumn [cmp] const' is true/false 1164 // If the op == LT,LE,GT,GE and it gets an Overflow when converting, return inf/-inf. 1165 // If the op == EQ,NullEQ and the constant can never be equal to the int defCausumn, return ‘con’(the input, a non-int constant). 1166 func tryToConvertConstantInt(ctx stochastikctx.Context, targetFieldType *types.FieldType, con *Constant) (_ *Constant, isExceptional bool) { 1167 if con.GetType().EvalType() == types.ETInt { 1168 return con, false 1169 } 1170 dt, err := con.Eval(chunk.Event{}) 1171 if err != nil { 1172 return con, false 1173 } 1174 sc := ctx.GetStochastikVars().StmtCtx 1175 1176 dt, err = dt.ConvertTo(sc, targetFieldType) 1177 if err != nil { 1178 if terror.ErrorEqual(err, types.ErrOverflow) { 1179 return &Constant{ 1180 Value: dt, 1181 RetType: targetFieldType, 1182 DeferredExpr: con.DeferredExpr, 1183 ParamMarker: con.ParamMarker, 1184 }, true 1185 } 1186 return con, false 1187 } 1188 return &Constant{ 1189 Value: dt, 1190 RetType: targetFieldType, 1191 DeferredExpr: con.DeferredExpr, 1192 ParamMarker: con.ParamMarker, 1193 }, false 1194 } 1195 1196 // RefineComparedConstant changes a non-integer constant argument to its ceiling or floor result by the given op. 1197 // isExceptional indicates whether the 'int defCausumn [cmp] const' might be true/false. 1198 // If isExceptional is true, InterDircptionalVal is returned. Or, CorrectVal is returned. 1199 // CorrectVal: The computed result. If the constant can be converted to int without exception, return the val. Else return 'con'(the input). 1200 // ExceptionalVal : It is used to get more information to check whether 'int defCausumn [cmp] const' is true/false 1201 // If the op == LT,LE,GT,GE and it gets an Overflow when converting, return inf/-inf. 1202 // If the op == EQ,NullEQ and the constant can never be equal to the int defCausumn, return ‘con’(the input, a non-int constant). 1203 func RefineComparedConstant(ctx stochastikctx.Context, targetFieldType types.FieldType, con *Constant, op opcode.Op) (_ *Constant, isExceptional bool) { 1204 dt, err := con.Eval(chunk.Event{}) 1205 if err != nil { 1206 return con, false 1207 } 1208 sc := ctx.GetStochastikVars().StmtCtx 1209 1210 if targetFieldType.Tp == allegrosql.TypeBit { 1211 targetFieldType = *types.NewFieldType(allegrosql.TypeLonglong) 1212 } 1213 var intCauset types.Causet 1214 intCauset, err = dt.ConvertTo(sc, &targetFieldType) 1215 if err != nil { 1216 if terror.ErrorEqual(err, types.ErrOverflow) { 1217 return &Constant{ 1218 Value: intCauset, 1219 RetType: &targetFieldType, 1220 DeferredExpr: con.DeferredExpr, 1221 ParamMarker: con.ParamMarker, 1222 }, true 1223 } 1224 return con, false 1225 } 1226 c, err := intCauset.CompareCauset(sc, &con.Value) 1227 if err != nil { 1228 return con, false 1229 } 1230 if c == 0 { 1231 return &Constant{ 1232 Value: intCauset, 1233 RetType: &targetFieldType, 1234 DeferredExpr: con.DeferredExpr, 1235 ParamMarker: con.ParamMarker, 1236 }, false 1237 } 1238 switch op { 1239 case opcode.LT, opcode.GE: 1240 resultExpr := NewFunctionInternal(ctx, ast.Ceil, types.NewFieldType(allegrosql.TypeUnspecified), con) 1241 if resultCon, ok := resultExpr.(*Constant); ok { 1242 return tryToConvertConstantInt(ctx, &targetFieldType, resultCon) 1243 } 1244 case opcode.LE, opcode.GT: 1245 resultExpr := NewFunctionInternal(ctx, ast.Floor, types.NewFieldType(allegrosql.TypeUnspecified), con) 1246 if resultCon, ok := resultExpr.(*Constant); ok { 1247 return tryToConvertConstantInt(ctx, &targetFieldType, resultCon) 1248 } 1249 case opcode.NullEQ, opcode.EQ: 1250 switch con.GetType().EvalType() { 1251 // An integer value equal or NULL-safe equal to a float value which contains 1252 // non-zero decimal digits is definitely false. 1253 // e.g., 1254 // 1. "integer = 1.1" is definitely false. 1255 // 2. "integer <=> 1.1" is definitely false. 1256 case types.ETReal, types.ETDecimal: 1257 return con, true 1258 case types.ETString: 1259 // We try to convert the string constant to double. 1260 // If the double result equals the int result, we can return the int result; 1261 // otherwise, the compare function will be false. 1262 var doubleCauset types.Causet 1263 doubleCauset, err = dt.ConvertTo(sc, types.NewFieldType(allegrosql.TypeDouble)) 1264 if err != nil { 1265 return con, false 1266 } 1267 if c, err = doubleCauset.CompareCauset(sc, &intCauset); err != nil { 1268 return con, false 1269 } 1270 if c != 0 { 1271 return con, true 1272 } 1273 return &Constant{ 1274 Value: intCauset, 1275 RetType: &targetFieldType, 1276 DeferredExpr: con.DeferredExpr, 1277 ParamMarker: con.ParamMarker, 1278 }, false 1279 } 1280 } 1281 return con, false 1282 } 1283 1284 // refineArgs will rewrite the arguments if the compare memex is `int defCausumn <cmp> non-int constant` or 1285 // `non-int constant <cmp> int defCausumn`. E.g., `a < 1.1` will be rewritten to `a < 2`. 1286 func (c *compareFunctionClass) refineArgs(ctx stochastikctx.Context, args []Expression) []Expression { 1287 if ContainMublockConst(ctx, args) { 1288 return args 1289 } 1290 arg0Type, arg1Type := args[0].GetType(), args[1].GetType() 1291 arg0IsInt := arg0Type.EvalType() == types.ETInt 1292 arg1IsInt := arg1Type.EvalType() == types.ETInt 1293 arg0, arg0IsCon := args[0].(*Constant) 1294 arg1, arg1IsCon := args[1].(*Constant) 1295 isExceptional, finalArg0, finalArg1 := false, args[0], args[1] 1296 isPositiveInfinite, isNegativeInfinite := false, false 1297 // int non-constant [cmp] non-int constant 1298 if arg0IsInt && !arg0IsCon && !arg1IsInt && arg1IsCon { 1299 arg1, isExceptional = RefineComparedConstant(ctx, *arg0Type, arg1, c.op) 1300 finalArg1 = arg1 1301 if isExceptional && arg1.GetType().EvalType() == types.ETInt { 1302 // Judge it is inf or -inf 1303 // For int: 1304 // inf: 01111111 & 1 == 1 1305 // -inf: 10000000 & 1 == 0 1306 // For uint: 1307 // inf: 11111111 & 1 == 1 1308 // -inf: 00000000 & 0 == 0 1309 if arg1.Value.GetInt64()&1 == 1 { 1310 isPositiveInfinite = true 1311 } else { 1312 isNegativeInfinite = true 1313 } 1314 } 1315 } 1316 // non-int constant [cmp] int non-constant 1317 if arg1IsInt && !arg1IsCon && !arg0IsInt && arg0IsCon { 1318 arg0, isExceptional = RefineComparedConstant(ctx, *arg1Type, arg0, symmetricOp[c.op]) 1319 finalArg0 = arg0 1320 if isExceptional && arg0.GetType().EvalType() == types.ETInt { 1321 if arg0.Value.GetInt64()&1 == 1 { 1322 isNegativeInfinite = true 1323 } else { 1324 isPositiveInfinite = true 1325 } 1326 } 1327 } 1328 if isExceptional && (c.op == opcode.EQ || c.op == opcode.NullEQ) { 1329 // This will always be false. 1330 return []Expression{NewZero(), NewOne()} 1331 } 1332 if isPositiveInfinite { 1333 // If the op is opcode.LT, opcode.LE 1334 // This will always be true. 1335 // If the op is opcode.GT, opcode.GE 1336 // This will always be false. 1337 return []Expression{NewZero(), NewOne()} 1338 } 1339 if isNegativeInfinite { 1340 // If the op is opcode.GT, opcode.GE 1341 // This will always be true. 1342 // If the op is opcode.LT, opcode.LE 1343 // This will always be false. 1344 return []Expression{NewOne(), NewZero()} 1345 } 1346 1347 return []Expression{finalArg0, finalArg1} 1348 } 1349 1350 // getFunction sets compare built-in function signatures for various types. 1351 func (c *compareFunctionClass) getFunction(ctx stochastikctx.Context, rawArgs []Expression) (sig builtinFunc, err error) { 1352 if err = c.verifyArgs(rawArgs); err != nil { 1353 return nil, err 1354 } 1355 args := c.refineArgs(ctx, rawArgs) 1356 cmpType := GetAccurateCmpType(args[0], args[1]) 1357 sig, err = c.generateCmpSigs(ctx, args, cmpType) 1358 return sig, err 1359 } 1360 1361 // generateCmpSigs generates compare function signatures. 1362 func (c *compareFunctionClass) generateCmpSigs(ctx stochastikctx.Context, args []Expression, tp types.EvalType) (sig builtinFunc, err error) { 1363 bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, tp, tp) 1364 if err != nil { 1365 return nil, err 1366 } 1367 if tp == types.ETJson { 1368 // In compare, if we cast string to JSON, we shouldn't parse it. 1369 for i := range args { 1370 DisableParseJSONFlag4Expr(args[i]) 1371 } 1372 } 1373 bf.tp.Flen = 1 1374 switch tp { 1375 case types.ETInt: 1376 switch c.op { 1377 case opcode.LT: 1378 sig = &builtinLTIntSig{bf} 1379 sig.setPbCode(fidelpb.ScalarFuncSig_LTInt) 1380 case opcode.LE: 1381 sig = &builtinLEIntSig{bf} 1382 sig.setPbCode(fidelpb.ScalarFuncSig_LEInt) 1383 case opcode.GT: 1384 sig = &builtinGTIntSig{bf} 1385 sig.setPbCode(fidelpb.ScalarFuncSig_GTInt) 1386 case opcode.EQ: 1387 sig = &builtinEQIntSig{bf} 1388 sig.setPbCode(fidelpb.ScalarFuncSig_EQInt) 1389 case opcode.GE: 1390 sig = &builtinGEIntSig{bf} 1391 sig.setPbCode(fidelpb.ScalarFuncSig_GEInt) 1392 case opcode.NE: 1393 sig = &builtinNEIntSig{bf} 1394 sig.setPbCode(fidelpb.ScalarFuncSig_NEInt) 1395 case opcode.NullEQ: 1396 sig = &builtinNullEQIntSig{bf} 1397 sig.setPbCode(fidelpb.ScalarFuncSig_NullEQInt) 1398 } 1399 case types.ETReal: 1400 switch c.op { 1401 case opcode.LT: 1402 sig = &builtinLTRealSig{bf} 1403 sig.setPbCode(fidelpb.ScalarFuncSig_LTReal) 1404 case opcode.LE: 1405 sig = &builtinLERealSig{bf} 1406 sig.setPbCode(fidelpb.ScalarFuncSig_LEReal) 1407 case opcode.GT: 1408 sig = &builtinGTRealSig{bf} 1409 sig.setPbCode(fidelpb.ScalarFuncSig_GTReal) 1410 case opcode.GE: 1411 sig = &builtinGERealSig{bf} 1412 sig.setPbCode(fidelpb.ScalarFuncSig_GEReal) 1413 case opcode.EQ: 1414 sig = &builtinEQRealSig{bf} 1415 sig.setPbCode(fidelpb.ScalarFuncSig_EQReal) 1416 case opcode.NE: 1417 sig = &builtinNERealSig{bf} 1418 sig.setPbCode(fidelpb.ScalarFuncSig_NEReal) 1419 case opcode.NullEQ: 1420 sig = &builtinNullEQRealSig{bf} 1421 sig.setPbCode(fidelpb.ScalarFuncSig_NullEQReal) 1422 } 1423 case types.ETDecimal: 1424 switch c.op { 1425 case opcode.LT: 1426 sig = &builtinLTDecimalSig{bf} 1427 sig.setPbCode(fidelpb.ScalarFuncSig_LTDecimal) 1428 case opcode.LE: 1429 sig = &builtinLEDecimalSig{bf} 1430 sig.setPbCode(fidelpb.ScalarFuncSig_LEDecimal) 1431 case opcode.GT: 1432 sig = &builtinGTDecimalSig{bf} 1433 sig.setPbCode(fidelpb.ScalarFuncSig_GTDecimal) 1434 case opcode.GE: 1435 sig = &builtinGEDecimalSig{bf} 1436 sig.setPbCode(fidelpb.ScalarFuncSig_GEDecimal) 1437 case opcode.EQ: 1438 sig = &builtinEQDecimalSig{bf} 1439 sig.setPbCode(fidelpb.ScalarFuncSig_EQDecimal) 1440 case opcode.NE: 1441 sig = &builtinNEDecimalSig{bf} 1442 sig.setPbCode(fidelpb.ScalarFuncSig_NEDecimal) 1443 case opcode.NullEQ: 1444 sig = &builtinNullEQDecimalSig{bf} 1445 sig.setPbCode(fidelpb.ScalarFuncSig_NullEQDecimal) 1446 } 1447 case types.ETString: 1448 switch c.op { 1449 case opcode.LT: 1450 sig = &builtinLTStringSig{bf} 1451 sig.setPbCode(fidelpb.ScalarFuncSig_LTString) 1452 case opcode.LE: 1453 sig = &builtinLEStringSig{bf} 1454 sig.setPbCode(fidelpb.ScalarFuncSig_LEString) 1455 case opcode.GT: 1456 sig = &builtinGTStringSig{bf} 1457 sig.setPbCode(fidelpb.ScalarFuncSig_GTString) 1458 case opcode.GE: 1459 sig = &builtinGEStringSig{bf} 1460 sig.setPbCode(fidelpb.ScalarFuncSig_GEString) 1461 case opcode.EQ: 1462 sig = &builtinEQStringSig{bf} 1463 sig.setPbCode(fidelpb.ScalarFuncSig_EQString) 1464 case opcode.NE: 1465 sig = &builtinNEStringSig{bf} 1466 sig.setPbCode(fidelpb.ScalarFuncSig_NEString) 1467 case opcode.NullEQ: 1468 sig = &builtinNullEQStringSig{bf} 1469 sig.setPbCode(fidelpb.ScalarFuncSig_NullEQString) 1470 } 1471 case types.ETDuration: 1472 switch c.op { 1473 case opcode.LT: 1474 sig = &builtinLTDurationSig{bf} 1475 sig.setPbCode(fidelpb.ScalarFuncSig_LTDuration) 1476 case opcode.LE: 1477 sig = &builtinLEDurationSig{bf} 1478 sig.setPbCode(fidelpb.ScalarFuncSig_LEDuration) 1479 case opcode.GT: 1480 sig = &builtinGTDurationSig{bf} 1481 sig.setPbCode(fidelpb.ScalarFuncSig_GTDuration) 1482 case opcode.GE: 1483 sig = &builtinGEDurationSig{bf} 1484 sig.setPbCode(fidelpb.ScalarFuncSig_GEDuration) 1485 case opcode.EQ: 1486 sig = &builtinEQDurationSig{bf} 1487 sig.setPbCode(fidelpb.ScalarFuncSig_EQDuration) 1488 case opcode.NE: 1489 sig = &builtinNEDurationSig{bf} 1490 sig.setPbCode(fidelpb.ScalarFuncSig_NEDuration) 1491 case opcode.NullEQ: 1492 sig = &builtinNullEQDurationSig{bf} 1493 sig.setPbCode(fidelpb.ScalarFuncSig_NullEQDuration) 1494 } 1495 case types.ETDatetime, types.ETTimestamp: 1496 switch c.op { 1497 case opcode.LT: 1498 sig = &builtinLTTimeSig{bf} 1499 sig.setPbCode(fidelpb.ScalarFuncSig_LTTime) 1500 case opcode.LE: 1501 sig = &builtinLETimeSig{bf} 1502 sig.setPbCode(fidelpb.ScalarFuncSig_LETime) 1503 case opcode.GT: 1504 sig = &builtinGTTimeSig{bf} 1505 sig.setPbCode(fidelpb.ScalarFuncSig_GTTime) 1506 case opcode.GE: 1507 sig = &builtinGETimeSig{bf} 1508 sig.setPbCode(fidelpb.ScalarFuncSig_GETime) 1509 case opcode.EQ: 1510 sig = &builtinEQTimeSig{bf} 1511 sig.setPbCode(fidelpb.ScalarFuncSig_EQTime) 1512 case opcode.NE: 1513 sig = &builtinNETimeSig{bf} 1514 sig.setPbCode(fidelpb.ScalarFuncSig_NETime) 1515 case opcode.NullEQ: 1516 sig = &builtinNullEQTimeSig{bf} 1517 sig.setPbCode(fidelpb.ScalarFuncSig_NullEQTime) 1518 } 1519 case types.ETJson: 1520 switch c.op { 1521 case opcode.LT: 1522 sig = &builtinLTJSONSig{bf} 1523 sig.setPbCode(fidelpb.ScalarFuncSig_LTJson) 1524 case opcode.LE: 1525 sig = &builtinLEJSONSig{bf} 1526 sig.setPbCode(fidelpb.ScalarFuncSig_LEJson) 1527 case opcode.GT: 1528 sig = &builtinGTJSONSig{bf} 1529 sig.setPbCode(fidelpb.ScalarFuncSig_GTJson) 1530 case opcode.GE: 1531 sig = &builtinGEJSONSig{bf} 1532 sig.setPbCode(fidelpb.ScalarFuncSig_GEJson) 1533 case opcode.EQ: 1534 sig = &builtinEQJSONSig{bf} 1535 sig.setPbCode(fidelpb.ScalarFuncSig_EQJson) 1536 case opcode.NE: 1537 sig = &builtinNEJSONSig{bf} 1538 sig.setPbCode(fidelpb.ScalarFuncSig_NEJson) 1539 case opcode.NullEQ: 1540 sig = &builtinNullEQJSONSig{bf} 1541 sig.setPbCode(fidelpb.ScalarFuncSig_NullEQJson) 1542 } 1543 } 1544 return 1545 } 1546 1547 type builtinLTIntSig struct { 1548 baseBuiltinFunc 1549 } 1550 1551 func (b *builtinLTIntSig) Clone() builtinFunc { 1552 newSig := &builtinLTIntSig{} 1553 newSig.cloneFrom(&b.baseBuiltinFunc) 1554 return newSig 1555 } 1556 1557 func (b *builtinLTIntSig) evalIntWithCtx(ctx stochastikctx.Context, event chunk.Event) (val int64, isNull bool, err error) { 1558 return resOfLT(CompareInt(ctx, b.args[0], b.args[1], event, event)) 1559 } 1560 1561 func (b *builtinLTIntSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1562 return resOfLT(CompareInt(b.ctx, b.args[0], b.args[1], event, event)) 1563 } 1564 1565 type builtinLTRealSig struct { 1566 baseBuiltinFunc 1567 } 1568 1569 func (b *builtinLTRealSig) Clone() builtinFunc { 1570 newSig := &builtinLTRealSig{} 1571 newSig.cloneFrom(&b.baseBuiltinFunc) 1572 return newSig 1573 } 1574 1575 func (b *builtinLTRealSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1576 return resOfLT(CompareReal(b.ctx, b.args[0], b.args[1], event, event)) 1577 } 1578 1579 type builtinLTDecimalSig struct { 1580 baseBuiltinFunc 1581 } 1582 1583 func (b *builtinLTDecimalSig) Clone() builtinFunc { 1584 newSig := &builtinLTDecimalSig{} 1585 newSig.cloneFrom(&b.baseBuiltinFunc) 1586 return newSig 1587 } 1588 1589 func (b *builtinLTDecimalSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1590 return resOfLT(CompareDecimal(b.ctx, b.args[0], b.args[1], event, event)) 1591 } 1592 1593 type builtinLTStringSig struct { 1594 baseBuiltinFunc 1595 } 1596 1597 func (b *builtinLTStringSig) Clone() builtinFunc { 1598 newSig := &builtinLTStringSig{} 1599 newSig.cloneFrom(&b.baseBuiltinFunc) 1600 return newSig 1601 } 1602 1603 func (b *builtinLTStringSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1604 return resOfLT(CompareStringWithDefCauslationInfo(b.ctx, b.args[0], b.args[1], event, event, b.defCauslation)) 1605 } 1606 1607 type builtinLTDurationSig struct { 1608 baseBuiltinFunc 1609 } 1610 1611 func (b *builtinLTDurationSig) Clone() builtinFunc { 1612 newSig := &builtinLTDurationSig{} 1613 newSig.cloneFrom(&b.baseBuiltinFunc) 1614 return newSig 1615 } 1616 1617 func (b *builtinLTDurationSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1618 return resOfLT(CompareDuration(b.ctx, b.args[0], b.args[1], event, event)) 1619 } 1620 1621 type builtinLTTimeSig struct { 1622 baseBuiltinFunc 1623 } 1624 1625 func (b *builtinLTTimeSig) Clone() builtinFunc { 1626 newSig := &builtinLTTimeSig{} 1627 newSig.cloneFrom(&b.baseBuiltinFunc) 1628 return newSig 1629 } 1630 1631 func (b *builtinLTTimeSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1632 return resOfLT(CompareTime(b.ctx, b.args[0], b.args[1], event, event)) 1633 } 1634 1635 type builtinLTJSONSig struct { 1636 baseBuiltinFunc 1637 } 1638 1639 func (b *builtinLTJSONSig) Clone() builtinFunc { 1640 newSig := &builtinLTJSONSig{} 1641 newSig.cloneFrom(&b.baseBuiltinFunc) 1642 return newSig 1643 } 1644 1645 func (b *builtinLTJSONSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1646 return resOfLT(CompareJSON(b.ctx, b.args[0], b.args[1], event, event)) 1647 } 1648 1649 type builtinLEIntSig struct { 1650 baseBuiltinFunc 1651 } 1652 1653 func (b *builtinLEIntSig) Clone() builtinFunc { 1654 newSig := &builtinLEIntSig{} 1655 newSig.cloneFrom(&b.baseBuiltinFunc) 1656 return newSig 1657 } 1658 1659 func (b *builtinLEIntSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1660 return resOfLE(CompareInt(b.ctx, b.args[0], b.args[1], event, event)) 1661 } 1662 1663 type builtinLERealSig struct { 1664 baseBuiltinFunc 1665 } 1666 1667 func (b *builtinLERealSig) Clone() builtinFunc { 1668 newSig := &builtinLERealSig{} 1669 newSig.cloneFrom(&b.baseBuiltinFunc) 1670 return newSig 1671 } 1672 1673 func (b *builtinLERealSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1674 return resOfLE(CompareReal(b.ctx, b.args[0], b.args[1], event, event)) 1675 } 1676 1677 type builtinLEDecimalSig struct { 1678 baseBuiltinFunc 1679 } 1680 1681 func (b *builtinLEDecimalSig) Clone() builtinFunc { 1682 newSig := &builtinLEDecimalSig{} 1683 newSig.cloneFrom(&b.baseBuiltinFunc) 1684 return newSig 1685 } 1686 1687 func (b *builtinLEDecimalSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1688 return resOfLE(CompareDecimal(b.ctx, b.args[0], b.args[1], event, event)) 1689 } 1690 1691 type builtinLEStringSig struct { 1692 baseBuiltinFunc 1693 } 1694 1695 func (b *builtinLEStringSig) Clone() builtinFunc { 1696 newSig := &builtinLEStringSig{} 1697 newSig.cloneFrom(&b.baseBuiltinFunc) 1698 return newSig 1699 } 1700 1701 func (b *builtinLEStringSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1702 return resOfLE(CompareStringWithDefCauslationInfo(b.ctx, b.args[0], b.args[1], event, event, b.defCauslation)) 1703 } 1704 1705 type builtinLEDurationSig struct { 1706 baseBuiltinFunc 1707 } 1708 1709 func (b *builtinLEDurationSig) Clone() builtinFunc { 1710 newSig := &builtinLEDurationSig{} 1711 newSig.cloneFrom(&b.baseBuiltinFunc) 1712 return newSig 1713 } 1714 1715 func (b *builtinLEDurationSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1716 return resOfLE(CompareDuration(b.ctx, b.args[0], b.args[1], event, event)) 1717 } 1718 1719 type builtinLETimeSig struct { 1720 baseBuiltinFunc 1721 } 1722 1723 func (b *builtinLETimeSig) Clone() builtinFunc { 1724 newSig := &builtinLETimeSig{} 1725 newSig.cloneFrom(&b.baseBuiltinFunc) 1726 return newSig 1727 } 1728 1729 func (b *builtinLETimeSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1730 return resOfLE(CompareTime(b.ctx, b.args[0], b.args[1], event, event)) 1731 } 1732 1733 type builtinLEJSONSig struct { 1734 baseBuiltinFunc 1735 } 1736 1737 func (b *builtinLEJSONSig) Clone() builtinFunc { 1738 newSig := &builtinLEJSONSig{} 1739 newSig.cloneFrom(&b.baseBuiltinFunc) 1740 return newSig 1741 } 1742 1743 func (b *builtinLEJSONSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1744 return resOfLE(CompareJSON(b.ctx, b.args[0], b.args[1], event, event)) 1745 } 1746 1747 type builtinGTIntSig struct { 1748 baseBuiltinFunc 1749 } 1750 1751 func (b *builtinGTIntSig) Clone() builtinFunc { 1752 newSig := &builtinGTIntSig{} 1753 newSig.cloneFrom(&b.baseBuiltinFunc) 1754 return newSig 1755 } 1756 1757 func (b *builtinGTIntSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1758 return resOfGT(CompareInt(b.ctx, b.args[0], b.args[1], event, event)) 1759 } 1760 1761 type builtinGTRealSig struct { 1762 baseBuiltinFunc 1763 } 1764 1765 func (b *builtinGTRealSig) Clone() builtinFunc { 1766 newSig := &builtinGTRealSig{} 1767 newSig.cloneFrom(&b.baseBuiltinFunc) 1768 return newSig 1769 } 1770 1771 func (b *builtinGTRealSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1772 return resOfGT(CompareReal(b.ctx, b.args[0], b.args[1], event, event)) 1773 } 1774 1775 type builtinGTDecimalSig struct { 1776 baseBuiltinFunc 1777 } 1778 1779 func (b *builtinGTDecimalSig) Clone() builtinFunc { 1780 newSig := &builtinGTDecimalSig{} 1781 newSig.cloneFrom(&b.baseBuiltinFunc) 1782 return newSig 1783 } 1784 1785 func (b *builtinGTDecimalSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1786 return resOfGT(CompareDecimal(b.ctx, b.args[0], b.args[1], event, event)) 1787 } 1788 1789 type builtinGTStringSig struct { 1790 baseBuiltinFunc 1791 } 1792 1793 func (b *builtinGTStringSig) Clone() builtinFunc { 1794 newSig := &builtinGTStringSig{} 1795 newSig.cloneFrom(&b.baseBuiltinFunc) 1796 return newSig 1797 } 1798 1799 func (b *builtinGTStringSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1800 return resOfGT(CompareStringWithDefCauslationInfo(b.ctx, b.args[0], b.args[1], event, event, b.defCauslation)) 1801 } 1802 1803 type builtinGTDurationSig struct { 1804 baseBuiltinFunc 1805 } 1806 1807 func (b *builtinGTDurationSig) Clone() builtinFunc { 1808 newSig := &builtinGTDurationSig{} 1809 newSig.cloneFrom(&b.baseBuiltinFunc) 1810 return newSig 1811 } 1812 1813 func (b *builtinGTDurationSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1814 return resOfGT(CompareDuration(b.ctx, b.args[0], b.args[1], event, event)) 1815 } 1816 1817 type builtinGTTimeSig struct { 1818 baseBuiltinFunc 1819 } 1820 1821 func (b *builtinGTTimeSig) Clone() builtinFunc { 1822 newSig := &builtinGTTimeSig{} 1823 newSig.cloneFrom(&b.baseBuiltinFunc) 1824 return newSig 1825 } 1826 1827 func (b *builtinGTTimeSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1828 return resOfGT(CompareTime(b.ctx, b.args[0], b.args[1], event, event)) 1829 } 1830 1831 type builtinGTJSONSig struct { 1832 baseBuiltinFunc 1833 } 1834 1835 func (b *builtinGTJSONSig) Clone() builtinFunc { 1836 newSig := &builtinGTJSONSig{} 1837 newSig.cloneFrom(&b.baseBuiltinFunc) 1838 return newSig 1839 } 1840 1841 func (b *builtinGTJSONSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1842 return resOfGT(CompareJSON(b.ctx, b.args[0], b.args[1], event, event)) 1843 } 1844 1845 type builtinGEIntSig struct { 1846 baseBuiltinFunc 1847 } 1848 1849 func (b *builtinGEIntSig) Clone() builtinFunc { 1850 newSig := &builtinGEIntSig{} 1851 newSig.cloneFrom(&b.baseBuiltinFunc) 1852 return newSig 1853 } 1854 1855 func (b *builtinGEIntSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1856 return resOfGE(CompareInt(b.ctx, b.args[0], b.args[1], event, event)) 1857 } 1858 1859 type builtinGERealSig struct { 1860 baseBuiltinFunc 1861 } 1862 1863 func (b *builtinGERealSig) Clone() builtinFunc { 1864 newSig := &builtinGERealSig{} 1865 newSig.cloneFrom(&b.baseBuiltinFunc) 1866 return newSig 1867 } 1868 1869 func (b *builtinGERealSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1870 return resOfGE(CompareReal(b.ctx, b.args[0], b.args[1], event, event)) 1871 } 1872 1873 type builtinGEDecimalSig struct { 1874 baseBuiltinFunc 1875 } 1876 1877 func (b *builtinGEDecimalSig) Clone() builtinFunc { 1878 newSig := &builtinGEDecimalSig{} 1879 newSig.cloneFrom(&b.baseBuiltinFunc) 1880 return newSig 1881 } 1882 1883 func (b *builtinGEDecimalSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1884 return resOfGE(CompareDecimal(b.ctx, b.args[0], b.args[1], event, event)) 1885 } 1886 1887 type builtinGEStringSig struct { 1888 baseBuiltinFunc 1889 } 1890 1891 func (b *builtinGEStringSig) Clone() builtinFunc { 1892 newSig := &builtinGEStringSig{} 1893 newSig.cloneFrom(&b.baseBuiltinFunc) 1894 return newSig 1895 } 1896 1897 func (b *builtinGEStringSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1898 return resOfGE(CompareStringWithDefCauslationInfo(b.ctx, b.args[0], b.args[1], event, event, b.defCauslation)) 1899 } 1900 1901 type builtinGEDurationSig struct { 1902 baseBuiltinFunc 1903 } 1904 1905 func (b *builtinGEDurationSig) Clone() builtinFunc { 1906 newSig := &builtinGEDurationSig{} 1907 newSig.cloneFrom(&b.baseBuiltinFunc) 1908 return newSig 1909 } 1910 1911 func (b *builtinGEDurationSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1912 return resOfGE(CompareDuration(b.ctx, b.args[0], b.args[1], event, event)) 1913 } 1914 1915 type builtinGETimeSig struct { 1916 baseBuiltinFunc 1917 } 1918 1919 func (b *builtinGETimeSig) Clone() builtinFunc { 1920 newSig := &builtinGETimeSig{} 1921 newSig.cloneFrom(&b.baseBuiltinFunc) 1922 return newSig 1923 } 1924 1925 func (b *builtinGETimeSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1926 return resOfGE(CompareTime(b.ctx, b.args[0], b.args[1], event, event)) 1927 } 1928 1929 type builtinGEJSONSig struct { 1930 baseBuiltinFunc 1931 } 1932 1933 func (b *builtinGEJSONSig) Clone() builtinFunc { 1934 newSig := &builtinGEJSONSig{} 1935 newSig.cloneFrom(&b.baseBuiltinFunc) 1936 return newSig 1937 } 1938 1939 func (b *builtinGEJSONSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1940 return resOfGE(CompareJSON(b.ctx, b.args[0], b.args[1], event, event)) 1941 } 1942 1943 type builtinEQIntSig struct { 1944 baseBuiltinFunc 1945 } 1946 1947 func (b *builtinEQIntSig) Clone() builtinFunc { 1948 newSig := &builtinEQIntSig{} 1949 newSig.cloneFrom(&b.baseBuiltinFunc) 1950 return newSig 1951 } 1952 1953 func (b *builtinEQIntSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1954 return resOfEQ(CompareInt(b.ctx, b.args[0], b.args[1], event, event)) 1955 } 1956 1957 type builtinEQRealSig struct { 1958 baseBuiltinFunc 1959 } 1960 1961 func (b *builtinEQRealSig) Clone() builtinFunc { 1962 newSig := &builtinEQRealSig{} 1963 newSig.cloneFrom(&b.baseBuiltinFunc) 1964 return newSig 1965 } 1966 1967 func (b *builtinEQRealSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1968 return resOfEQ(CompareReal(b.ctx, b.args[0], b.args[1], event, event)) 1969 } 1970 1971 type builtinEQDecimalSig struct { 1972 baseBuiltinFunc 1973 } 1974 1975 func (b *builtinEQDecimalSig) Clone() builtinFunc { 1976 newSig := &builtinEQDecimalSig{} 1977 newSig.cloneFrom(&b.baseBuiltinFunc) 1978 return newSig 1979 } 1980 1981 func (b *builtinEQDecimalSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1982 return resOfEQ(CompareDecimal(b.ctx, b.args[0], b.args[1], event, event)) 1983 } 1984 1985 type builtinEQStringSig struct { 1986 baseBuiltinFunc 1987 } 1988 1989 func (b *builtinEQStringSig) Clone() builtinFunc { 1990 newSig := &builtinEQStringSig{} 1991 newSig.cloneFrom(&b.baseBuiltinFunc) 1992 return newSig 1993 } 1994 1995 func (b *builtinEQStringSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 1996 return resOfEQ(CompareStringWithDefCauslationInfo(b.ctx, b.args[0], b.args[1], event, event, b.defCauslation)) 1997 } 1998 1999 type builtinEQDurationSig struct { 2000 baseBuiltinFunc 2001 } 2002 2003 func (b *builtinEQDurationSig) Clone() builtinFunc { 2004 newSig := &builtinEQDurationSig{} 2005 newSig.cloneFrom(&b.baseBuiltinFunc) 2006 return newSig 2007 } 2008 2009 func (b *builtinEQDurationSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2010 return resOfEQ(CompareDuration(b.ctx, b.args[0], b.args[1], event, event)) 2011 } 2012 2013 type builtinEQTimeSig struct { 2014 baseBuiltinFunc 2015 } 2016 2017 func (b *builtinEQTimeSig) Clone() builtinFunc { 2018 newSig := &builtinEQTimeSig{} 2019 newSig.cloneFrom(&b.baseBuiltinFunc) 2020 return newSig 2021 } 2022 2023 func (b *builtinEQTimeSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2024 return resOfEQ(CompareTime(b.ctx, b.args[0], b.args[1], event, event)) 2025 } 2026 2027 type builtinEQJSONSig struct { 2028 baseBuiltinFunc 2029 } 2030 2031 func (b *builtinEQJSONSig) Clone() builtinFunc { 2032 newSig := &builtinEQJSONSig{} 2033 newSig.cloneFrom(&b.baseBuiltinFunc) 2034 return newSig 2035 } 2036 2037 func (b *builtinEQJSONSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2038 return resOfEQ(CompareJSON(b.ctx, b.args[0], b.args[1], event, event)) 2039 } 2040 2041 type builtinNEIntSig struct { 2042 baseBuiltinFunc 2043 } 2044 2045 func (b *builtinNEIntSig) Clone() builtinFunc { 2046 newSig := &builtinNEIntSig{} 2047 newSig.cloneFrom(&b.baseBuiltinFunc) 2048 return newSig 2049 } 2050 2051 func (b *builtinNEIntSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2052 return resOfNE(CompareInt(b.ctx, b.args[0], b.args[1], event, event)) 2053 } 2054 2055 type builtinNERealSig struct { 2056 baseBuiltinFunc 2057 } 2058 2059 func (b *builtinNERealSig) Clone() builtinFunc { 2060 newSig := &builtinNERealSig{} 2061 newSig.cloneFrom(&b.baseBuiltinFunc) 2062 return newSig 2063 } 2064 2065 func (b *builtinNERealSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2066 return resOfNE(CompareReal(b.ctx, b.args[0], b.args[1], event, event)) 2067 } 2068 2069 type builtinNEDecimalSig struct { 2070 baseBuiltinFunc 2071 } 2072 2073 func (b *builtinNEDecimalSig) Clone() builtinFunc { 2074 newSig := &builtinNEDecimalSig{} 2075 newSig.cloneFrom(&b.baseBuiltinFunc) 2076 return newSig 2077 } 2078 2079 func (b *builtinNEDecimalSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2080 return resOfNE(CompareDecimal(b.ctx, b.args[0], b.args[1], event, event)) 2081 } 2082 2083 type builtinNEStringSig struct { 2084 baseBuiltinFunc 2085 } 2086 2087 func (b *builtinNEStringSig) Clone() builtinFunc { 2088 newSig := &builtinNEStringSig{} 2089 newSig.cloneFrom(&b.baseBuiltinFunc) 2090 return newSig 2091 } 2092 2093 func (b *builtinNEStringSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2094 return resOfNE(CompareStringWithDefCauslationInfo(b.ctx, b.args[0], b.args[1], event, event, b.defCauslation)) 2095 } 2096 2097 type builtinNEDurationSig struct { 2098 baseBuiltinFunc 2099 } 2100 2101 func (b *builtinNEDurationSig) Clone() builtinFunc { 2102 newSig := &builtinNEDurationSig{} 2103 newSig.cloneFrom(&b.baseBuiltinFunc) 2104 return newSig 2105 } 2106 2107 func (b *builtinNEDurationSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2108 return resOfNE(CompareDuration(b.ctx, b.args[0], b.args[1], event, event)) 2109 } 2110 2111 type builtinNETimeSig struct { 2112 baseBuiltinFunc 2113 } 2114 2115 func (b *builtinNETimeSig) Clone() builtinFunc { 2116 newSig := &builtinNETimeSig{} 2117 newSig.cloneFrom(&b.baseBuiltinFunc) 2118 return newSig 2119 } 2120 2121 func (b *builtinNETimeSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2122 return resOfNE(CompareTime(b.ctx, b.args[0], b.args[1], event, event)) 2123 } 2124 2125 type builtinNEJSONSig struct { 2126 baseBuiltinFunc 2127 } 2128 2129 func (b *builtinNEJSONSig) Clone() builtinFunc { 2130 newSig := &builtinNEJSONSig{} 2131 newSig.cloneFrom(&b.baseBuiltinFunc) 2132 return newSig 2133 } 2134 2135 func (b *builtinNEJSONSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2136 return resOfNE(CompareJSON(b.ctx, b.args[0], b.args[1], event, event)) 2137 } 2138 2139 type builtinNullEQIntSig struct { 2140 baseBuiltinFunc 2141 } 2142 2143 func (b *builtinNullEQIntSig) Clone() builtinFunc { 2144 newSig := &builtinNullEQIntSig{} 2145 newSig.cloneFrom(&b.baseBuiltinFunc) 2146 return newSig 2147 } 2148 2149 func (b *builtinNullEQIntSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2150 arg0, isNull0, err := b.args[0].EvalInt(b.ctx, event) 2151 if err != nil { 2152 return 0, isNull0, err 2153 } 2154 arg1, isNull1, err := b.args[1].EvalInt(b.ctx, event) 2155 if err != nil { 2156 return 0, isNull1, err 2157 } 2158 isUnsigned0, isUnsigned1 := allegrosql.HasUnsignedFlag(b.args[0].GetType().Flag), allegrosql.HasUnsignedFlag(b.args[1].GetType().Flag) 2159 var res int64 2160 switch { 2161 case isNull0 && isNull1: 2162 res = 1 2163 case isNull0 != isNull1: 2164 break 2165 case isUnsigned0 && isUnsigned1 && types.CompareUint64(uint64(arg0), uint64(arg1)) == 0: 2166 res = 1 2167 case !isUnsigned0 && !isUnsigned1 && types.CompareInt64(arg0, arg1) == 0: 2168 res = 1 2169 case isUnsigned0 && !isUnsigned1: 2170 if arg1 < 0 { 2171 break 2172 } 2173 if types.CompareInt64(arg0, arg1) == 0 { 2174 res = 1 2175 } 2176 case !isUnsigned0 && isUnsigned1: 2177 if arg0 < 0 { 2178 break 2179 } 2180 if types.CompareInt64(arg0, arg1) == 0 { 2181 res = 1 2182 } 2183 } 2184 return res, false, nil 2185 } 2186 2187 type builtinNullEQRealSig struct { 2188 baseBuiltinFunc 2189 } 2190 2191 func (b *builtinNullEQRealSig) Clone() builtinFunc { 2192 newSig := &builtinNullEQRealSig{} 2193 newSig.cloneFrom(&b.baseBuiltinFunc) 2194 return newSig 2195 } 2196 2197 func (b *builtinNullEQRealSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2198 arg0, isNull0, err := b.args[0].EvalReal(b.ctx, event) 2199 if err != nil { 2200 return 0, true, err 2201 } 2202 arg1, isNull1, err := b.args[1].EvalReal(b.ctx, event) 2203 if err != nil { 2204 return 0, true, err 2205 } 2206 var res int64 2207 switch { 2208 case isNull0 && isNull1: 2209 res = 1 2210 case isNull0 != isNull1: 2211 break 2212 case types.CompareFloat64(arg0, arg1) == 0: 2213 res = 1 2214 } 2215 return res, false, nil 2216 } 2217 2218 type builtinNullEQDecimalSig struct { 2219 baseBuiltinFunc 2220 } 2221 2222 func (b *builtinNullEQDecimalSig) Clone() builtinFunc { 2223 newSig := &builtinNullEQDecimalSig{} 2224 newSig.cloneFrom(&b.baseBuiltinFunc) 2225 return newSig 2226 } 2227 2228 func (b *builtinNullEQDecimalSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2229 arg0, isNull0, err := b.args[0].EvalDecimal(b.ctx, event) 2230 if err != nil { 2231 return 0, true, err 2232 } 2233 arg1, isNull1, err := b.args[1].EvalDecimal(b.ctx, event) 2234 if err != nil { 2235 return 0, true, err 2236 } 2237 var res int64 2238 switch { 2239 case isNull0 && isNull1: 2240 res = 1 2241 case isNull0 != isNull1: 2242 break 2243 case arg0.Compare(arg1) == 0: 2244 res = 1 2245 } 2246 return res, false, nil 2247 } 2248 2249 type builtinNullEQStringSig struct { 2250 baseBuiltinFunc 2251 } 2252 2253 func (b *builtinNullEQStringSig) Clone() builtinFunc { 2254 newSig := &builtinNullEQStringSig{} 2255 newSig.cloneFrom(&b.baseBuiltinFunc) 2256 return newSig 2257 } 2258 2259 func (b *builtinNullEQStringSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2260 arg0, isNull0, err := b.args[0].EvalString(b.ctx, event) 2261 if err != nil { 2262 return 0, true, err 2263 } 2264 arg1, isNull1, err := b.args[1].EvalString(b.ctx, event) 2265 if err != nil { 2266 return 0, true, err 2267 } 2268 var res int64 2269 switch { 2270 case isNull0 && isNull1: 2271 res = 1 2272 case isNull0 != isNull1: 2273 break 2274 case types.CompareString(arg0, arg1, b.defCauslation) == 0: 2275 res = 1 2276 } 2277 return res, false, nil 2278 } 2279 2280 type builtinNullEQDurationSig struct { 2281 baseBuiltinFunc 2282 } 2283 2284 func (b *builtinNullEQDurationSig) Clone() builtinFunc { 2285 newSig := &builtinNullEQDurationSig{} 2286 newSig.cloneFrom(&b.baseBuiltinFunc) 2287 return newSig 2288 } 2289 2290 func (b *builtinNullEQDurationSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2291 arg0, isNull0, err := b.args[0].EvalDuration(b.ctx, event) 2292 if err != nil { 2293 return 0, true, err 2294 } 2295 arg1, isNull1, err := b.args[1].EvalDuration(b.ctx, event) 2296 if err != nil { 2297 return 0, true, err 2298 } 2299 var res int64 2300 switch { 2301 case isNull0 && isNull1: 2302 res = 1 2303 case isNull0 != isNull1: 2304 break 2305 case arg0.Compare(arg1) == 0: 2306 res = 1 2307 } 2308 return res, false, nil 2309 } 2310 2311 type builtinNullEQTimeSig struct { 2312 baseBuiltinFunc 2313 } 2314 2315 func (b *builtinNullEQTimeSig) Clone() builtinFunc { 2316 newSig := &builtinNullEQTimeSig{} 2317 newSig.cloneFrom(&b.baseBuiltinFunc) 2318 return newSig 2319 } 2320 2321 func (b *builtinNullEQTimeSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2322 arg0, isNull0, err := b.args[0].EvalTime(b.ctx, event) 2323 if err != nil { 2324 return 0, true, err 2325 } 2326 arg1, isNull1, err := b.args[1].EvalTime(b.ctx, event) 2327 if err != nil { 2328 return 0, true, err 2329 } 2330 var res int64 2331 switch { 2332 case isNull0 && isNull1: 2333 res = 1 2334 case isNull0 != isNull1: 2335 break 2336 case arg0.Compare(arg1) == 0: 2337 res = 1 2338 } 2339 return res, false, nil 2340 } 2341 2342 type builtinNullEQJSONSig struct { 2343 baseBuiltinFunc 2344 } 2345 2346 func (b *builtinNullEQJSONSig) Clone() builtinFunc { 2347 newSig := &builtinNullEQJSONSig{} 2348 newSig.cloneFrom(&b.baseBuiltinFunc) 2349 return newSig 2350 } 2351 2352 func (b *builtinNullEQJSONSig) evalInt(event chunk.Event) (val int64, isNull bool, err error) { 2353 arg0, isNull0, err := b.args[0].EvalJSON(b.ctx, event) 2354 if err != nil { 2355 return 0, true, err 2356 } 2357 arg1, isNull1, err := b.args[1].EvalJSON(b.ctx, event) 2358 if err != nil { 2359 return 0, true, err 2360 } 2361 var res int64 2362 switch { 2363 case isNull0 && isNull1: 2364 res = 1 2365 case isNull0 != isNull1: 2366 break 2367 default: 2368 cmpRes := json.CompareBinary(arg0, arg1) 2369 if cmpRes == 0 { 2370 res = 1 2371 } 2372 } 2373 return res, false, nil 2374 } 2375 2376 func resOfLT(val int64, isNull bool, err error) (int64, bool, error) { 2377 if isNull || err != nil { 2378 return 0, isNull, err 2379 } 2380 if val < 0 { 2381 val = 1 2382 } else { 2383 val = 0 2384 } 2385 return val, false, nil 2386 } 2387 2388 func resOfLE(val int64, isNull bool, err error) (int64, bool, error) { 2389 if isNull || err != nil { 2390 return 0, isNull, err 2391 } 2392 if val <= 0 { 2393 val = 1 2394 } else { 2395 val = 0 2396 } 2397 return val, false, nil 2398 } 2399 2400 func resOfGT(val int64, isNull bool, err error) (int64, bool, error) { 2401 if isNull || err != nil { 2402 return 0, isNull, err 2403 } 2404 if val > 0 { 2405 val = 1 2406 } else { 2407 val = 0 2408 } 2409 return val, false, nil 2410 } 2411 2412 func resOfGE(val int64, isNull bool, err error) (int64, bool, error) { 2413 if isNull || err != nil { 2414 return 0, isNull, err 2415 } 2416 if val >= 0 { 2417 val = 1 2418 } else { 2419 val = 0 2420 } 2421 return val, false, nil 2422 } 2423 2424 func resOfEQ(val int64, isNull bool, err error) (int64, bool, error) { 2425 if isNull || err != nil { 2426 return 0, isNull, err 2427 } 2428 if val == 0 { 2429 val = 1 2430 } else { 2431 val = 0 2432 } 2433 return val, false, nil 2434 } 2435 2436 func resOfNE(val int64, isNull bool, err error) (int64, bool, error) { 2437 if isNull || err != nil { 2438 return 0, isNull, err 2439 } 2440 if val != 0 { 2441 val = 1 2442 } else { 2443 val = 0 2444 } 2445 return val, false, nil 2446 } 2447 2448 // compareNull compares null values based on the following rules. 2449 // 1. NULL is considered to be equal to NULL 2450 // 2. NULL is considered to be smaller than a non-NULL value. 2451 // NOTE: (lhsIsNull == true) or (rhsIsNull == true) is required. 2452 func compareNull(lhsIsNull, rhsIsNull bool) int64 { 2453 if lhsIsNull && rhsIsNull { 2454 return 0 2455 } 2456 if lhsIsNull { 2457 return -1 2458 } 2459 return 1 2460 } 2461 2462 // CompareFunc defines the compare function prototype. 2463 type CompareFunc = func(sctx stochastikctx.Context, lhsArg, rhsArg Expression, lhsEvent, rhsEvent chunk.Event) (int64, bool, error) 2464 2465 // CompareInt compares two integers. 2466 func CompareInt(sctx stochastikctx.Context, lhsArg, rhsArg Expression, lhsEvent, rhsEvent chunk.Event) (int64, bool, error) { 2467 arg0, isNull0, err := lhsArg.EvalInt(sctx, lhsEvent) 2468 if err != nil { 2469 return 0, true, err 2470 } 2471 2472 arg1, isNull1, err := rhsArg.EvalInt(sctx, rhsEvent) 2473 if err != nil { 2474 return 0, true, err 2475 } 2476 2477 // compare null values. 2478 if isNull0 || isNull1 { 2479 return compareNull(isNull0, isNull1), true, nil 2480 } 2481 2482 isUnsigned0, isUnsigned1 := allegrosql.HasUnsignedFlag(lhsArg.GetType().Flag), allegrosql.HasUnsignedFlag(rhsArg.GetType().Flag) 2483 var res int 2484 switch { 2485 case isUnsigned0 && isUnsigned1: 2486 res = types.CompareUint64(uint64(arg0), uint64(arg1)) 2487 case isUnsigned0 && !isUnsigned1: 2488 if arg1 < 0 || uint64(arg0) > math.MaxInt64 { 2489 res = 1 2490 } else { 2491 res = types.CompareInt64(arg0, arg1) 2492 } 2493 case !isUnsigned0 && isUnsigned1: 2494 if arg0 < 0 || uint64(arg1) > math.MaxInt64 { 2495 res = -1 2496 } else { 2497 res = types.CompareInt64(arg0, arg1) 2498 } 2499 case !isUnsigned0 && !isUnsigned1: 2500 res = types.CompareInt64(arg0, arg1) 2501 } 2502 return int64(res), false, nil 2503 } 2504 2505 func genCompareString(defCauslation string) func(sctx stochastikctx.Context, lhsArg Expression, rhsArg Expression, lhsEvent chunk.Event, rhsEvent chunk.Event) (int64, bool, error) { 2506 return func(sctx stochastikctx.Context, lhsArg, rhsArg Expression, lhsEvent, rhsEvent chunk.Event) (int64, bool, error) { 2507 return CompareStringWithDefCauslationInfo(sctx, lhsArg, rhsArg, lhsEvent, rhsEvent, defCauslation) 2508 } 2509 } 2510 2511 // CompareStringWithDefCauslationInfo compares two strings with the specified defCauslation information. 2512 func CompareStringWithDefCauslationInfo(sctx stochastikctx.Context, lhsArg, rhsArg Expression, lhsEvent, rhsEvent chunk.Event, defCauslation string) (int64, bool, error) { 2513 arg0, isNull0, err := lhsArg.EvalString(sctx, lhsEvent) 2514 if err != nil { 2515 return 0, true, err 2516 } 2517 2518 arg1, isNull1, err := rhsArg.EvalString(sctx, rhsEvent) 2519 if err != nil { 2520 return 0, true, err 2521 } 2522 2523 if isNull0 || isNull1 { 2524 return compareNull(isNull0, isNull1), true, nil 2525 } 2526 return int64(types.CompareString(arg0, arg1, defCauslation)), false, nil 2527 } 2528 2529 // CompareReal compares two float-point values. 2530 func CompareReal(sctx stochastikctx.Context, lhsArg, rhsArg Expression, lhsEvent, rhsEvent chunk.Event) (int64, bool, error) { 2531 arg0, isNull0, err := lhsArg.EvalReal(sctx, lhsEvent) 2532 if err != nil { 2533 return 0, true, err 2534 } 2535 2536 arg1, isNull1, err := rhsArg.EvalReal(sctx, rhsEvent) 2537 if err != nil { 2538 return 0, true, err 2539 } 2540 2541 if isNull0 || isNull1 { 2542 return compareNull(isNull0, isNull1), true, nil 2543 } 2544 return int64(types.CompareFloat64(arg0, arg1)), false, nil 2545 } 2546 2547 // CompareDecimal compares two decimals. 2548 func CompareDecimal(sctx stochastikctx.Context, lhsArg, rhsArg Expression, lhsEvent, rhsEvent chunk.Event) (int64, bool, error) { 2549 arg0, isNull0, err := lhsArg.EvalDecimal(sctx, lhsEvent) 2550 if err != nil { 2551 return 0, true, err 2552 } 2553 2554 arg1, isNull1, err := rhsArg.EvalDecimal(sctx, rhsEvent) 2555 if err != nil { 2556 return 0, true, err 2557 } 2558 2559 if isNull0 || isNull1 { 2560 return compareNull(isNull0, isNull1), true, nil 2561 } 2562 return int64(arg0.Compare(arg1)), false, nil 2563 } 2564 2565 // CompareTime compares two datetime or timestamps. 2566 func CompareTime(sctx stochastikctx.Context, lhsArg, rhsArg Expression, lhsEvent, rhsEvent chunk.Event) (int64, bool, error) { 2567 arg0, isNull0, err := lhsArg.EvalTime(sctx, lhsEvent) 2568 if err != nil { 2569 return 0, true, err 2570 } 2571 2572 arg1, isNull1, err := rhsArg.EvalTime(sctx, rhsEvent) 2573 if err != nil { 2574 return 0, true, err 2575 } 2576 2577 if isNull0 || isNull1 { 2578 return compareNull(isNull0, isNull1), true, nil 2579 } 2580 return int64(arg0.Compare(arg1)), false, nil 2581 } 2582 2583 // CompareDuration compares two durations. 2584 func CompareDuration(sctx stochastikctx.Context, lhsArg, rhsArg Expression, lhsEvent, rhsEvent chunk.Event) (int64, bool, error) { 2585 arg0, isNull0, err := lhsArg.EvalDuration(sctx, lhsEvent) 2586 if err != nil { 2587 return 0, true, err 2588 } 2589 2590 arg1, isNull1, err := rhsArg.EvalDuration(sctx, rhsEvent) 2591 if err != nil { 2592 return 0, true, err 2593 } 2594 2595 if isNull0 || isNull1 { 2596 return compareNull(isNull0, isNull1), true, nil 2597 } 2598 return int64(arg0.Compare(arg1)), false, nil 2599 } 2600 2601 // CompareJSON compares two JSONs. 2602 func CompareJSON(sctx stochastikctx.Context, lhsArg, rhsArg Expression, lhsEvent, rhsEvent chunk.Event) (int64, bool, error) { 2603 arg0, isNull0, err := lhsArg.EvalJSON(sctx, lhsEvent) 2604 if err != nil { 2605 return 0, true, err 2606 } 2607 2608 arg1, isNull1, err := rhsArg.EvalJSON(sctx, rhsEvent) 2609 if err != nil { 2610 return 0, true, err 2611 } 2612 2613 if isNull0 || isNull1 { 2614 return compareNull(isNull0, isNull1), true, nil 2615 } 2616 return int64(json.CompareBinary(arg0, arg1)), false, nil 2617 }