github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_cast.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 // We implement 6 CastAsXXFunctionClass for `cast` built-in functions. 15 // XX means the return type of the `cast` built-in functions. 16 // XX contains the following 6 types: 17 // Int, Decimal, Real, String, Time, Duration. 18 19 // We implement 6 CastYYAsXXSig built-in function signatures for every CastAsXXFunctionClass. 20 // builtinCastXXAsYYSig takes a argument of type XX and returns a value of type YY. 21 22 package memex 23 24 import ( 25 "math" 26 "strconv" 27 "strings" 28 29 "github.com/whtcorpsinc/errors" 30 "github.com/whtcorpsinc/BerolinaSQL/ast" 31 "github.com/whtcorpsinc/BerolinaSQL/perceptron" 32 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 33 "github.com/whtcorpsinc/BerolinaSQL/terror" 34 "github.com/whtcorpsinc/milevadb/stochastikctx" 35 "github.com/whtcorpsinc/milevadb/stochastikctx/variable" 36 "github.com/whtcorpsinc/milevadb/types" 37 "github.com/whtcorpsinc/milevadb/types/json" 38 "github.com/whtcorpsinc/milevadb/soliton/chunk" 39 "github.com/whtcorpsinc/fidelpb/go-fidelpb" 40 ) 41 42 var ( 43 _ functionClass = &castAsIntFunctionClass{} 44 _ functionClass = &castAsRealFunctionClass{} 45 _ functionClass = &castAsStringFunctionClass{} 46 _ functionClass = &castAsDecimalFunctionClass{} 47 _ functionClass = &castAsTimeFunctionClass{} 48 _ functionClass = &castAsDurationFunctionClass{} 49 _ functionClass = &castAsJSONFunctionClass{} 50 ) 51 52 var ( 53 _ builtinFunc = &builtinCastIntAsIntSig{} 54 _ builtinFunc = &builtinCastIntAsRealSig{} 55 _ builtinFunc = &builtinCastIntAsStringSig{} 56 _ builtinFunc = &builtinCastIntAsDecimalSig{} 57 _ builtinFunc = &builtinCastIntAsTimeSig{} 58 _ builtinFunc = &builtinCastIntAsDurationSig{} 59 _ builtinFunc = &builtinCastIntAsJSONSig{} 60 61 _ builtinFunc = &builtinCastRealAsIntSig{} 62 _ builtinFunc = &builtinCastRealAsRealSig{} 63 _ builtinFunc = &builtinCastRealAsStringSig{} 64 _ builtinFunc = &builtinCastRealAsDecimalSig{} 65 _ builtinFunc = &builtinCastRealAsTimeSig{} 66 _ builtinFunc = &builtinCastRealAsDurationSig{} 67 _ builtinFunc = &builtinCastRealAsJSONSig{} 68 69 _ builtinFunc = &builtinCastDecimalAsIntSig{} 70 _ builtinFunc = &builtinCastDecimalAsRealSig{} 71 _ builtinFunc = &builtinCastDecimalAsStringSig{} 72 _ builtinFunc = &builtinCastDecimalAsDecimalSig{} 73 _ builtinFunc = &builtinCastDecimalAsTimeSig{} 74 _ builtinFunc = &builtinCastDecimalAsDurationSig{} 75 _ builtinFunc = &builtinCastDecimalAsJSONSig{} 76 77 _ builtinFunc = &builtinCastStringAsIntSig{} 78 _ builtinFunc = &builtinCastStringAsRealSig{} 79 _ builtinFunc = &builtinCastStringAsStringSig{} 80 _ builtinFunc = &builtinCastStringAsDecimalSig{} 81 _ builtinFunc = &builtinCastStringAsTimeSig{} 82 _ builtinFunc = &builtinCastStringAsDurationSig{} 83 _ builtinFunc = &builtinCastStringAsJSONSig{} 84 85 _ builtinFunc = &builtinCastTimeAsIntSig{} 86 _ builtinFunc = &builtinCastTimeAsRealSig{} 87 _ builtinFunc = &builtinCastTimeAsStringSig{} 88 _ builtinFunc = &builtinCastTimeAsDecimalSig{} 89 _ builtinFunc = &builtinCastTimeAsTimeSig{} 90 _ builtinFunc = &builtinCastTimeAsDurationSig{} 91 _ builtinFunc = &builtinCastTimeAsJSONSig{} 92 93 _ builtinFunc = &builtinCastDurationAsIntSig{} 94 _ builtinFunc = &builtinCastDurationAsRealSig{} 95 _ builtinFunc = &builtinCastDurationAsStringSig{} 96 _ builtinFunc = &builtinCastDurationAsDecimalSig{} 97 _ builtinFunc = &builtinCastDurationAsTimeSig{} 98 _ builtinFunc = &builtinCastDurationAsDurationSig{} 99 _ builtinFunc = &builtinCastDurationAsJSONSig{} 100 101 _ builtinFunc = &builtinCastJSONAsIntSig{} 102 _ builtinFunc = &builtinCastJSONAsRealSig{} 103 _ builtinFunc = &builtinCastJSONAsStringSig{} 104 _ builtinFunc = &builtinCastJSONAsDecimalSig{} 105 _ builtinFunc = &builtinCastJSONAsTimeSig{} 106 _ builtinFunc = &builtinCastJSONAsDurationSig{} 107 _ builtinFunc = &builtinCastJSONAsJSONSig{} 108 ) 109 110 type castAsIntFunctionClass struct { 111 baseFunctionClass 112 113 tp *types.FieldType 114 } 115 116 func (c *castAsIntFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) { 117 if err := c.verifyArgs(args); err != nil { 118 return nil, err 119 } 120 b, err := newBaseBuiltinFunc(ctx, c.funcName, args, c.tp.EvalType()) 121 if err != nil { 122 return nil, err 123 } 124 bf := newBaseBuiltinCastFunc(b, ctx.Value(inUnionCastContext) != nil) 125 bf.tp = c.tp 126 if args[0].GetType().Hybrid() || IsBinaryLiteral(args[0]) { 127 sig = &builtinCastIntAsIntSig{bf} 128 sig.setPbCode(fidelpb.ScalarFuncSig_CastIntAsInt) 129 return sig, nil 130 } 131 argTp := args[0].GetType().EvalType() 132 switch argTp { 133 case types.ETInt: 134 sig = &builtinCastIntAsIntSig{bf} 135 sig.setPbCode(fidelpb.ScalarFuncSig_CastIntAsInt) 136 case types.ETReal: 137 sig = &builtinCastRealAsIntSig{bf} 138 sig.setPbCode(fidelpb.ScalarFuncSig_CastRealAsInt) 139 case types.ETDecimal: 140 sig = &builtinCastDecimalAsIntSig{bf} 141 sig.setPbCode(fidelpb.ScalarFuncSig_CastDecimalAsInt) 142 case types.ETDatetime, types.ETTimestamp: 143 sig = &builtinCastTimeAsIntSig{bf} 144 sig.setPbCode(fidelpb.ScalarFuncSig_CastTimeAsInt) 145 case types.ETDuration: 146 sig = &builtinCastDurationAsIntSig{bf} 147 sig.setPbCode(fidelpb.ScalarFuncSig_CastDurationAsInt) 148 case types.ETJson: 149 sig = &builtinCastJSONAsIntSig{bf} 150 sig.setPbCode(fidelpb.ScalarFuncSig_CastJsonAsInt) 151 case types.ETString: 152 sig = &builtinCastStringAsIntSig{bf} 153 sig.setPbCode(fidelpb.ScalarFuncSig_CastStringAsInt) 154 default: 155 panic("unsupported types.EvalType in castAsIntFunctionClass") 156 } 157 return sig, nil 158 } 159 160 type castAsRealFunctionClass struct { 161 baseFunctionClass 162 163 tp *types.FieldType 164 } 165 166 func (c *castAsRealFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) { 167 if err := c.verifyArgs(args); err != nil { 168 return nil, err 169 } 170 b, err := newBaseBuiltinFunc(ctx, c.funcName, args, c.tp.EvalType()) 171 if err != nil { 172 return nil, err 173 } 174 bf := newBaseBuiltinCastFunc(b, ctx.Value(inUnionCastContext) != nil) 175 bf.tp = c.tp 176 if IsBinaryLiteral(args[0]) { 177 sig = &builtinCastRealAsRealSig{bf} 178 sig.setPbCode(fidelpb.ScalarFuncSig_CastRealAsReal) 179 return sig, nil 180 } 181 var argTp types.EvalType 182 if args[0].GetType().Hybrid() { 183 argTp = types.ETInt 184 } else { 185 argTp = args[0].GetType().EvalType() 186 } 187 switch argTp { 188 case types.ETInt: 189 sig = &builtinCastIntAsRealSig{bf} 190 sig.setPbCode(fidelpb.ScalarFuncSig_CastIntAsReal) 191 case types.ETReal: 192 sig = &builtinCastRealAsRealSig{bf} 193 sig.setPbCode(fidelpb.ScalarFuncSig_CastRealAsReal) 194 case types.ETDecimal: 195 sig = &builtinCastDecimalAsRealSig{bf} 196 sig.setPbCode(fidelpb.ScalarFuncSig_CastDecimalAsReal) 197 case types.ETDatetime, types.ETTimestamp: 198 sig = &builtinCastTimeAsRealSig{bf} 199 sig.setPbCode(fidelpb.ScalarFuncSig_CastTimeAsReal) 200 case types.ETDuration: 201 sig = &builtinCastDurationAsRealSig{bf} 202 sig.setPbCode(fidelpb.ScalarFuncSig_CastDurationAsReal) 203 case types.ETJson: 204 sig = &builtinCastJSONAsRealSig{bf} 205 sig.setPbCode(fidelpb.ScalarFuncSig_CastJsonAsReal) 206 case types.ETString: 207 sig = &builtinCastStringAsRealSig{bf} 208 sig.setPbCode(fidelpb.ScalarFuncSig_CastStringAsReal) 209 default: 210 panic("unsupported types.EvalType in castAsRealFunctionClass") 211 } 212 return sig, nil 213 } 214 215 type castAsDecimalFunctionClass struct { 216 baseFunctionClass 217 218 tp *types.FieldType 219 } 220 221 func (c *castAsDecimalFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) { 222 if err := c.verifyArgs(args); err != nil { 223 return nil, err 224 } 225 b, err := newBaseBuiltinFunc(ctx, c.funcName, args, c.tp.EvalType()) 226 if err != nil { 227 return nil, err 228 } 229 bf := newBaseBuiltinCastFunc(b, ctx.Value(inUnionCastContext) != nil) 230 bf.tp = c.tp 231 if IsBinaryLiteral(args[0]) { 232 sig = &builtinCastDecimalAsDecimalSig{bf} 233 sig.setPbCode(fidelpb.ScalarFuncSig_CastDecimalAsDecimal) 234 return sig, nil 235 } 236 var argTp types.EvalType 237 if args[0].GetType().Hybrid() { 238 argTp = types.ETInt 239 } else { 240 argTp = args[0].GetType().EvalType() 241 } 242 switch argTp { 243 case types.ETInt: 244 sig = &builtinCastIntAsDecimalSig{bf} 245 sig.setPbCode(fidelpb.ScalarFuncSig_CastIntAsDecimal) 246 case types.ETReal: 247 sig = &builtinCastRealAsDecimalSig{bf} 248 sig.setPbCode(fidelpb.ScalarFuncSig_CastRealAsDecimal) 249 case types.ETDecimal: 250 sig = &builtinCastDecimalAsDecimalSig{bf} 251 sig.setPbCode(fidelpb.ScalarFuncSig_CastDecimalAsDecimal) 252 case types.ETDatetime, types.ETTimestamp: 253 sig = &builtinCastTimeAsDecimalSig{bf} 254 sig.setPbCode(fidelpb.ScalarFuncSig_CastTimeAsDecimal) 255 case types.ETDuration: 256 sig = &builtinCastDurationAsDecimalSig{bf} 257 sig.setPbCode(fidelpb.ScalarFuncSig_CastDurationAsDecimal) 258 case types.ETJson: 259 sig = &builtinCastJSONAsDecimalSig{bf} 260 sig.setPbCode(fidelpb.ScalarFuncSig_CastJsonAsDecimal) 261 case types.ETString: 262 sig = &builtinCastStringAsDecimalSig{bf} 263 sig.setPbCode(fidelpb.ScalarFuncSig_CastStringAsDecimal) 264 default: 265 panic("unsupported types.EvalType in castAsDecimalFunctionClass") 266 } 267 return sig, nil 268 } 269 270 type castAsStringFunctionClass struct { 271 baseFunctionClass 272 273 tp *types.FieldType 274 } 275 276 func (c *castAsStringFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) { 277 if err := c.verifyArgs(args); err != nil { 278 return nil, err 279 } 280 bf, err := newBaseBuiltinFunc(ctx, c.funcName, args, c.tp.EvalType()) 281 if err != nil { 282 return nil, err 283 } 284 bf.tp = c.tp 285 if args[0].GetType().Hybrid() || IsBinaryLiteral(args[0]) { 286 sig = &builtinCastStringAsStringSig{bf} 287 sig.setPbCode(fidelpb.ScalarFuncSig_CastStringAsString) 288 return sig, nil 289 } 290 argTp := args[0].GetType().EvalType() 291 switch argTp { 292 case types.ETInt: 293 sig = &builtinCastIntAsStringSig{bf} 294 sig.setPbCode(fidelpb.ScalarFuncSig_CastIntAsString) 295 case types.ETReal: 296 sig = &builtinCastRealAsStringSig{bf} 297 sig.setPbCode(fidelpb.ScalarFuncSig_CastRealAsString) 298 case types.ETDecimal: 299 sig = &builtinCastDecimalAsStringSig{bf} 300 sig.setPbCode(fidelpb.ScalarFuncSig_CastDecimalAsString) 301 case types.ETDatetime, types.ETTimestamp: 302 sig = &builtinCastTimeAsStringSig{bf} 303 sig.setPbCode(fidelpb.ScalarFuncSig_CastTimeAsString) 304 case types.ETDuration: 305 sig = &builtinCastDurationAsStringSig{bf} 306 sig.setPbCode(fidelpb.ScalarFuncSig_CastDurationAsString) 307 case types.ETJson: 308 sig = &builtinCastJSONAsStringSig{bf} 309 sig.setPbCode(fidelpb.ScalarFuncSig_CastJsonAsString) 310 case types.ETString: 311 sig = &builtinCastStringAsStringSig{bf} 312 sig.setPbCode(fidelpb.ScalarFuncSig_CastStringAsString) 313 default: 314 panic("unsupported types.EvalType in castAsStringFunctionClass") 315 } 316 return sig, nil 317 } 318 319 type castAsTimeFunctionClass struct { 320 baseFunctionClass 321 322 tp *types.FieldType 323 } 324 325 func (c *castAsTimeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) { 326 if err := c.verifyArgs(args); err != nil { 327 return nil, err 328 } 329 bf, err := newBaseBuiltinFunc(ctx, c.funcName, args, c.tp.EvalType()) 330 if err != nil { 331 return nil, err 332 } 333 bf.tp = c.tp 334 argTp := args[0].GetType().EvalType() 335 switch argTp { 336 case types.ETInt: 337 sig = &builtinCastIntAsTimeSig{bf} 338 sig.setPbCode(fidelpb.ScalarFuncSig_CastIntAsTime) 339 case types.ETReal: 340 sig = &builtinCastRealAsTimeSig{bf} 341 sig.setPbCode(fidelpb.ScalarFuncSig_CastRealAsTime) 342 case types.ETDecimal: 343 sig = &builtinCastDecimalAsTimeSig{bf} 344 sig.setPbCode(fidelpb.ScalarFuncSig_CastDecimalAsTime) 345 case types.ETDatetime, types.ETTimestamp: 346 sig = &builtinCastTimeAsTimeSig{bf} 347 sig.setPbCode(fidelpb.ScalarFuncSig_CastTimeAsTime) 348 case types.ETDuration: 349 sig = &builtinCastDurationAsTimeSig{bf} 350 sig.setPbCode(fidelpb.ScalarFuncSig_CastDurationAsTime) 351 case types.ETJson: 352 sig = &builtinCastJSONAsTimeSig{bf} 353 sig.setPbCode(fidelpb.ScalarFuncSig_CastJsonAsTime) 354 case types.ETString: 355 sig = &builtinCastStringAsTimeSig{bf} 356 sig.setPbCode(fidelpb.ScalarFuncSig_CastStringAsTime) 357 default: 358 panic("unsupported types.EvalType in castAsTimeFunctionClass") 359 } 360 return sig, nil 361 } 362 363 type castAsDurationFunctionClass struct { 364 baseFunctionClass 365 366 tp *types.FieldType 367 } 368 369 func (c *castAsDurationFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) { 370 if err := c.verifyArgs(args); err != nil { 371 return nil, err 372 } 373 bf, err := newBaseBuiltinFunc(ctx, c.funcName, args, c.tp.EvalType()) 374 if err != nil { 375 return nil, err 376 } 377 bf.tp = c.tp 378 argTp := args[0].GetType().EvalType() 379 switch argTp { 380 case types.ETInt: 381 sig = &builtinCastIntAsDurationSig{bf} 382 sig.setPbCode(fidelpb.ScalarFuncSig_CastIntAsDuration) 383 case types.ETReal: 384 sig = &builtinCastRealAsDurationSig{bf} 385 sig.setPbCode(fidelpb.ScalarFuncSig_CastRealAsDuration) 386 case types.ETDecimal: 387 sig = &builtinCastDecimalAsDurationSig{bf} 388 sig.setPbCode(fidelpb.ScalarFuncSig_CastDecimalAsDuration) 389 case types.ETDatetime, types.ETTimestamp: 390 sig = &builtinCastTimeAsDurationSig{bf} 391 sig.setPbCode(fidelpb.ScalarFuncSig_CastTimeAsDuration) 392 case types.ETDuration: 393 sig = &builtinCastDurationAsDurationSig{bf} 394 sig.setPbCode(fidelpb.ScalarFuncSig_CastDurationAsDuration) 395 case types.ETJson: 396 sig = &builtinCastJSONAsDurationSig{bf} 397 sig.setPbCode(fidelpb.ScalarFuncSig_CastJsonAsDuration) 398 case types.ETString: 399 sig = &builtinCastStringAsDurationSig{bf} 400 sig.setPbCode(fidelpb.ScalarFuncSig_CastStringAsDuration) 401 default: 402 panic("unsupported types.EvalType in castAsDurationFunctionClass") 403 } 404 return sig, nil 405 } 406 407 type castAsJSONFunctionClass struct { 408 baseFunctionClass 409 410 tp *types.FieldType 411 } 412 413 func (c *castAsJSONFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (sig builtinFunc, err error) { 414 if err := c.verifyArgs(args); err != nil { 415 return nil, err 416 } 417 bf, err := newBaseBuiltinFunc(ctx, c.funcName, args, c.tp.EvalType()) 418 if err != nil { 419 return nil, err 420 } 421 bf.tp = c.tp 422 argTp := args[0].GetType().EvalType() 423 switch argTp { 424 case types.ETInt: 425 sig = &builtinCastIntAsJSONSig{bf} 426 sig.setPbCode(fidelpb.ScalarFuncSig_CastIntAsJson) 427 case types.ETReal: 428 sig = &builtinCastRealAsJSONSig{bf} 429 sig.setPbCode(fidelpb.ScalarFuncSig_CastRealAsJson) 430 case types.ETDecimal: 431 sig = &builtinCastDecimalAsJSONSig{bf} 432 sig.setPbCode(fidelpb.ScalarFuncSig_CastDecimalAsJson) 433 case types.ETDatetime, types.ETTimestamp: 434 sig = &builtinCastTimeAsJSONSig{bf} 435 sig.setPbCode(fidelpb.ScalarFuncSig_CastTimeAsJson) 436 case types.ETDuration: 437 sig = &builtinCastDurationAsJSONSig{bf} 438 sig.setPbCode(fidelpb.ScalarFuncSig_CastDurationAsJson) 439 case types.ETJson: 440 sig = &builtinCastJSONAsJSONSig{bf} 441 sig.setPbCode(fidelpb.ScalarFuncSig_CastJsonAsJson) 442 case types.ETString: 443 sig = &builtinCastStringAsJSONSig{bf} 444 sig.getRetTp().Flag |= allegrosql.ParseToJSONFlag 445 sig.setPbCode(fidelpb.ScalarFuncSig_CastStringAsJson) 446 default: 447 panic("unsupported types.EvalType in castAsJSONFunctionClass") 448 } 449 return sig, nil 450 } 451 452 type builtinCastIntAsIntSig struct { 453 baseBuiltinCastFunc 454 } 455 456 func (b *builtinCastIntAsIntSig) Clone() builtinFunc { 457 newSig := &builtinCastIntAsIntSig{} 458 newSig.cloneFrom(&b.baseBuiltinCastFunc) 459 return newSig 460 } 461 462 func (b *builtinCastIntAsIntSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) { 463 res, isNull, err = b.args[0].EvalInt(b.ctx, event) 464 if isNull || err != nil { 465 return 466 } 467 if b.inUnion && allegrosql.HasUnsignedFlag(b.tp.Flag) && res < 0 { 468 res = 0 469 } 470 return 471 } 472 473 type builtinCastIntAsRealSig struct { 474 baseBuiltinCastFunc 475 } 476 477 func (b *builtinCastIntAsRealSig) Clone() builtinFunc { 478 newSig := &builtinCastIntAsRealSig{} 479 newSig.cloneFrom(&b.baseBuiltinCastFunc) 480 return newSig 481 } 482 483 func (b *builtinCastIntAsRealSig) evalReal(event chunk.Event) (res float64, isNull bool, err error) { 484 val, isNull, err := b.args[0].EvalInt(b.ctx, event) 485 if isNull || err != nil { 486 return res, isNull, err 487 } 488 if unsignedArgs0 := allegrosql.HasUnsignedFlag(b.args[0].GetType().Flag); !allegrosql.HasUnsignedFlag(b.tp.Flag) && !unsignedArgs0 { 489 res = float64(val) 490 } else if b.inUnion && !unsignedArgs0 && val < 0 { 491 // Round up to 0 if the value is negative but the memex eval type is unsigned in `UNION` memex 492 // NOTE: the following memexs are equal (so choose the more efficient one): 493 // `b.inUnion && allegrosql.HasUnsignedFlag(b.tp.Flag) && !unsignedArgs0 && val < 0` 494 // `b.inUnion && !unsignedArgs0 && val < 0` 495 res = 0 496 } else { 497 // recall that, int to float is different from uint to float 498 res = float64(uint64(val)) 499 } 500 return res, false, err 501 } 502 503 type builtinCastIntAsDecimalSig struct { 504 baseBuiltinCastFunc 505 } 506 507 func (b *builtinCastIntAsDecimalSig) Clone() builtinFunc { 508 newSig := &builtinCastIntAsDecimalSig{} 509 newSig.cloneFrom(&b.baseBuiltinCastFunc) 510 return newSig 511 } 512 513 func (b *builtinCastIntAsDecimalSig) evalDecimal(event chunk.Event) (res *types.MyDecimal, isNull bool, err error) { 514 val, isNull, err := b.args[0].EvalInt(b.ctx, event) 515 if isNull || err != nil { 516 return res, isNull, err 517 } 518 519 if unsignedArgs0 := allegrosql.HasUnsignedFlag(b.args[0].GetType().Flag); !allegrosql.HasUnsignedFlag(b.tp.Flag) && !unsignedArgs0 { 520 res = types.NewDecFromInt(val) 521 // Round up to 0 if the value is negative but the memex eval type is unsigned in `UNION` memex 522 // NOTE: the following memexs are equal (so choose the more efficient one): 523 // `b.inUnion && allegrosql.HasUnsignedFlag(b.tp.Flag) && !unsignedArgs0 && val < 0` 524 // `b.inUnion && !unsignedArgs0 && val < 0` 525 } else if b.inUnion && !unsignedArgs0 && val < 0 { 526 res = &types.MyDecimal{} 527 } else { 528 res = types.NewDecFromUint(uint64(val)) 529 } 530 res, err = types.ProduceDecWithSpecifiedTp(res, b.tp, b.ctx.GetStochastikVars().StmtCtx) 531 return res, isNull, err 532 } 533 534 type builtinCastIntAsStringSig struct { 535 baseBuiltinFunc 536 } 537 538 func (b *builtinCastIntAsStringSig) Clone() builtinFunc { 539 newSig := &builtinCastIntAsStringSig{} 540 newSig.cloneFrom(&b.baseBuiltinFunc) 541 return newSig 542 } 543 544 func (b *builtinCastIntAsStringSig) evalString(event chunk.Event) (res string, isNull bool, err error) { 545 val, isNull, err := b.args[0].EvalInt(b.ctx, event) 546 if isNull || err != nil { 547 return res, isNull, err 548 } 549 if !allegrosql.HasUnsignedFlag(b.args[0].GetType().Flag) { 550 res = strconv.FormatInt(val, 10) 551 } else { 552 res = strconv.FormatUint(uint64(val), 10) 553 } 554 res, err = types.ProduceStrWithSpecifiedTp(res, b.tp, b.ctx.GetStochastikVars().StmtCtx, false) 555 if err != nil { 556 return res, false, err 557 } 558 return padZeroForBinaryType(res, b.tp, b.ctx) 559 } 560 561 type builtinCastIntAsTimeSig struct { 562 baseBuiltinFunc 563 } 564 565 func (b *builtinCastIntAsTimeSig) Clone() builtinFunc { 566 newSig := &builtinCastIntAsTimeSig{} 567 newSig.cloneFrom(&b.baseBuiltinFunc) 568 return newSig 569 } 570 571 func (b *builtinCastIntAsTimeSig) evalTime(event chunk.Event) (res types.Time, isNull bool, err error) { 572 val, isNull, err := b.args[0].EvalInt(b.ctx, event) 573 if isNull || err != nil { 574 return res, isNull, err 575 } 576 res, err = types.ParseTimeFromNum(b.ctx.GetStochastikVars().StmtCtx, val, b.tp.Tp, int8(b.tp.Decimal)) 577 if err != nil { 578 return types.ZeroTime, true, handleInvalidTimeError(b.ctx, err) 579 } 580 if b.tp.Tp == allegrosql.TypeDate { 581 // Truncate hh:mm:ss part if the type is Date. 582 res.SetCoreTime(types.FromDate(res.Year(), res.Month(), res.Day(), 0, 0, 0, 0)) 583 } 584 return res, false, nil 585 } 586 587 type builtinCastIntAsDurationSig struct { 588 baseBuiltinFunc 589 } 590 591 func (b *builtinCastIntAsDurationSig) Clone() builtinFunc { 592 newSig := &builtinCastIntAsDurationSig{} 593 newSig.cloneFrom(&b.baseBuiltinFunc) 594 return newSig 595 } 596 597 func (b *builtinCastIntAsDurationSig) evalDuration(event chunk.Event) (res types.Duration, isNull bool, err error) { 598 val, isNull, err := b.args[0].EvalInt(b.ctx, event) 599 if isNull || err != nil { 600 return res, isNull, err 601 } 602 dur, err := types.NumberToDuration(val, int8(b.tp.Decimal)) 603 if err != nil { 604 if types.ErrOverflow.Equal(err) { 605 err = b.ctx.GetStochastikVars().StmtCtx.HandleOverflow(err, err) 606 } 607 return res, true, err 608 } 609 return dur, false, err 610 } 611 612 type builtinCastIntAsJSONSig struct { 613 baseBuiltinFunc 614 } 615 616 func (b *builtinCastIntAsJSONSig) Clone() builtinFunc { 617 newSig := &builtinCastIntAsJSONSig{} 618 newSig.cloneFrom(&b.baseBuiltinFunc) 619 return newSig 620 } 621 622 func (b *builtinCastIntAsJSONSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) { 623 val, isNull, err := b.args[0].EvalInt(b.ctx, event) 624 if isNull || err != nil { 625 return res, isNull, err 626 } 627 if allegrosql.HasIsBooleanFlag(b.args[0].GetType().Flag) { 628 res = json.CreateBinary(val != 0) 629 } else if allegrosql.HasUnsignedFlag(b.args[0].GetType().Flag) { 630 res = json.CreateBinary(uint64(val)) 631 } else { 632 res = json.CreateBinary(val) 633 } 634 return res, false, nil 635 } 636 637 type builtinCastRealAsJSONSig struct { 638 baseBuiltinFunc 639 } 640 641 func (b *builtinCastRealAsJSONSig) Clone() builtinFunc { 642 newSig := &builtinCastRealAsJSONSig{} 643 newSig.cloneFrom(&b.baseBuiltinFunc) 644 return newSig 645 } 646 647 func (b *builtinCastRealAsJSONSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) { 648 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 649 // FIXME: `select json_type(cast(1111.11 as json))` should return `DECIMAL`, we return `DOUBLE` now. 650 return json.CreateBinary(val), isNull, err 651 } 652 653 type builtinCastDecimalAsJSONSig struct { 654 baseBuiltinFunc 655 } 656 657 func (b *builtinCastDecimalAsJSONSig) Clone() builtinFunc { 658 newSig := &builtinCastDecimalAsJSONSig{} 659 newSig.cloneFrom(&b.baseBuiltinFunc) 660 return newSig 661 } 662 663 func (b *builtinCastDecimalAsJSONSig) evalJSON(event chunk.Event) (json.BinaryJSON, bool, error) { 664 val, isNull, err := b.args[0].EvalDecimal(b.ctx, event) 665 if isNull || err != nil { 666 return json.BinaryJSON{}, true, err 667 } 668 // FIXME: `select json_type(cast(1111.11 as json))` should return `DECIMAL`, we return `DOUBLE` now. 669 f64, err := val.ToFloat64() 670 if err != nil { 671 return json.BinaryJSON{}, true, err 672 } 673 return json.CreateBinary(f64), isNull, err 674 } 675 676 type builtinCastStringAsJSONSig struct { 677 baseBuiltinFunc 678 } 679 680 func (b *builtinCastStringAsJSONSig) Clone() builtinFunc { 681 newSig := &builtinCastStringAsJSONSig{} 682 newSig.cloneFrom(&b.baseBuiltinFunc) 683 return newSig 684 } 685 686 func (b *builtinCastStringAsJSONSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) { 687 val, isNull, err := b.args[0].EvalString(b.ctx, event) 688 if isNull || err != nil { 689 return res, isNull, err 690 } 691 if allegrosql.HasParseToJSONFlag(b.tp.Flag) { 692 res, err = json.ParseBinaryFromString(val) 693 } else { 694 res = json.CreateBinary(val) 695 } 696 return res, false, err 697 } 698 699 type builtinCastDurationAsJSONSig struct { 700 baseBuiltinFunc 701 } 702 703 func (b *builtinCastDurationAsJSONSig) Clone() builtinFunc { 704 newSig := &builtinCastDurationAsJSONSig{} 705 newSig.cloneFrom(&b.baseBuiltinFunc) 706 return newSig 707 } 708 709 func (b *builtinCastDurationAsJSONSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) { 710 val, isNull, err := b.args[0].EvalDuration(b.ctx, event) 711 if isNull || err != nil { 712 return res, isNull, err 713 } 714 val.Fsp = types.MaxFsp 715 return json.CreateBinary(val.String()), false, nil 716 } 717 718 type builtinCastTimeAsJSONSig struct { 719 baseBuiltinFunc 720 } 721 722 func (b *builtinCastTimeAsJSONSig) Clone() builtinFunc { 723 newSig := &builtinCastTimeAsJSONSig{} 724 newSig.cloneFrom(&b.baseBuiltinFunc) 725 return newSig 726 } 727 728 func (b *builtinCastTimeAsJSONSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) { 729 val, isNull, err := b.args[0].EvalTime(b.ctx, event) 730 if isNull || err != nil { 731 return res, isNull, err 732 } 733 if val.Type() == allegrosql.TypeDatetime || val.Type() == allegrosql.TypeTimestamp { 734 val.SetFsp(types.MaxFsp) 735 } 736 return json.CreateBinary(val.String()), false, nil 737 } 738 739 type builtinCastRealAsRealSig struct { 740 baseBuiltinCastFunc 741 } 742 743 func (b *builtinCastRealAsRealSig) Clone() builtinFunc { 744 newSig := &builtinCastRealAsRealSig{} 745 newSig.cloneFrom(&b.baseBuiltinCastFunc) 746 return newSig 747 } 748 749 func (b *builtinCastRealAsRealSig) evalReal(event chunk.Event) (res float64, isNull bool, err error) { 750 res, isNull, err = b.args[0].EvalReal(b.ctx, event) 751 if b.inUnion && allegrosql.HasUnsignedFlag(b.tp.Flag) && res < 0 { 752 res = 0 753 } 754 return 755 } 756 757 type builtinCastRealAsIntSig struct { 758 baseBuiltinCastFunc 759 } 760 761 func (b *builtinCastRealAsIntSig) Clone() builtinFunc { 762 newSig := &builtinCastRealAsIntSig{} 763 newSig.cloneFrom(&b.baseBuiltinCastFunc) 764 return newSig 765 } 766 767 func (b *builtinCastRealAsIntSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) { 768 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 769 if isNull || err != nil { 770 return res, isNull, err 771 } 772 if !allegrosql.HasUnsignedFlag(b.tp.Flag) { 773 res, err = types.ConvertFloatToInt(val, types.IntergerSignedLowerBound(allegrosql.TypeLonglong), types.IntergerSignedUpperBound(allegrosql.TypeLonglong), allegrosql.TypeLonglong) 774 } else if b.inUnion && val < 0 { 775 res = 0 776 } else { 777 var uintVal uint64 778 sc := b.ctx.GetStochastikVars().StmtCtx 779 uintVal, err = types.ConvertFloatToUint(sc, val, types.IntergerUnsignedUpperBound(allegrosql.TypeLonglong), allegrosql.TypeLonglong) 780 res = int64(uintVal) 781 } 782 if types.ErrOverflow.Equal(err) { 783 err = b.ctx.GetStochastikVars().StmtCtx.HandleOverflow(err, err) 784 } 785 return res, isNull, err 786 } 787 788 type builtinCastRealAsDecimalSig struct { 789 baseBuiltinCastFunc 790 } 791 792 func (b *builtinCastRealAsDecimalSig) Clone() builtinFunc { 793 newSig := &builtinCastRealAsDecimalSig{} 794 newSig.cloneFrom(&b.baseBuiltinCastFunc) 795 return newSig 796 } 797 798 func (b *builtinCastRealAsDecimalSig) evalDecimal(event chunk.Event) (res *types.MyDecimal, isNull bool, err error) { 799 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 800 if isNull || err != nil { 801 return res, isNull, err 802 } 803 res = new(types.MyDecimal) 804 if !b.inUnion || val >= 0 { 805 err = res.FromFloat64(val) 806 if types.ErrOverflow.Equal(err) { 807 warnErr := types.ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", b.args[0]) 808 err = b.ctx.GetStochastikVars().StmtCtx.HandleOverflow(err, warnErr) 809 } else if types.ErrTruncated.Equal(err) { 810 // This behavior is consistent with MyALLEGROSQL. 811 err = nil 812 } 813 if err != nil { 814 return res, false, err 815 } 816 } 817 res, err = types.ProduceDecWithSpecifiedTp(res, b.tp, b.ctx.GetStochastikVars().StmtCtx) 818 return res, false, err 819 } 820 821 type builtinCastRealAsStringSig struct { 822 baseBuiltinFunc 823 } 824 825 func (b *builtinCastRealAsStringSig) Clone() builtinFunc { 826 newSig := &builtinCastRealAsStringSig{} 827 newSig.cloneFrom(&b.baseBuiltinFunc) 828 return newSig 829 } 830 831 func (b *builtinCastRealAsStringSig) evalString(event chunk.Event) (res string, isNull bool, err error) { 832 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 833 if isNull || err != nil { 834 return res, isNull, err 835 } 836 837 bits := 64 838 if b.args[0].GetType().Tp == allegrosql.TypeFloat { 839 // b.args[0].EvalReal() casts the value from float32 to float64, for example: 840 // float32(208.867) is cast to float64(208.86700439) 841 // If we strconv.FormatFloat the value with 64bits, the result is incorrect! 842 bits = 32 843 } 844 res, err = types.ProduceStrWithSpecifiedTp(strconv.FormatFloat(val, 'f', -1, bits), b.tp, b.ctx.GetStochastikVars().StmtCtx, false) 845 if err != nil { 846 return res, false, err 847 } 848 return padZeroForBinaryType(res, b.tp, b.ctx) 849 } 850 851 type builtinCastRealAsTimeSig struct { 852 baseBuiltinFunc 853 } 854 855 func (b *builtinCastRealAsTimeSig) Clone() builtinFunc { 856 newSig := &builtinCastRealAsTimeSig{} 857 newSig.cloneFrom(&b.baseBuiltinFunc) 858 return newSig 859 } 860 861 func (b *builtinCastRealAsTimeSig) evalTime(event chunk.Event) (types.Time, bool, error) { 862 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 863 if isNull || err != nil { 864 return types.ZeroTime, true, err 865 } 866 // MyALLEGROSQL compatibility: 0 should not be converted to null, see #11203 867 fv := strconv.FormatFloat(val, 'f', -1, 64) 868 if fv == "0" { 869 return types.ZeroTime, false, nil 870 } 871 sc := b.ctx.GetStochastikVars().StmtCtx 872 res, err := types.ParseTime(sc, fv, b.tp.Tp, int8(b.tp.Decimal)) 873 if err != nil { 874 return types.ZeroTime, true, handleInvalidTimeError(b.ctx, err) 875 } 876 if b.tp.Tp == allegrosql.TypeDate { 877 // Truncate hh:mm:ss part if the type is Date. 878 res.SetCoreTime(types.FromDate(res.Year(), res.Month(), res.Day(), 0, 0, 0, 0)) 879 } 880 return res, false, nil 881 } 882 883 type builtinCastRealAsDurationSig struct { 884 baseBuiltinFunc 885 } 886 887 func (b *builtinCastRealAsDurationSig) Clone() builtinFunc { 888 newSig := &builtinCastRealAsDurationSig{} 889 newSig.cloneFrom(&b.baseBuiltinFunc) 890 return newSig 891 } 892 893 func (b *builtinCastRealAsDurationSig) evalDuration(event chunk.Event) (res types.Duration, isNull bool, err error) { 894 val, isNull, err := b.args[0].EvalReal(b.ctx, event) 895 if isNull || err != nil { 896 return res, isNull, err 897 } 898 res, err = types.ParseDuration(b.ctx.GetStochastikVars().StmtCtx, strconv.FormatFloat(val, 'f', -1, 64), int8(b.tp.Decimal)) 899 if err != nil { 900 if types.ErrTruncatedWrongVal.Equal(err) { 901 err = b.ctx.GetStochastikVars().StmtCtx.HandleTruncate(err) 902 // ZeroDuration of error ErrTruncatedWrongVal needs to be considered NULL. 903 if res == types.ZeroDuration { 904 return res, true, err 905 } 906 } 907 } 908 return res, false, err 909 } 910 911 type builtinCastDecimalAsDecimalSig struct { 912 baseBuiltinCastFunc 913 } 914 915 func (b *builtinCastDecimalAsDecimalSig) Clone() builtinFunc { 916 newSig := &builtinCastDecimalAsDecimalSig{} 917 newSig.cloneFrom(&b.baseBuiltinCastFunc) 918 return newSig 919 } 920 921 func (b *builtinCastDecimalAsDecimalSig) evalDecimal(event chunk.Event) (res *types.MyDecimal, isNull bool, err error) { 922 evalDecimal, isNull, err := b.args[0].EvalDecimal(b.ctx, event) 923 if isNull || err != nil { 924 return res, isNull, err 925 } 926 res = &types.MyDecimal{} 927 if !(b.inUnion && allegrosql.HasUnsignedFlag(b.tp.Flag) && evalDecimal.IsNegative()) { 928 *res = *evalDecimal 929 } 930 sc := b.ctx.GetStochastikVars().StmtCtx 931 res, err = types.ProduceDecWithSpecifiedTp(res, b.tp, sc) 932 return res, false, err 933 } 934 935 type builtinCastDecimalAsIntSig struct { 936 baseBuiltinCastFunc 937 } 938 939 func (b *builtinCastDecimalAsIntSig) Clone() builtinFunc { 940 newSig := &builtinCastDecimalAsIntSig{} 941 newSig.cloneFrom(&b.baseBuiltinCastFunc) 942 return newSig 943 } 944 945 func (b *builtinCastDecimalAsIntSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) { 946 val, isNull, err := b.args[0].EvalDecimal(b.ctx, event) 947 if isNull || err != nil { 948 return res, isNull, err 949 } 950 951 // Round is needed for both unsigned and signed. 952 var to types.MyDecimal 953 err = val.Round(&to, 0, types.ModeHalfEven) 954 if err != nil { 955 return 0, true, err 956 } 957 958 if !allegrosql.HasUnsignedFlag(b.tp.Flag) { 959 res, err = to.ToInt() 960 } else if b.inUnion && to.IsNegative() { 961 res = 0 962 } else { 963 var uintRes uint64 964 uintRes, err = to.ToUint() 965 res = int64(uintRes) 966 } 967 968 if types.ErrOverflow.Equal(err) { 969 warnErr := types.ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", val) 970 err = b.ctx.GetStochastikVars().StmtCtx.HandleOverflow(err, warnErr) 971 } 972 973 return res, false, err 974 } 975 976 type builtinCastDecimalAsStringSig struct { 977 baseBuiltinFunc 978 } 979 980 func (b *builtinCastDecimalAsStringSig) Clone() builtinFunc { 981 newSig := &builtinCastDecimalAsStringSig{} 982 newSig.cloneFrom(&b.baseBuiltinFunc) 983 return newSig 984 } 985 986 func (b *builtinCastDecimalAsStringSig) evalString(event chunk.Event) (res string, isNull bool, err error) { 987 val, isNull, err := b.args[0].EvalDecimal(b.ctx, event) 988 if isNull || err != nil { 989 return res, isNull, err 990 } 991 sc := b.ctx.GetStochastikVars().StmtCtx 992 res, err = types.ProduceStrWithSpecifiedTp(string(val.ToString()), b.tp, sc, false) 993 if err != nil { 994 return res, false, err 995 } 996 return padZeroForBinaryType(res, b.tp, b.ctx) 997 } 998 999 type builtinCastDecimalAsRealSig struct { 1000 baseBuiltinCastFunc 1001 } 1002 1003 func (b *builtinCastDecimalAsRealSig) Clone() builtinFunc { 1004 newSig := &builtinCastDecimalAsRealSig{} 1005 newSig.cloneFrom(&b.baseBuiltinCastFunc) 1006 return newSig 1007 } 1008 1009 func (b *builtinCastDecimalAsRealSig) evalReal(event chunk.Event) (res float64, isNull bool, err error) { 1010 val, isNull, err := b.args[0].EvalDecimal(b.ctx, event) 1011 if isNull || err != nil { 1012 return res, isNull, err 1013 } 1014 if b.inUnion && allegrosql.HasUnsignedFlag(b.tp.Flag) && val.IsNegative() { 1015 res = 0 1016 } else { 1017 res, err = val.ToFloat64() 1018 } 1019 return res, false, err 1020 } 1021 1022 type builtinCastDecimalAsTimeSig struct { 1023 baseBuiltinFunc 1024 } 1025 1026 func (b *builtinCastDecimalAsTimeSig) Clone() builtinFunc { 1027 newSig := &builtinCastDecimalAsTimeSig{} 1028 newSig.cloneFrom(&b.baseBuiltinFunc) 1029 return newSig 1030 } 1031 1032 func (b *builtinCastDecimalAsTimeSig) evalTime(event chunk.Event) (res types.Time, isNull bool, err error) { 1033 val, isNull, err := b.args[0].EvalDecimal(b.ctx, event) 1034 if isNull || err != nil { 1035 return res, isNull, err 1036 } 1037 sc := b.ctx.GetStochastikVars().StmtCtx 1038 res, err = types.ParseTimeFromFloatString(sc, string(val.ToString()), b.tp.Tp, int8(b.tp.Decimal)) 1039 if err != nil { 1040 return types.ZeroTime, true, handleInvalidTimeError(b.ctx, err) 1041 } 1042 if b.tp.Tp == allegrosql.TypeDate { 1043 // Truncate hh:mm:ss part if the type is Date. 1044 res.SetCoreTime(types.FromDate(res.Year(), res.Month(), res.Day(), 0, 0, 0, 0)) 1045 } 1046 return res, false, err 1047 } 1048 1049 type builtinCastDecimalAsDurationSig struct { 1050 baseBuiltinFunc 1051 } 1052 1053 func (b *builtinCastDecimalAsDurationSig) Clone() builtinFunc { 1054 newSig := &builtinCastDecimalAsDurationSig{} 1055 newSig.cloneFrom(&b.baseBuiltinFunc) 1056 return newSig 1057 } 1058 1059 func (b *builtinCastDecimalAsDurationSig) evalDuration(event chunk.Event) (res types.Duration, isNull bool, err error) { 1060 val, isNull, err := b.args[0].EvalDecimal(b.ctx, event) 1061 if isNull || err != nil { 1062 return res, true, err 1063 } 1064 res, err = types.ParseDuration(b.ctx.GetStochastikVars().StmtCtx, string(val.ToString()), int8(b.tp.Decimal)) 1065 if types.ErrTruncatedWrongVal.Equal(err) { 1066 err = b.ctx.GetStochastikVars().StmtCtx.HandleTruncate(err) 1067 // ZeroDuration of error ErrTruncatedWrongVal needs to be considered NULL. 1068 if res == types.ZeroDuration { 1069 return res, true, err 1070 } 1071 } 1072 return res, false, err 1073 } 1074 1075 type builtinCastStringAsStringSig struct { 1076 baseBuiltinFunc 1077 } 1078 1079 func (b *builtinCastStringAsStringSig) Clone() builtinFunc { 1080 newSig := &builtinCastStringAsStringSig{} 1081 newSig.cloneFrom(&b.baseBuiltinFunc) 1082 return newSig 1083 } 1084 1085 func (b *builtinCastStringAsStringSig) evalString(event chunk.Event) (res string, isNull bool, err error) { 1086 res, isNull, err = b.args[0].EvalString(b.ctx, event) 1087 if isNull || err != nil { 1088 return res, isNull, err 1089 } 1090 sc := b.ctx.GetStochastikVars().StmtCtx 1091 res, err = types.ProduceStrWithSpecifiedTp(res, b.tp, sc, false) 1092 if err != nil { 1093 return res, false, err 1094 } 1095 return padZeroForBinaryType(res, b.tp, b.ctx) 1096 } 1097 1098 type builtinCastStringAsIntSig struct { 1099 baseBuiltinCastFunc 1100 } 1101 1102 func (b *builtinCastStringAsIntSig) Clone() builtinFunc { 1103 newSig := &builtinCastStringAsIntSig{} 1104 newSig.cloneFrom(&b.baseBuiltinCastFunc) 1105 return newSig 1106 } 1107 1108 // handleOverflow handles the overflow caused by cast string as int, 1109 // see https://dev.allegrosql.com/doc/refman/5.7/en/out-of-range-and-overflow.html. 1110 // When an out-of-range value is assigned to an integer defCausumn, MyALLEGROSQL stores the value representing the corresponding endpoint of the defCausumn data type range. If it is in select memex, it will return the 1111 // endpoint value with a warning. 1112 func (b *builtinCastStringAsIntSig) handleOverflow(origRes int64, origStr string, origErr error, isNegative bool) (res int64, err error) { 1113 res, err = origRes, origErr 1114 if err == nil { 1115 return 1116 } 1117 1118 sc := b.ctx.GetStochastikVars().StmtCtx 1119 if types.ErrOverflow.Equal(origErr) { 1120 if isNegative { 1121 res = math.MinInt64 1122 } else { 1123 uval := uint64(math.MaxUint64) 1124 res = int64(uval) 1125 } 1126 warnErr := types.ErrTruncatedWrongVal.GenWithStackByArgs("INTEGER", origStr) 1127 err = sc.HandleOverflow(origErr, warnErr) 1128 } 1129 return 1130 } 1131 1132 func (b *builtinCastStringAsIntSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) { 1133 if b.args[0].GetType().Hybrid() || IsBinaryLiteral(b.args[0]) { 1134 return b.args[0].EvalInt(b.ctx, event) 1135 } 1136 val, isNull, err := b.args[0].EvalString(b.ctx, event) 1137 if isNull || err != nil { 1138 return res, isNull, err 1139 } 1140 1141 val = strings.TrimSpace(val) 1142 isNegative := false 1143 if len(val) > 1 && val[0] == '-' { // negative number 1144 isNegative = true 1145 } 1146 1147 var ures uint64 1148 sc := b.ctx.GetStochastikVars().StmtCtx 1149 if !isNegative { 1150 ures, err = types.StrToUint(sc, val, true) 1151 res = int64(ures) 1152 1153 if err == nil && !allegrosql.HasUnsignedFlag(b.tp.Flag) && ures > uint64(math.MaxInt64) { 1154 sc.AppendWarning(types.ErrCastAsSignedOverflow) 1155 } 1156 } else if b.inUnion && allegrosql.HasUnsignedFlag(b.tp.Flag) { 1157 res = 0 1158 } else { 1159 res, err = types.StrToInt(sc, val, true) 1160 if err == nil && allegrosql.HasUnsignedFlag(b.tp.Flag) { 1161 // If overflow, don't append this warnings 1162 sc.AppendWarning(types.ErrCastNegIntAsUnsigned) 1163 } 1164 } 1165 1166 res, err = b.handleOverflow(res, val, err, isNegative) 1167 return res, false, err 1168 } 1169 1170 type builtinCastStringAsRealSig struct { 1171 baseBuiltinCastFunc 1172 } 1173 1174 func (b *builtinCastStringAsRealSig) Clone() builtinFunc { 1175 newSig := &builtinCastStringAsRealSig{} 1176 newSig.cloneFrom(&b.baseBuiltinCastFunc) 1177 return newSig 1178 } 1179 1180 func (b *builtinCastStringAsRealSig) evalReal(event chunk.Event) (res float64, isNull bool, err error) { 1181 if IsBinaryLiteral(b.args[0]) { 1182 return b.args[0].EvalReal(b.ctx, event) 1183 } 1184 val, isNull, err := b.args[0].EvalString(b.ctx, event) 1185 if isNull || err != nil { 1186 return res, isNull, err 1187 } 1188 sctx := b.ctx.GetStochastikVars().StmtCtx 1189 if val == "" && (sctx.InInsertStmt || sctx.InUFIDelateStmt) { 1190 return 0, false, nil 1191 } 1192 sc := b.ctx.GetStochastikVars().StmtCtx 1193 res, err = types.StrToFloat(sc, val, true) 1194 if err != nil { 1195 return 0, false, err 1196 } 1197 if b.inUnion && allegrosql.HasUnsignedFlag(b.tp.Flag) && res < 0 { 1198 res = 0 1199 } 1200 res, err = types.ProduceFloatWithSpecifiedTp(res, b.tp, sc) 1201 return res, false, err 1202 } 1203 1204 type builtinCastStringAsDecimalSig struct { 1205 baseBuiltinCastFunc 1206 } 1207 1208 func (b *builtinCastStringAsDecimalSig) Clone() builtinFunc { 1209 newSig := &builtinCastStringAsDecimalSig{} 1210 newSig.cloneFrom(&b.baseBuiltinCastFunc) 1211 return newSig 1212 } 1213 1214 func (b *builtinCastStringAsDecimalSig) evalDecimal(event chunk.Event) (res *types.MyDecimal, isNull bool, err error) { 1215 if IsBinaryLiteral(b.args[0]) { 1216 return b.args[0].EvalDecimal(b.ctx, event) 1217 } 1218 val, isNull, err := b.args[0].EvalString(b.ctx, event) 1219 if isNull || err != nil { 1220 return res, isNull, err 1221 } 1222 val = strings.TrimSpace(val) 1223 isNegative := len(val) > 1 && val[0] == '-' 1224 res = new(types.MyDecimal) 1225 sc := b.ctx.GetStochastikVars().StmtCtx 1226 if !(b.inUnion && allegrosql.HasUnsignedFlag(b.tp.Flag) && isNegative) { 1227 err = sc.HandleTruncate(res.FromString([]byte(val))) 1228 if err != nil { 1229 return res, false, err 1230 } 1231 } 1232 res, err = types.ProduceDecWithSpecifiedTp(res, b.tp, sc) 1233 return res, false, err 1234 } 1235 1236 type builtinCastStringAsTimeSig struct { 1237 baseBuiltinFunc 1238 } 1239 1240 func (b *builtinCastStringAsTimeSig) Clone() builtinFunc { 1241 newSig := &builtinCastStringAsTimeSig{} 1242 newSig.cloneFrom(&b.baseBuiltinFunc) 1243 return newSig 1244 } 1245 1246 func (b *builtinCastStringAsTimeSig) evalTime(event chunk.Event) (res types.Time, isNull bool, err error) { 1247 val, isNull, err := b.args[0].EvalString(b.ctx, event) 1248 if isNull || err != nil { 1249 return res, isNull, err 1250 } 1251 sc := b.ctx.GetStochastikVars().StmtCtx 1252 res, err = types.ParseTime(sc, val, b.tp.Tp, int8(b.tp.Decimal)) 1253 if err != nil { 1254 return types.ZeroTime, true, handleInvalidTimeError(b.ctx, err) 1255 } 1256 if b.tp.Tp == allegrosql.TypeDate { 1257 // Truncate hh:mm:ss part if the type is Date. 1258 res.SetCoreTime(types.FromDate(res.Year(), res.Month(), res.Day(), 0, 0, 0, 0)) 1259 } 1260 return res, false, nil 1261 } 1262 1263 type builtinCastStringAsDurationSig struct { 1264 baseBuiltinFunc 1265 } 1266 1267 func (b *builtinCastStringAsDurationSig) Clone() builtinFunc { 1268 newSig := &builtinCastStringAsDurationSig{} 1269 newSig.cloneFrom(&b.baseBuiltinFunc) 1270 return newSig 1271 } 1272 1273 func (b *builtinCastStringAsDurationSig) evalDuration(event chunk.Event) (res types.Duration, isNull bool, err error) { 1274 val, isNull, err := b.args[0].EvalString(b.ctx, event) 1275 if isNull || err != nil { 1276 return res, isNull, err 1277 } 1278 res, err = types.ParseDuration(b.ctx.GetStochastikVars().StmtCtx, val, int8(b.tp.Decimal)) 1279 if types.ErrTruncatedWrongVal.Equal(err) { 1280 sc := b.ctx.GetStochastikVars().StmtCtx 1281 err = sc.HandleTruncate(err) 1282 // ZeroDuration of error ErrTruncatedWrongVal needs to be considered NULL. 1283 if res == types.ZeroDuration { 1284 return res, true, err 1285 } 1286 } 1287 return res, false, err 1288 } 1289 1290 type builtinCastTimeAsTimeSig struct { 1291 baseBuiltinFunc 1292 } 1293 1294 func (b *builtinCastTimeAsTimeSig) Clone() builtinFunc { 1295 newSig := &builtinCastTimeAsTimeSig{} 1296 newSig.cloneFrom(&b.baseBuiltinFunc) 1297 return newSig 1298 } 1299 1300 func (b *builtinCastTimeAsTimeSig) evalTime(event chunk.Event) (res types.Time, isNull bool, err error) { 1301 res, isNull, err = b.args[0].EvalTime(b.ctx, event) 1302 if isNull || err != nil { 1303 return res, isNull, err 1304 } 1305 1306 sc := b.ctx.GetStochastikVars().StmtCtx 1307 if res, err = res.Convert(sc, b.tp.Tp); err != nil { 1308 return types.ZeroTime, true, handleInvalidTimeError(b.ctx, err) 1309 } 1310 res, err = res.RoundFrac(sc, int8(b.tp.Decimal)) 1311 if b.tp.Tp == allegrosql.TypeDate { 1312 // Truncate hh:mm:ss part if the type is Date. 1313 res.SetCoreTime(types.FromDate(res.Year(), res.Month(), res.Day(), 0, 0, 0, 0)) 1314 res.SetType(b.tp.Tp) 1315 } 1316 return res, false, err 1317 } 1318 1319 type builtinCastTimeAsIntSig struct { 1320 baseBuiltinCastFunc 1321 } 1322 1323 func (b *builtinCastTimeAsIntSig) Clone() builtinFunc { 1324 newSig := &builtinCastTimeAsIntSig{} 1325 newSig.cloneFrom(&b.baseBuiltinCastFunc) 1326 return newSig 1327 } 1328 1329 func (b *builtinCastTimeAsIntSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) { 1330 val, isNull, err := b.args[0].EvalTime(b.ctx, event) 1331 if isNull || err != nil { 1332 return res, isNull, err 1333 } 1334 sc := b.ctx.GetStochastikVars().StmtCtx 1335 t, err := val.RoundFrac(sc, types.DefaultFsp) 1336 if err != nil { 1337 return res, false, err 1338 } 1339 res, err = t.ToNumber().ToInt() 1340 return res, false, err 1341 } 1342 1343 type builtinCastTimeAsRealSig struct { 1344 baseBuiltinCastFunc 1345 } 1346 1347 func (b *builtinCastTimeAsRealSig) Clone() builtinFunc { 1348 newSig := &builtinCastTimeAsRealSig{} 1349 newSig.cloneFrom(&b.baseBuiltinCastFunc) 1350 return newSig 1351 } 1352 1353 func (b *builtinCastTimeAsRealSig) evalReal(event chunk.Event) (res float64, isNull bool, err error) { 1354 val, isNull, err := b.args[0].EvalTime(b.ctx, event) 1355 if isNull || err != nil { 1356 return res, isNull, err 1357 } 1358 res, err = val.ToNumber().ToFloat64() 1359 return res, false, err 1360 } 1361 1362 type builtinCastTimeAsDecimalSig struct { 1363 baseBuiltinCastFunc 1364 } 1365 1366 func (b *builtinCastTimeAsDecimalSig) Clone() builtinFunc { 1367 newSig := &builtinCastTimeAsDecimalSig{} 1368 newSig.cloneFrom(&b.baseBuiltinCastFunc) 1369 return newSig 1370 } 1371 1372 func (b *builtinCastTimeAsDecimalSig) evalDecimal(event chunk.Event) (res *types.MyDecimal, isNull bool, err error) { 1373 val, isNull, err := b.args[0].EvalTime(b.ctx, event) 1374 if isNull || err != nil { 1375 return res, isNull, err 1376 } 1377 sc := b.ctx.GetStochastikVars().StmtCtx 1378 res, err = types.ProduceDecWithSpecifiedTp(val.ToNumber(), b.tp, sc) 1379 return res, false, err 1380 } 1381 1382 type builtinCastTimeAsStringSig struct { 1383 baseBuiltinFunc 1384 } 1385 1386 func (b *builtinCastTimeAsStringSig) Clone() builtinFunc { 1387 newSig := &builtinCastTimeAsStringSig{} 1388 newSig.cloneFrom(&b.baseBuiltinFunc) 1389 return newSig 1390 } 1391 1392 func (b *builtinCastTimeAsStringSig) evalString(event chunk.Event) (res string, isNull bool, err error) { 1393 val, isNull, err := b.args[0].EvalTime(b.ctx, event) 1394 if isNull || err != nil { 1395 return res, isNull, err 1396 } 1397 sc := b.ctx.GetStochastikVars().StmtCtx 1398 res, err = types.ProduceStrWithSpecifiedTp(val.String(), b.tp, sc, false) 1399 if err != nil { 1400 return res, false, err 1401 } 1402 return padZeroForBinaryType(res, b.tp, b.ctx) 1403 } 1404 1405 type builtinCastTimeAsDurationSig struct { 1406 baseBuiltinFunc 1407 } 1408 1409 func (b *builtinCastTimeAsDurationSig) Clone() builtinFunc { 1410 newSig := &builtinCastTimeAsDurationSig{} 1411 newSig.cloneFrom(&b.baseBuiltinFunc) 1412 return newSig 1413 } 1414 1415 func (b *builtinCastTimeAsDurationSig) evalDuration(event chunk.Event) (res types.Duration, isNull bool, err error) { 1416 val, isNull, err := b.args[0].EvalTime(b.ctx, event) 1417 if isNull || err != nil { 1418 return res, isNull, err 1419 } 1420 res, err = val.ConvertToDuration() 1421 if err != nil { 1422 return res, false, err 1423 } 1424 res, err = res.RoundFrac(int8(b.tp.Decimal)) 1425 return res, false, err 1426 } 1427 1428 type builtinCastDurationAsDurationSig struct { 1429 baseBuiltinFunc 1430 } 1431 1432 func (b *builtinCastDurationAsDurationSig) Clone() builtinFunc { 1433 newSig := &builtinCastDurationAsDurationSig{} 1434 newSig.cloneFrom(&b.baseBuiltinFunc) 1435 return newSig 1436 } 1437 1438 func (b *builtinCastDurationAsDurationSig) evalDuration(event chunk.Event) (res types.Duration, isNull bool, err error) { 1439 res, isNull, err = b.args[0].EvalDuration(b.ctx, event) 1440 if isNull || err != nil { 1441 return res, isNull, err 1442 } 1443 res, err = res.RoundFrac(int8(b.tp.Decimal)) 1444 return res, false, err 1445 } 1446 1447 type builtinCastDurationAsIntSig struct { 1448 baseBuiltinCastFunc 1449 } 1450 1451 func (b *builtinCastDurationAsIntSig) Clone() builtinFunc { 1452 newSig := &builtinCastDurationAsIntSig{} 1453 newSig.cloneFrom(&b.baseBuiltinCastFunc) 1454 return newSig 1455 } 1456 1457 func (b *builtinCastDurationAsIntSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) { 1458 val, isNull, err := b.args[0].EvalDuration(b.ctx, event) 1459 if isNull || err != nil { 1460 return res, isNull, err 1461 } 1462 dur, err := val.RoundFrac(types.DefaultFsp) 1463 if err != nil { 1464 return res, false, err 1465 } 1466 res, err = dur.ToNumber().ToInt() 1467 return res, false, err 1468 } 1469 1470 type builtinCastDurationAsRealSig struct { 1471 baseBuiltinCastFunc 1472 } 1473 1474 func (b *builtinCastDurationAsRealSig) Clone() builtinFunc { 1475 newSig := &builtinCastDurationAsRealSig{} 1476 newSig.cloneFrom(&b.baseBuiltinCastFunc) 1477 return newSig 1478 } 1479 1480 func (b *builtinCastDurationAsRealSig) evalReal(event chunk.Event) (res float64, isNull bool, err error) { 1481 val, isNull, err := b.args[0].EvalDuration(b.ctx, event) 1482 if isNull || err != nil { 1483 return res, isNull, err 1484 } 1485 if val.Fsp, err = types.CheckFsp(int(val.Fsp)); err != nil { 1486 return res, false, err 1487 } 1488 res, err = val.ToNumber().ToFloat64() 1489 return res, false, err 1490 } 1491 1492 type builtinCastDurationAsDecimalSig struct { 1493 baseBuiltinCastFunc 1494 } 1495 1496 func (b *builtinCastDurationAsDecimalSig) Clone() builtinFunc { 1497 newSig := &builtinCastDurationAsDecimalSig{} 1498 newSig.cloneFrom(&b.baseBuiltinCastFunc) 1499 return newSig 1500 } 1501 1502 func (b *builtinCastDurationAsDecimalSig) evalDecimal(event chunk.Event) (res *types.MyDecimal, isNull bool, err error) { 1503 val, isNull, err := b.args[0].EvalDuration(b.ctx, event) 1504 if isNull || err != nil { 1505 return res, isNull, err 1506 } 1507 if val.Fsp, err = types.CheckFsp(int(val.Fsp)); err != nil { 1508 return res, false, err 1509 } 1510 sc := b.ctx.GetStochastikVars().StmtCtx 1511 res, err = types.ProduceDecWithSpecifiedTp(val.ToNumber(), b.tp, sc) 1512 return res, false, err 1513 } 1514 1515 type builtinCastDurationAsStringSig struct { 1516 baseBuiltinFunc 1517 } 1518 1519 func (b *builtinCastDurationAsStringSig) Clone() builtinFunc { 1520 newSig := &builtinCastDurationAsStringSig{} 1521 newSig.cloneFrom(&b.baseBuiltinFunc) 1522 return newSig 1523 } 1524 1525 func (b *builtinCastDurationAsStringSig) evalString(event chunk.Event) (res string, isNull bool, err error) { 1526 val, isNull, err := b.args[0].EvalDuration(b.ctx, event) 1527 if isNull || err != nil { 1528 return res, isNull, err 1529 } 1530 sc := b.ctx.GetStochastikVars().StmtCtx 1531 res, err = types.ProduceStrWithSpecifiedTp(val.String(), b.tp, sc, false) 1532 if err != nil { 1533 return res, false, err 1534 } 1535 return padZeroForBinaryType(res, b.tp, b.ctx) 1536 } 1537 1538 func padZeroForBinaryType(s string, tp *types.FieldType, ctx stochastikctx.Context) (string, bool, error) { 1539 flen := tp.Flen 1540 if tp.Tp == allegrosql.TypeString && types.IsBinaryStr(tp) && len(s) < flen { 1541 sc := ctx.GetStochastikVars().StmtCtx 1542 valStr, _ := ctx.GetStochastikVars().GetSystemVar(variable.MaxAllowedPacket) 1543 maxAllowedPacket, err := strconv.ParseUint(valStr, 10, 64) 1544 if err != nil { 1545 return "", false, errors.Trace(err) 1546 } 1547 if uint64(flen) > maxAllowedPacket { 1548 sc.AppendWarning(errWarnAllowedPacketOverflowed.GenWithStackByArgs("cast_as_binary", maxAllowedPacket)) 1549 return "", true, nil 1550 } 1551 padding := make([]byte, flen-len(s)) 1552 s = string(append([]byte(s), padding...)) 1553 } 1554 return s, false, nil 1555 } 1556 1557 type builtinCastDurationAsTimeSig struct { 1558 baseBuiltinFunc 1559 } 1560 1561 func (b *builtinCastDurationAsTimeSig) Clone() builtinFunc { 1562 newSig := &builtinCastDurationAsTimeSig{} 1563 newSig.cloneFrom(&b.baseBuiltinFunc) 1564 return newSig 1565 } 1566 1567 func (b *builtinCastDurationAsTimeSig) evalTime(event chunk.Event) (res types.Time, isNull bool, err error) { 1568 val, isNull, err := b.args[0].EvalDuration(b.ctx, event) 1569 if isNull || err != nil { 1570 return res, isNull, err 1571 } 1572 sc := b.ctx.GetStochastikVars().StmtCtx 1573 res, err = val.ConvertToTime(sc, b.tp.Tp) 1574 if err != nil { 1575 return types.ZeroTime, true, handleInvalidTimeError(b.ctx, err) 1576 } 1577 res, err = res.RoundFrac(sc, int8(b.tp.Decimal)) 1578 return res, false, err 1579 } 1580 1581 type builtinCastJSONAsJSONSig struct { 1582 baseBuiltinFunc 1583 } 1584 1585 func (b *builtinCastJSONAsJSONSig) Clone() builtinFunc { 1586 newSig := &builtinCastJSONAsJSONSig{} 1587 newSig.cloneFrom(&b.baseBuiltinFunc) 1588 return newSig 1589 } 1590 1591 func (b *builtinCastJSONAsJSONSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) { 1592 return b.args[0].EvalJSON(b.ctx, event) 1593 } 1594 1595 type builtinCastJSONAsIntSig struct { 1596 baseBuiltinCastFunc 1597 } 1598 1599 func (b *builtinCastJSONAsIntSig) Clone() builtinFunc { 1600 newSig := &builtinCastJSONAsIntSig{} 1601 newSig.cloneFrom(&b.baseBuiltinCastFunc) 1602 return newSig 1603 } 1604 1605 func (b *builtinCastJSONAsIntSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) { 1606 val, isNull, err := b.args[0].EvalJSON(b.ctx, event) 1607 if isNull || err != nil { 1608 return res, isNull, err 1609 } 1610 sc := b.ctx.GetStochastikVars().StmtCtx 1611 res, err = types.ConvertJSONToInt(sc, val, allegrosql.HasUnsignedFlag(b.tp.Flag)) 1612 return 1613 } 1614 1615 type builtinCastJSONAsRealSig struct { 1616 baseBuiltinCastFunc 1617 } 1618 1619 func (b *builtinCastJSONAsRealSig) Clone() builtinFunc { 1620 newSig := &builtinCastJSONAsRealSig{} 1621 newSig.cloneFrom(&b.baseBuiltinCastFunc) 1622 return newSig 1623 } 1624 1625 func (b *builtinCastJSONAsRealSig) evalReal(event chunk.Event) (res float64, isNull bool, err error) { 1626 val, isNull, err := b.args[0].EvalJSON(b.ctx, event) 1627 if isNull || err != nil { 1628 return res, isNull, err 1629 } 1630 sc := b.ctx.GetStochastikVars().StmtCtx 1631 res, err = types.ConvertJSONToFloat(sc, val) 1632 return 1633 } 1634 1635 type builtinCastJSONAsDecimalSig struct { 1636 baseBuiltinCastFunc 1637 } 1638 1639 func (b *builtinCastJSONAsDecimalSig) Clone() builtinFunc { 1640 newSig := &builtinCastJSONAsDecimalSig{} 1641 newSig.cloneFrom(&b.baseBuiltinCastFunc) 1642 return newSig 1643 } 1644 1645 func (b *builtinCastJSONAsDecimalSig) evalDecimal(event chunk.Event) (res *types.MyDecimal, isNull bool, err error) { 1646 val, isNull, err := b.args[0].EvalJSON(b.ctx, event) 1647 if isNull || err != nil { 1648 return res, isNull, err 1649 } 1650 sc := b.ctx.GetStochastikVars().StmtCtx 1651 res, err = types.ConvertJSONToDecimal(sc, val) 1652 if err != nil { 1653 return res, false, err 1654 } 1655 res, err = types.ProduceDecWithSpecifiedTp(res, b.tp, sc) 1656 return res, false, err 1657 } 1658 1659 type builtinCastJSONAsStringSig struct { 1660 baseBuiltinFunc 1661 } 1662 1663 func (b *builtinCastJSONAsStringSig) Clone() builtinFunc { 1664 newSig := &builtinCastJSONAsStringSig{} 1665 newSig.cloneFrom(&b.baseBuiltinFunc) 1666 return newSig 1667 } 1668 1669 func (b *builtinCastJSONAsStringSig) evalString(event chunk.Event) (res string, isNull bool, err error) { 1670 val, isNull, err := b.args[0].EvalJSON(b.ctx, event) 1671 if isNull || err != nil { 1672 return res, isNull, err 1673 } 1674 return val.String(), false, nil 1675 } 1676 1677 type builtinCastJSONAsTimeSig struct { 1678 baseBuiltinFunc 1679 } 1680 1681 func (b *builtinCastJSONAsTimeSig) Clone() builtinFunc { 1682 newSig := &builtinCastJSONAsTimeSig{} 1683 newSig.cloneFrom(&b.baseBuiltinFunc) 1684 return newSig 1685 } 1686 1687 func (b *builtinCastJSONAsTimeSig) evalTime(event chunk.Event) (res types.Time, isNull bool, err error) { 1688 val, isNull, err := b.args[0].EvalJSON(b.ctx, event) 1689 if isNull || err != nil { 1690 return res, isNull, err 1691 } 1692 s, err := val.Unquote() 1693 if err != nil { 1694 return res, false, err 1695 } 1696 sc := b.ctx.GetStochastikVars().StmtCtx 1697 res, err = types.ParseTime(sc, s, b.tp.Tp, int8(b.tp.Decimal)) 1698 if err != nil { 1699 return types.ZeroTime, true, handleInvalidTimeError(b.ctx, err) 1700 } 1701 if b.tp.Tp == allegrosql.TypeDate { 1702 // Truncate hh:mm:ss part if the type is Date. 1703 res.SetCoreTime(types.FromDate(res.Year(), res.Month(), res.Day(), 0, 0, 0, 0)) 1704 } 1705 return 1706 } 1707 1708 type builtinCastJSONAsDurationSig struct { 1709 baseBuiltinFunc 1710 } 1711 1712 func (b *builtinCastJSONAsDurationSig) Clone() builtinFunc { 1713 newSig := &builtinCastJSONAsDurationSig{} 1714 newSig.cloneFrom(&b.baseBuiltinFunc) 1715 return newSig 1716 } 1717 1718 func (b *builtinCastJSONAsDurationSig) evalDuration(event chunk.Event) (res types.Duration, isNull bool, err error) { 1719 val, isNull, err := b.args[0].EvalJSON(b.ctx, event) 1720 if isNull || err != nil { 1721 return res, isNull, err 1722 } 1723 s, err := val.Unquote() 1724 if err != nil { 1725 return res, false, err 1726 } 1727 res, err = types.ParseDuration(b.ctx.GetStochastikVars().StmtCtx, s, int8(b.tp.Decimal)) 1728 if types.ErrTruncatedWrongVal.Equal(err) { 1729 sc := b.ctx.GetStochastikVars().StmtCtx 1730 err = sc.HandleTruncate(err) 1731 } 1732 return 1733 } 1734 1735 // inCastContext is stochastik key type that indicates whether executing 1736 // in special cast context that negative unsigned num will be zero. 1737 type inCastContext int 1738 1739 func (i inCastContext) String() string { 1740 return "__cast_ctx" 1741 } 1742 1743 // inUnionCastContext is stochastik key value that indicates whether executing in 1744 // union cast context. 1745 // @see BuildCastFunction4Union 1746 const inUnionCastContext inCastContext = 0 1747 1748 // hasSpecialCast checks if this expr has its own special cast function. 1749 // for example(#9713): when doing arithmetic using results of function DayName, 1750 // "Monday" should be regarded as 0, "Tuesday" should be regarded as 1 and so on. 1751 func hasSpecialCast(ctx stochastikctx.Context, expr Expression, tp *types.FieldType) bool { 1752 switch f := expr.(type) { 1753 case *ScalarFunction: 1754 switch f.FuncName.L { 1755 case ast.DayName: 1756 switch tp.EvalType() { 1757 case types.ETInt, types.ETReal: 1758 return true 1759 } 1760 } 1761 } 1762 return false 1763 } 1764 1765 // BuildCastFunction4Union build a implicitly CAST ScalarFunction from the Union 1766 // Expression. 1767 func BuildCastFunction4Union(ctx stochastikctx.Context, expr Expression, tp *types.FieldType) (res Expression) { 1768 ctx.SetValue(inUnionCastContext, struct{}{}) 1769 defer func() { 1770 ctx.SetValue(inUnionCastContext, nil) 1771 }() 1772 return BuildCastFunction(ctx, expr, tp) 1773 } 1774 1775 // BuildCastFunction builds a CAST ScalarFunction from the Expression. 1776 func BuildCastFunction(ctx stochastikctx.Context, expr Expression, tp *types.FieldType) (res Expression) { 1777 if hasSpecialCast(ctx, expr, tp) { 1778 return expr 1779 } 1780 1781 var fc functionClass 1782 switch tp.EvalType() { 1783 case types.ETInt: 1784 fc = &castAsIntFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp} 1785 case types.ETDecimal: 1786 fc = &castAsDecimalFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp} 1787 case types.ETReal: 1788 fc = &castAsRealFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp} 1789 case types.ETDatetime, types.ETTimestamp: 1790 fc = &castAsTimeFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp} 1791 case types.ETDuration: 1792 fc = &castAsDurationFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp} 1793 case types.ETJson: 1794 fc = &castAsJSONFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp} 1795 case types.ETString: 1796 fc = &castAsStringFunctionClass{baseFunctionClass{ast.Cast, 1, 1}, tp} 1797 } 1798 f, err := fc.getFunction(ctx, []Expression{expr}) 1799 terror.Log(err) 1800 res = &ScalarFunction{ 1801 FuncName: perceptron.NewCIStr(ast.Cast), 1802 RetType: tp, 1803 Function: f, 1804 } 1805 // We do not fold CAST if the eval type of this scalar function is ETJson 1806 // since we may reset the flag of the field type of CastAsJson later which 1807 // would affect the evaluation of it. 1808 if tp.EvalType() != types.ETJson { 1809 res = FoldConstant(res) 1810 } 1811 return res 1812 } 1813 1814 // WrapWithCastAsInt wraps `expr` with `cast` if the return type of expr is not 1815 // type int, otherwise, returns `expr` directly. 1816 func WrapWithCastAsInt(ctx stochastikctx.Context, expr Expression) Expression { 1817 if expr.GetType().EvalType() == types.ETInt { 1818 return expr 1819 } 1820 tp := types.NewFieldType(allegrosql.TypeLonglong) 1821 tp.Flen, tp.Decimal = expr.GetType().Flen, 0 1822 types.SetBinChsClnFlag(tp) 1823 tp.Flag |= expr.GetType().Flag & allegrosql.UnsignedFlag 1824 return BuildCastFunction(ctx, expr, tp) 1825 } 1826 1827 // WrapWithCastAsReal wraps `expr` with `cast` if the return type of expr is not 1828 // type real, otherwise, returns `expr` directly. 1829 func WrapWithCastAsReal(ctx stochastikctx.Context, expr Expression) Expression { 1830 if expr.GetType().EvalType() == types.ETReal { 1831 return expr 1832 } 1833 tp := types.NewFieldType(allegrosql.TypeDouble) 1834 tp.Flen, tp.Decimal = allegrosql.MaxRealWidth, types.UnspecifiedLength 1835 types.SetBinChsClnFlag(tp) 1836 tp.Flag |= expr.GetType().Flag & allegrosql.UnsignedFlag 1837 return BuildCastFunction(ctx, expr, tp) 1838 } 1839 1840 // WrapWithCastAsDecimal wraps `expr` with `cast` if the return type of expr is 1841 // not type decimal, otherwise, returns `expr` directly. 1842 func WrapWithCastAsDecimal(ctx stochastikctx.Context, expr Expression) Expression { 1843 if expr.GetType().EvalType() == types.ETDecimal { 1844 return expr 1845 } 1846 tp := types.NewFieldType(allegrosql.TypeNewDecimal) 1847 tp.Flen, tp.Decimal = expr.GetType().Flen, expr.GetType().Decimal 1848 if expr.GetType().EvalType() == types.ETInt { 1849 tp.Flen = allegrosql.MaxIntWidth 1850 } 1851 types.SetBinChsClnFlag(tp) 1852 tp.Flag |= expr.GetType().Flag & allegrosql.UnsignedFlag 1853 return BuildCastFunction(ctx, expr, tp) 1854 } 1855 1856 // WrapWithCastAsString wraps `expr` with `cast` if the return type of expr is 1857 // not type string, otherwise, returns `expr` directly. 1858 func WrapWithCastAsString(ctx stochastikctx.Context, expr Expression) Expression { 1859 exprTp := expr.GetType() 1860 if exprTp.EvalType() == types.ETString { 1861 return expr 1862 } 1863 argLen := exprTp.Flen 1864 // If expr is decimal, we should take the decimal point and negative sign 1865 // into consideration, so we set `expr.GetType().Flen + 2` as the `argLen`. 1866 // Since the length of float and double is not accurate, we do not handle 1867 // them. 1868 if exprTp.Tp == allegrosql.TypeNewDecimal && argLen != int(types.UnspecifiedFsp) { 1869 argLen += 2 1870 } 1871 if exprTp.EvalType() == types.ETInt { 1872 argLen = allegrosql.MaxIntWidth 1873 } 1874 tp := types.NewFieldType(allegrosql.TypeVarString) 1875 tp.Charset, tp.DefCauslate = expr.CharsetAndDefCauslation(ctx) 1876 tp.Flen, tp.Decimal = argLen, types.UnspecifiedLength 1877 return BuildCastFunction(ctx, expr, tp) 1878 } 1879 1880 // WrapWithCastAsTime wraps `expr` with `cast` if the return type of expr is not 1881 // same as type of the specified `tp` , otherwise, returns `expr` directly. 1882 func WrapWithCastAsTime(ctx stochastikctx.Context, expr Expression, tp *types.FieldType) Expression { 1883 exprTp := expr.GetType().Tp 1884 if tp.Tp == exprTp { 1885 return expr 1886 } else if (exprTp == allegrosql.TypeDate || exprTp == allegrosql.TypeTimestamp) && tp.Tp == allegrosql.TypeDatetime { 1887 return expr 1888 } 1889 switch x := expr.GetType(); x.Tp { 1890 case allegrosql.TypeDatetime, allegrosql.TypeTimestamp, allegrosql.TypeDate, allegrosql.TypeDuration: 1891 tp.Decimal = x.Decimal 1892 default: 1893 tp.Decimal = int(types.MaxFsp) 1894 } 1895 switch tp.Tp { 1896 case allegrosql.TypeDate: 1897 tp.Flen = allegrosql.MaxDateWidth 1898 case allegrosql.TypeDatetime, allegrosql.TypeTimestamp: 1899 tp.Flen = allegrosql.MaxDatetimeWidthNoFsp 1900 if tp.Decimal > 0 { 1901 tp.Flen = tp.Flen + 1 + tp.Decimal 1902 } 1903 } 1904 types.SetBinChsClnFlag(tp) 1905 return BuildCastFunction(ctx, expr, tp) 1906 } 1907 1908 // WrapWithCastAsDuration wraps `expr` with `cast` if the return type of expr is 1909 // not type duration, otherwise, returns `expr` directly. 1910 func WrapWithCastAsDuration(ctx stochastikctx.Context, expr Expression) Expression { 1911 if expr.GetType().Tp == allegrosql.TypeDuration { 1912 return expr 1913 } 1914 tp := types.NewFieldType(allegrosql.TypeDuration) 1915 switch x := expr.GetType(); x.Tp { 1916 case allegrosql.TypeDatetime, allegrosql.TypeTimestamp, allegrosql.TypeDate: 1917 tp.Decimal = x.Decimal 1918 default: 1919 tp.Decimal = int(types.MaxFsp) 1920 } 1921 tp.Flen = allegrosql.MaxDurationWidthNoFsp 1922 if tp.Decimal > 0 { 1923 tp.Flen = tp.Flen + 1 + tp.Decimal 1924 } 1925 return BuildCastFunction(ctx, expr, tp) 1926 } 1927 1928 // WrapWithCastAsJSON wraps `expr` with `cast` if the return type of expr is not 1929 // type json, otherwise, returns `expr` directly. 1930 func WrapWithCastAsJSON(ctx stochastikctx.Context, expr Expression) Expression { 1931 if expr.GetType().Tp == allegrosql.TypeJSON && !allegrosql.HasParseToJSONFlag(expr.GetType().Flag) { 1932 return expr 1933 } 1934 tp := &types.FieldType{ 1935 Tp: allegrosql.TypeJSON, 1936 Flen: 12582912, // FIXME: Here the Flen is not trusted. 1937 Decimal: 0, 1938 Charset: allegrosql.DefaultCharset, 1939 DefCauslate: allegrosql.DefaultDefCauslationName, 1940 Flag: allegrosql.BinaryFlag, 1941 } 1942 return BuildCastFunction(ctx, expr, tp) 1943 }