github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/function/func_binary.go (about) 1 // Copyright 2021 - 2022 Matrix Origin 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 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package function 16 17 import ( 18 "bytes" 19 "context" 20 "crypto/sha256" 21 "crypto/sha512" 22 "encoding/hex" 23 "fmt" 24 "math" 25 "strconv" 26 "strings" 27 "time" 28 29 "github.com/matrixorigin/matrixone/pkg/common/moerr" 30 "github.com/matrixorigin/matrixone/pkg/container/bytejson" 31 "github.com/matrixorigin/matrixone/pkg/container/types" 32 "github.com/matrixorigin/matrixone/pkg/container/vector" 33 "github.com/matrixorigin/matrixone/pkg/sql/plan/function/functionUtil" 34 "github.com/matrixorigin/matrixone/pkg/util/fault" 35 "github.com/matrixorigin/matrixone/pkg/vectorize/floor" 36 "github.com/matrixorigin/matrixone/pkg/vectorize/format" 37 "github.com/matrixorigin/matrixone/pkg/vectorize/instr" 38 "github.com/matrixorigin/matrixone/pkg/vectorize/moarray" 39 "github.com/matrixorigin/matrixone/pkg/vm/process" 40 "golang.org/x/exp/constraints" 41 ) 42 43 func AddFaultPoint(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 44 for i := 0; i < 5; i++ { 45 if ivecs[i].IsConstNull() || !ivecs[i].IsConst() { 46 return moerr.NewInvalidArg(proc.Ctx, "AddFaultPoint", "not scalar") 47 } 48 } 49 50 name, _ := vector.GenerateFunctionStrParameter(ivecs[0]).GetStrValue(0) 51 freq, _ := vector.GenerateFunctionStrParameter(ivecs[1]).GetStrValue(0) 52 action, _ := vector.GenerateFunctionStrParameter(ivecs[2]).GetStrValue(0) 53 iarg, _ := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[3]).GetValue(0) 54 sarg, _ := vector.GenerateFunctionStrParameter(ivecs[4]).GetStrValue(0) 55 56 rs := vector.MustFunctionResult[bool](result) 57 58 if err = fault.AddFaultPoint(proc.Ctx, string(name), string(freq), string(action), iarg, string(sarg)); err != nil { 59 return err 60 } 61 if err = rs.Append(true, false); err != nil { 62 return 63 } 64 return nil 65 } 66 67 type mathMultiT interface { 68 constraints.Integer | constraints.Float | types.Decimal64 | types.Decimal128 69 } 70 71 type mathMultiFun[T mathMultiT] func(T, int64) T 72 73 func generalMathMulti[T mathMultiT](funcName string, ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int, 74 cb mathMultiFun[T]) (err error) { 75 digits := int64(0) 76 if len(ivecs) > 1 { 77 if ivecs[1].IsConstNull() || !ivecs[1].IsConst() { 78 return moerr.NewInvalidArg(proc.Ctx, fmt.Sprintf("the second argument of the %s", funcName), "not const") 79 } 80 digits = vector.MustFixedCol[int64](ivecs[1])[0] 81 } 82 83 return opUnaryFixedToFixed[T, T](ivecs, result, proc, length, func(x T) T { 84 return cb(x, digits) 85 }) 86 } 87 88 func CeilStr(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 89 digits := int64(0) 90 if len(ivecs) > 1 { 91 if !ivecs[1].IsConst() || ivecs[1].GetType().Oid != types.T_int64 { 92 return moerr.NewInvalidArg(proc.Ctx, fmt.Sprintf("the second argument of the %s", "ceil"), "not const") 93 } 94 digits = vector.MustFixedCol[int64](ivecs[1])[0] 95 } 96 97 return opUnaryStrToFixedWithErrorCheck[float64](ivecs, result, proc, length, func(v string) (float64, error) { 98 floatVal, err1 := strconv.ParseFloat(v, 64) 99 if err1 != nil { 100 return 0, err1 101 } 102 return ceilFloat64(floatVal, digits), nil 103 }) 104 } 105 106 func ceilInt64(x, digits int64) int64 { 107 switch { 108 case digits >= 0: 109 return x 110 case digits > -floor.MaxInt64digits: 111 scale := int64(floor.ScaleTable[-digits]) 112 t := x % scale 113 s := x 114 if t != 0 { 115 s -= t 116 if s >= 0 && x > 0 { 117 x = (s + scale) / scale * scale 118 } else { 119 x = s 120 } 121 } 122 case digits <= -floor.MaxInt64digits: 123 x = 0 124 } 125 return x 126 } 127 128 func ceilUint64(x uint64, digits int64) uint64 { 129 switch { 130 case digits >= 0: 131 return x 132 case digits > -floor.MaxUint64digits: 133 scale := floor.ScaleTable[-digits] 134 t := x % scale 135 s := x 136 if t != 0 { 137 s -= t 138 x = (s + scale) / scale * scale 139 } 140 case digits <= -floor.MaxUint64digits: 141 x = 0 142 } 143 return x 144 } 145 146 func ceilFloat64(x float64, digits int64) float64 { 147 if digits == 0 { 148 return math.Ceil(x) 149 } 150 scale := math.Pow10(int(digits)) 151 value := x * scale 152 x = math.Ceil(value) / scale 153 return x 154 } 155 156 func CeilUint64(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 157 return generalMathMulti("ceil", ivecs, result, proc, length, ceilUint64) 158 } 159 160 func CeilInt64(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 161 return generalMathMulti("ceil", ivecs, result, proc, length, ceilInt64) 162 } 163 164 func CeilFloat64(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 165 return generalMathMulti("ceil", ivecs, result, proc, length, ceilFloat64) 166 } 167 168 func ceilDecimal64(x types.Decimal64, digits int64, scale int32) types.Decimal64 { 169 if digits > 19 { 170 digits = 19 171 } 172 if digits < -18 { 173 digits = -18 174 } 175 return x.Ceil(scale, int32(digits)) 176 } 177 178 func ceilDecimal128(x types.Decimal128, digits int64, scale int32) types.Decimal128 { 179 if digits > 39 { 180 digits = 19 181 } 182 if digits < -38 { 183 digits = -38 184 } 185 return x.Ceil(scale, int32(digits)) 186 } 187 188 func CeilDecimal64(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 189 scale := ivecs[0].GetType().Scale 190 if len(ivecs) > 1 { 191 digit := vector.MustFixedCol[int64](ivecs[1]) 192 if len(digit) > 0 && int32(digit[0]) <= scale-18 { 193 return moerr.NewOutOfRange(proc.Ctx, "decimal64", "ceil(decimal64(18,%v),%v)", scale, digit[0]) 194 } 195 } 196 cb := func(x types.Decimal64, digits int64) types.Decimal64 { 197 return ceilDecimal64(x, digits, scale) 198 } 199 return generalMathMulti("ceil", ivecs, result, proc, length, cb) 200 } 201 202 func CeilDecimal128(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 203 scale := ivecs[0].GetType().Scale 204 if len(ivecs) > 1 { 205 digit := vector.MustFixedCol[int64](ivecs[1]) 206 if len(digit) > 0 && int32(digit[0]) <= scale-38 { 207 return moerr.NewOutOfRange(proc.Ctx, "decimal128", "ceil(decimal128(38,%v),%v)", scale, digit[0]) 208 } 209 } 210 cb := func(x types.Decimal128, digits int64) types.Decimal128 { 211 return ceilDecimal128(x, digits, scale) 212 } 213 return generalMathMulti("ceil", ivecs, result, proc, length, cb) 214 } 215 216 var MaxUint64digits = numOfDigits(math.MaxUint64) // 20 217 var MaxInt64digits = numOfDigits(math.MaxInt64) // 19 218 219 func numOfDigits(value uint64) int64 { 220 digits := int64(0) 221 for value > 0 { 222 value /= 10 223 digits++ 224 } 225 return digits 226 } 227 228 // ScaleTable is a lookup array for digits 229 var ScaleTable = [...]uint64{ 230 1, 231 10, 232 100, 233 1000, 234 10000, 235 100000, 236 1000000, 237 10000000, 238 100000000, 239 1000000000, 240 10000000000, 241 100000000000, 242 1000000000000, 243 10000000000000, 244 100000000000000, 245 1000000000000000, 246 10000000000000000, 247 100000000000000000, 248 1000000000000000000, 249 10000000000000000000, // 1 followed by 19 zeros, maxUint64 number has 20 digits, so the max scale is 1 followed by 19 zeroes 250 } 251 252 func floorUint64(x uint64, digits int64) uint64 { 253 switch { 254 case digits >= 0: 255 return x 256 case digits > -MaxUint64digits: 257 scale := ScaleTable[-digits] 258 x = x / scale * scale 259 case digits <= -MaxUint64digits: 260 x = 0 261 } 262 return x 263 } 264 265 func FloorUInt64(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 266 return generalMathMulti("floor", ivecs, result, proc, length, floorUint64) 267 } 268 269 func floorInt64(x int64, digits int64) int64 { 270 switch { 271 case digits >= 0: 272 return x 273 case digits > -MaxInt64digits: 274 scale := int64(ScaleTable[-digits]) 275 value := x 276 if value < 0 { 277 value -= scale - 1 278 } 279 x = value / scale * scale 280 case digits <= -MaxInt64digits: 281 x = 0 282 } 283 return x 284 } 285 286 func FloorInt64(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 287 return generalMathMulti("floor", ivecs, result, proc, length, floorInt64) 288 } 289 290 func floorFloat64(x float64, digits int64) float64 { 291 if digits == 0 { 292 return math.Floor(x) 293 } 294 scale := math.Pow10(int(digits)) 295 value := x * scale 296 return math.Floor(value) / scale 297 } 298 299 func FloorFloat64(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 300 return generalMathMulti("floor", ivecs, result, proc, length, floorFloat64) 301 } 302 303 func floorDecimal64(x types.Decimal64, digits int64, scale int32) types.Decimal64 { 304 if digits > 19 { 305 digits = 19 306 } 307 if digits < -18 { 308 digits = -18 309 } 310 return x.Floor(scale, int32(digits)) 311 } 312 313 func floorDecimal128(x types.Decimal128, digits int64, scale int32) types.Decimal128 { 314 if digits > 39 { 315 digits = 39 316 } 317 if digits < -38 { 318 digits = -38 319 } 320 return x.Floor(scale, int32(digits)) 321 } 322 323 func FloorDecimal64(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 324 scale := ivecs[0].GetType().Scale 325 if len(ivecs) > 1 { 326 digit := vector.MustFixedCol[int64](ivecs[1]) 327 if len(digit) > 0 && int32(digit[0]) <= scale-18 { 328 return moerr.NewOutOfRange(proc.Ctx, "decimal64", "floor(decimal64(18,%v),%v)", scale, digit[0]) 329 } 330 } 331 cb := func(x types.Decimal64, digits int64) types.Decimal64 { 332 return floorDecimal64(x, digits, scale) 333 } 334 335 return generalMathMulti("floor", ivecs, result, proc, length, cb) 336 } 337 338 func FloorDecimal128(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 339 scale := ivecs[0].GetType().Scale 340 if len(ivecs) > 1 { 341 digit := vector.MustFixedCol[int64](ivecs[1]) 342 if len(digit) > 0 && int32(digit[0]) <= scale-38 { 343 return moerr.NewOutOfRange(proc.Ctx, "decimal128", "floor(decimal128(38,%v),%v)", scale, digit[0]) 344 } 345 } 346 cb := func(x types.Decimal128, digits int64) types.Decimal128 { 347 return floorDecimal128(x, digits, scale) 348 } 349 350 return generalMathMulti("floor", ivecs, result, proc, length, cb) 351 } 352 353 func FloorStr(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 354 digits := int64(0) 355 if len(ivecs) > 1 { 356 if !ivecs[1].IsConst() || ivecs[1].GetType().Oid != types.T_int64 { 357 return moerr.NewInvalidArg(proc.Ctx, fmt.Sprintf("the second argument of the %s", "ceil"), "not const") 358 } 359 digits = vector.MustFixedCol[int64](ivecs[1])[0] 360 } 361 362 rs := vector.MustFunctionResult[float64](result) 363 ivec := vector.GenerateFunctionStrParameter(ivecs[0]) 364 for i := uint64(0); i < uint64(length); i++ { 365 v, null := ivec.GetStrValue(i) 366 if null { 367 if err = rs.Append(0, true); err != nil { 368 return err 369 } 370 } else { 371 floatVal, err := strconv.ParseFloat(string(v), 64) 372 if err != nil { 373 return err 374 } 375 if err = rs.Append(floorFloat64(floatVal, digits), false); err != nil { 376 return err 377 } 378 } 379 } 380 return nil 381 } 382 383 func roundUint64(x uint64, digits int64) uint64 { 384 switch { 385 case digits >= 0: 386 return x 387 case digits > -MaxUint64digits: // round algorithm contributed by @ffftian 388 scale := ScaleTable[-digits] 389 step1 := x / scale * scale 390 step2 := x % scale 391 if step2 >= scale/2 { 392 x = step1 + scale 393 if x < step1 { 394 panic(moerr.NewOutOfRangeNoCtx("uint64", "ROUND")) 395 } 396 } else { 397 x = step1 398 } 399 case digits <= -MaxUint64digits: 400 x = 0 401 } 402 return x 403 } 404 405 func RoundUint64(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 406 return generalMathMulti("round", ivecs, result, proc, length, roundUint64) 407 } 408 409 func roundInt64(x int64, digits int64) int64 { 410 switch { 411 case digits >= 0: 412 return x 413 case digits > -MaxInt64digits: 414 scale := int64(ScaleTable[-digits]) // round algorithm contributed by @ffftian 415 if x > 0 { 416 step1 := x / scale * scale 417 step2 := x % scale 418 if step2 >= scale/2 { 419 x = step1 + scale 420 if x < step1 { 421 panic(moerr.NewOutOfRangeNoCtx("int64", "ROUND")) 422 } 423 } else { 424 x = step1 425 } 426 } else if x < 0 { 427 step1 := x / scale * scale 428 step2 := x % scale // module operation with negative numbers, the result is negative 429 if step2 <= scale/2 { 430 x = step1 - scale 431 if x > step1 { 432 panic(moerr.NewOutOfRangeNoCtx("int64", "ROUND")) 433 } 434 } else { 435 x = step1 436 } 437 } else { 438 x = 0 439 } 440 case digits <= MaxInt64digits: 441 x = 0 442 } 443 return x 444 } 445 446 func RoundInt64(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 447 return generalMathMulti("round", ivecs, result, proc, length, roundInt64) 448 } 449 450 func roundFloat64(x float64, digits int64) float64 { 451 if digits == 0 { 452 x = math.RoundToEven(x) 453 } else if digits >= 308 { // the range of float64 454 } else if digits <= -308 { 455 x = 0 456 } else { 457 var abs_digits uint64 458 if digits < 0 { 459 abs_digits = uint64(-digits) 460 } else { 461 abs_digits = uint64(digits) 462 } 463 var tmp = math.Pow(10.0, float64(abs_digits)) 464 465 if digits > 0 { 466 var value_mul_tmp = x * tmp 467 x = math.RoundToEven(value_mul_tmp) / tmp 468 } else { 469 var value_div_tmp = x / tmp 470 x = math.RoundToEven(value_div_tmp) * tmp 471 } 472 } 473 return x 474 } 475 476 func RoundFloat64(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 477 return generalMathMulti("round", ivecs, result, proc, length, roundFloat64) 478 } 479 480 func roundDecimal64(x types.Decimal64, digits int64, scale int32) types.Decimal64 { 481 if digits > 19 { 482 digits = 19 483 } 484 if digits < -18 { 485 digits = -18 486 } 487 return x.Round(scale, int32(digits)) 488 } 489 490 func roundDecimal128(x types.Decimal128, digits int64, scale int32) types.Decimal128 { 491 if digits > 39 { 492 digits = 39 493 } 494 if digits < -38 { 495 digits = -38 496 } 497 return x.Round(scale, int32(digits)) 498 } 499 500 func RoundDecimal64(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 501 scale := ivecs[0].GetType().Scale 502 cb := func(x types.Decimal64, digits int64) types.Decimal64 { 503 return roundDecimal64(x, digits, scale) 504 } 505 return generalMathMulti("round", ivecs, result, proc, length, cb) 506 } 507 508 func RoundDecimal128(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 509 scale := ivecs[0].GetType().Scale 510 cb := func(x types.Decimal128, digits int64) types.Decimal128 { 511 return roundDecimal128(x, digits, scale) 512 } 513 return generalMathMulti("round", ivecs, result, proc, length, cb) 514 } 515 516 type NormalType interface { 517 constraints.Integer | constraints.Float | bool | types.Date | types.Datetime | 518 types.Decimal64 | types.Decimal128 | types.Timestamp | types.Uuid 519 } 520 521 func coalesceCheck(overloads []overload, inputs []types.Type) checkResult { 522 if len(inputs) > 0 { 523 minIndex := -1 524 minOid := types.T(0) 525 minCost := math.MaxInt 526 overloadRequire := make([]types.T, len(inputs)) 527 for i, over := range overloads { 528 requireOid := over.args[0] 529 for j := range overloadRequire { 530 overloadRequire[j] = requireOid 531 } 532 533 sta, cos := tryToMatch(inputs, overloadRequire) 534 if sta == matchFailed { 535 continue 536 } else if sta == matchDirectly { 537 return newCheckResultWithSuccess(i) 538 } else { 539 if cos < minCost { 540 minIndex = i 541 minCost = cos 542 minOid = requireOid 543 } 544 } 545 } 546 if minIndex == -1 { 547 return newCheckResultWithFailure(failedFunctionParametersWrong) 548 } 549 castType := make([]types.Type, len(inputs)) 550 for i := range castType { 551 if minOid == inputs[i].Oid { 552 castType[i] = inputs[i] 553 } else { 554 castType[i] = minOid.ToType() 555 setTargetScaleFromSource(&inputs[i], &castType[i]) 556 } 557 } 558 559 if minOid.IsDecimal() || minOid.IsDateRelate() { 560 setMaxScaleForAll(castType) 561 } 562 return newCheckResultWithCast(minIndex, castType) 563 } 564 return newCheckResultWithFailure(failedFunctionParametersWrong) 565 } 566 567 func CoalesceGeneral[T NormalType](ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 568 rs := vector.MustFunctionResult[T](result) 569 vecs := make([]vector.FunctionParameterWrapper[T], len(ivecs)) 570 for i := range ivecs { 571 vecs[i] = vector.GenerateFunctionFixedTypeParameter[T](ivecs[i]) 572 } 573 var t T 574 for i := uint64(0); i < uint64(length); i++ { 575 isFill := false 576 for j := range vecs { 577 v, null := vecs[j].GetValue(i) 578 if null { 579 continue 580 } 581 if err = rs.Append(v, false); err != nil { 582 return err 583 } 584 isFill = true 585 break 586 } 587 if !isFill { 588 if err = rs.Append(t, true); err != nil { 589 return err 590 } 591 } 592 } 593 return nil 594 } 595 596 func CoalesceStr(ivecs []*vector.Vector, result vector.FunctionResultWrapper, _ *process.Process, length int) (err error) { 597 rs := vector.MustFunctionResult[types.Varlena](result) 598 vecs := make([]vector.FunctionParameterWrapper[types.Varlena], len(ivecs)) 599 for i := range ivecs { 600 vecs[i] = vector.GenerateFunctionStrParameter(ivecs[i]) 601 } 602 for i := uint64(0); i < uint64(length); i++ { 603 isFill := false 604 for j := range vecs { 605 v, null := vecs[j].GetStrValue(i) 606 if null { 607 continue 608 } 609 if err = rs.AppendBytes(v, false); err != nil { 610 return err 611 } 612 isFill = true 613 break 614 } 615 if !isFill { 616 if err = rs.AppendBytes(nil, true); err != nil { 617 return err 618 } 619 } 620 } 621 return nil 622 } 623 624 func concatWsCheck(overloads []overload, inputs []types.Type) checkResult { 625 // all args should be string or can cast to string type. 626 if len(inputs) > 1 { 627 ret := make([]types.Type, len(inputs)) 628 shouldConvert := false 629 630 for i, t := range inputs { 631 if t.Oid.IsMySQLString() { 632 ret[i] = t 633 continue 634 } 635 if can, _ := fixedImplicitTypeCast(t, types.T_varchar); can { 636 shouldConvert = true 637 ret[i] = types.T_varchar.ToType() 638 } else { 639 return newCheckResultWithFailure(failedFunctionParametersWrong) 640 } 641 } 642 if shouldConvert { 643 return newCheckResultWithCast(0, ret) 644 } 645 return newCheckResultWithSuccess(0) 646 } 647 return newCheckResultWithFailure(failedFunctionParametersWrong) 648 } 649 650 func ConcatWs(ivecs []*vector.Vector, result vector.FunctionResultWrapper, _ *process.Process, length int) (err error) { 651 rs := vector.MustFunctionResult[types.Varlena](result) 652 vecs := make([]vector.FunctionParameterWrapper[types.Varlena], len(ivecs)) 653 for i := range ivecs { 654 vecs[i] = vector.GenerateFunctionStrParameter(ivecs[i]) 655 } 656 for i := uint64(0); i < uint64(length); i++ { 657 sp, null := vecs[0].GetStrValue(i) 658 if null { 659 if err = rs.AppendBytes(nil, true); err != nil { 660 return err 661 } 662 continue 663 } 664 allNull := true 665 canSp := false 666 var str string 667 for j := 1; j < len(vecs); j++ { 668 v, null := vecs[j].GetStrValue(i) 669 if null { 670 continue 671 } 672 if canSp { 673 str += string(sp) 674 } 675 canSp = true 676 str += string(v) 677 allNull = false 678 } 679 if allNull { 680 if err = rs.AppendBytes(nil, true); err != nil { 681 return err 682 } 683 continue 684 } 685 if err = rs.AppendBytes([]byte(str), false); err != nil { 686 return err 687 } 688 } 689 return nil 690 } 691 692 func ConvertTz(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 693 dates := vector.GenerateFunctionFixedTypeParameter[types.Datetime](ivecs[0]) 694 fromTzs := vector.GenerateFunctionStrParameter(ivecs[1]) 695 toTzs := vector.GenerateFunctionStrParameter(ivecs[2]) 696 rs := vector.MustFunctionResult[types.Varlena](result) 697 698 var fromLoc, toLoc *time.Location 699 if ivecs[1].IsConst() && !ivecs[1].IsConstNull() { 700 fromTz, _ := fromTzs.GetStrValue(0) 701 fromLoc = convertTimezone(string(fromTz)) 702 } 703 if ivecs[2].IsConst() && !ivecs[2].IsConstNull() { 704 toTz, _ := toTzs.GetStrValue(0) 705 toLoc = convertTimezone(string(toTz)) 706 } 707 708 for i := uint64(0); i < uint64(length); i++ { 709 date, null1 := dates.GetValue(i) 710 fromTz, null2 := fromTzs.GetStrValue(i) 711 toTz, null3 := toTzs.GetStrValue(i) 712 713 if null1 || null2 || null3 { 714 if err = rs.AppendBytes(nil, true); err != nil { 715 return err 716 } 717 return nil 718 } else if len(fromTz) == 0 || len(toTz) == 0 { 719 if err = rs.AppendBytes(nil, true); err != nil { 720 return err 721 } 722 return nil 723 } else { 724 if !ivecs[1].IsConst() { 725 fromLoc = convertTimezone(string(fromTz)) 726 } 727 if !ivecs[2].IsConst() { 728 toLoc = convertTimezone(string(toTz)) 729 } 730 if fromLoc == nil || toLoc == nil { 731 if err = rs.AppendBytes(nil, true); err != nil { 732 return err 733 } 734 return nil 735 } 736 maxStartTime := time.Date(9999, 12, 31, 23, 59, 59, 0, fromLoc) 737 maxEndTime := time.Date(9999, 12, 31, 23, 59, 59, 0, toLoc) 738 minStartTime := time.Date(0001, 1, 1, 0, 0, 0, 0, fromLoc) 739 minEndTime := time.Date(0001, 1, 1, 0, 0, 0, 0, toLoc) 740 startTime := date.ConvertToGoTime(fromLoc) 741 if startTime.After(maxStartTime) { // if startTime > maxTime, return maxTime 742 if err = rs.AppendBytes([]byte(maxStartTime.Format(time.DateTime)), false); err != nil { 743 return err 744 } 745 } else if startTime.Before(minStartTime) { // if startTime < minTime, return minTime 746 if err = rs.AppendBytes([]byte(minStartTime.Format(time.DateTime)), false); err != nil { 747 return err 748 } 749 } else { // if minTime <= startTime <= maxTime 750 endTime := startTime.In(toLoc) 751 if endTime.After(maxEndTime) || endTime.Before(minEndTime) { // if endTime > maxTime or endTime < maxTime, return startTime 752 if err = rs.AppendBytes([]byte(startTime.Format(time.DateTime)), false); err != nil { 753 return err 754 } 755 } else { 756 if err = rs.AppendBytes([]byte(endTime.Format(time.DateTime)), false); err != nil { 757 return err 758 } 759 } 760 } 761 } 762 } 763 764 return nil 765 } 766 767 func convertTimezone(tz string) *time.Location { 768 loc, err := time.LoadLocation(tz) 769 if err != nil && tz[0] != '+' && tz[0] != '-' { 770 return nil 771 } 772 // convert from timezone offset to location 773 if tz[0] == '+' || tz[0] == '-' { 774 parts := strings.Split(tz, ":") 775 if len(parts) != 2 { 776 return nil 777 } 778 hours, err := strconv.Atoi(parts[0]) 779 if err != nil { 780 return nil 781 } else if hours < -13 || hours > 14 { // timezone should be in [-13, 14] 782 return nil 783 } 784 minutes, err := strconv.Atoi(parts[1]) 785 if tz[0] == '-' { 786 minutes = -minutes 787 } 788 if err != nil { 789 return nil 790 } 791 792 offset := time.Duration(hours)*time.Hour + time.Duration(minutes)*time.Minute 793 loc = time.FixedZone("GMT", int(offset.Seconds())) 794 } 795 796 return loc 797 } 798 799 func doDateAdd(start types.Date, diff int64, iTyp types.IntervalType) (types.Date, error) { 800 err := types.JudgeIntervalNumOverflow(diff, iTyp) 801 if err != nil { 802 return 0, err 803 } 804 dt, success := start.ToDatetime().AddInterval(diff, iTyp, types.DateType) 805 if success { 806 return dt.ToDate(), nil 807 } else { 808 return 0, moerr.NewOutOfRangeNoCtx("date", "") 809 } 810 } 811 812 func doTimeAdd(start types.Time, diff int64, iTyp types.IntervalType) (types.Time, error) { 813 err := types.JudgeIntervalNumOverflow(diff, iTyp) 814 if err != nil { 815 return 0, err 816 } 817 t, success := start.AddInterval(diff, iTyp) 818 if success { 819 return t, nil 820 } else { 821 return 0, moerr.NewOutOfRangeNoCtx("time", "") 822 } 823 } 824 825 func doDatetimeAdd(start types.Datetime, diff int64, iTyp types.IntervalType) (types.Datetime, error) { 826 err := types.JudgeIntervalNumOverflow(diff, iTyp) 827 if err != nil { 828 return 0, err 829 } 830 dt, success := start.AddInterval(diff, iTyp, types.DateTimeType) 831 if success { 832 return dt, nil 833 } else { 834 return 0, moerr.NewOutOfRangeNoCtx("datetime", "") 835 } 836 } 837 838 func doDateStringAdd(startStr string, diff int64, iTyp types.IntervalType) (types.Datetime, error) { 839 err := types.JudgeIntervalNumOverflow(diff, iTyp) 840 if err != nil { 841 return 0, err 842 } 843 start, err := types.ParseDatetime(startStr, 6) 844 if err != nil { 845 return 0, err 846 } 847 dt, success := start.AddInterval(diff, iTyp, types.DateType) 848 if success { 849 return dt, nil 850 } else { 851 return 0, moerr.NewOutOfRangeNoCtx("datetime", "") 852 } 853 } 854 855 func doTimestampAdd(loc *time.Location, start types.Timestamp, diff int64, iTyp types.IntervalType) (types.Timestamp, error) { 856 err := types.JudgeIntervalNumOverflow(diff, iTyp) 857 if err != nil { 858 return 0, err 859 } 860 dt, success := start.ToDatetime(loc).AddInterval(diff, iTyp, types.DateTimeType) 861 if success { 862 return dt.ToTimestamp(loc), nil 863 } else { 864 return 0, moerr.NewOutOfRangeNoCtx("timestamp", "") 865 } 866 } 867 868 func DateAdd(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 869 unit, _ := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[2]).GetValue(0) 870 iTyp := types.IntervalType(unit) 871 872 return opBinaryFixedFixedToFixedWithErrorCheck[types.Date, int64, types.Date](ivecs, result, proc, length, func(v1 types.Date, v2 int64) (types.Date, error) { 873 return doDateAdd(v1, v2, iTyp) 874 }) 875 } 876 877 func DatetimeAdd(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 878 unit, _ := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[2]).GetValue(0) 879 scale := ivecs[0].GetType().Scale 880 iTyp := types.IntervalType(unit) 881 if iTyp == types.MicroSecond { 882 scale = 6 883 } 884 rs := vector.MustFunctionResult[types.Datetime](result) 885 rs.TempSetType(types.New(types.T_datetime, 0, scale)) 886 887 return opBinaryFixedFixedToFixedWithErrorCheck[types.Datetime, int64, types.Datetime](ivecs, result, proc, length, func(v1 types.Datetime, v2 int64) (types.Datetime, error) { 888 return doDatetimeAdd(v1, v2, iTyp) 889 }) 890 } 891 892 func DateStringAdd(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 893 unit, _ := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[2]).GetValue(0) 894 iTyp := types.IntervalType(unit) 895 rs := vector.MustFunctionResult[types.Datetime](result) 896 rs.TempSetType(types.New(types.T_datetime, 0, 6)) 897 898 return opBinaryStrFixedToFixedWithErrorCheck[int64, types.Datetime](ivecs, result, proc, length, func(v1 string, v2 int64) (types.Datetime, error) { 899 return doDateStringAdd(v1, v2, iTyp) 900 }) 901 } 902 903 func TimestampAdd(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 904 rs := vector.MustFunctionResult[types.Timestamp](result) 905 unit, _ := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[2]).GetValue(0) 906 scale := ivecs[0].GetType().Scale 907 iTyp := types.IntervalType(unit) 908 switch iTyp { 909 case types.MicroSecond: 910 scale = 6 911 } 912 rs.TempSetType(types.New(types.T_timestamp, 0, scale)) 913 914 return opBinaryFixedFixedToFixedWithErrorCheck[types.Timestamp, int64, types.Timestamp](ivecs, result, proc, length, func(v1 types.Timestamp, v2 int64) (types.Timestamp, error) { 915 return doTimestampAdd(proc.SessionInfo.TimeZone, v1, v2, iTyp) 916 }) 917 } 918 919 func TimeAdd(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 920 rs := vector.MustFunctionResult[types.Time](result) 921 unit, _ := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[2]).GetValue(0) 922 scale := ivecs[0].GetType().Scale 923 iTyp := types.IntervalType(unit) 924 switch iTyp { 925 case types.MicroSecond: 926 scale = 6 927 } 928 rs.TempSetType(types.New(types.T_time, 0, scale)) 929 930 return opBinaryFixedFixedToFixedWithErrorCheck[types.Time, int64, types.Time](ivecs, result, proc, length, func(v1 types.Time, v2 int64) (types.Time, error) { 931 return doTimeAdd(v1, v2, iTyp) 932 }) 933 } 934 935 func DateFormat(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 936 if !ivecs[1].IsConst() { 937 return moerr.NewInvalidArg(proc.Ctx, "date format format", "not constant") 938 } 939 940 rs := vector.MustFunctionResult[types.Varlena](result) 941 942 dates := vector.GenerateFunctionFixedTypeParameter[types.Datetime](ivecs[0]) 943 formats := vector.GenerateFunctionStrParameter(ivecs[1]) 944 fmt, null2 := formats.GetStrValue(0) 945 946 var dateFmtOperator DateFormatFunc 947 switch string(fmt) { 948 case "%d/%m/%Y": 949 dateFmtOperator = date_format_combine_pattern1 950 case "%Y%m%d": 951 dateFmtOperator = date_format_combine_pattern2 952 case "%Y": 953 dateFmtOperator = date_format_combine_pattern3 954 case "%Y-%m-%d": 955 dateFmtOperator = date_format_combine_pattern4 956 case "%Y-%m-%d %H:%i:%s", "%Y-%m-%d %T": 957 dateFmtOperator = date_format_combine_pattern5 958 case "%Y/%m/%d": 959 dateFmtOperator = date_format_combine_pattern6 960 case "%Y/%m/%d %H:%i:%s", "%Y/%m/%d %T": 961 dateFmtOperator = date_format_combine_pattern7 962 default: 963 dateFmtOperator = datetimeFormat 964 } 965 966 //format := "%b %D %M" -> []func{func1,func2, func3} 967 var buf bytes.Buffer 968 for i := uint64(0); i < uint64(length); i++ { 969 d, null1 := dates.GetValue(i) 970 if null1 || null2 { 971 if err = rs.AppendBytes(nil, true); err != nil { 972 return err 973 } 974 } else { 975 buf.Reset() 976 if err = dateFmtOperator(proc.Ctx, d, string(fmt), &buf); err != nil { 977 return err 978 } 979 if err = rs.AppendBytes(buf.Bytes(), false); err != nil { 980 return err 981 } 982 } 983 } 984 return nil 985 } 986 987 type DateFormatFunc func(ctx context.Context, datetime types.Datetime, format string, buf *bytes.Buffer) error 988 989 // DATE_FORMAT datetime 990 // handle '%d/%m/%Y' -> 22/04/2021 991 func date_format_combine_pattern1(ctx context.Context, t types.Datetime, format string, buf *bytes.Buffer) error { 992 month := int(t.Month()) 993 day := int(t.Day()) 994 year := int(t.Year()) 995 996 // Convert numbers to strings using bitwise operations and append them to a buffer 997 buf.Grow(10) // Pre allocate sufficient buffer size 998 999 // Date and month conversion 1000 buf.WriteByte(byte('0' + (day / 10 % 10))) 1001 buf.WriteByte(byte('0' + (day % 10))) 1002 buf.WriteByte('/') 1003 buf.WriteByte(byte('0' + (month / 10 % 10))) 1004 buf.WriteByte(byte('0' + (month % 10))) 1005 buf.WriteByte('/') 1006 1007 // Year conversion 1008 buf.WriteByte(byte('0' + (year / 1000 % 10))) 1009 buf.WriteByte(byte('0' + (year / 100 % 10))) 1010 buf.WriteByte(byte('0' + (year / 10 % 10))) 1011 buf.WriteByte(byte('0' + (year % 10))) 1012 return nil 1013 } 1014 1015 // handle '%Y%m%d' -> 20210422 1016 func date_format_combine_pattern2(ctx context.Context, t types.Datetime, format string, buf *bytes.Buffer) error { 1017 year := t.Year() 1018 month := int(t.Month()) 1019 day := int(t.Day()) 1020 1021 // Convert numbers to strings using bitwise operations and append them to a buffer 1022 buf.Grow(8) // Pre allocate sufficient buffer size 1023 1024 // Year conversion 1025 buf.WriteByte(byte('0' + (year / 1000 % 10))) 1026 buf.WriteByte(byte('0' + (year / 100 % 10))) 1027 buf.WriteByte(byte('0' + (year / 10 % 10))) 1028 buf.WriteByte(byte('0' + (year % 10))) 1029 1030 // Month conversion 1031 buf.WriteByte(byte('0' + (month / 10))) 1032 buf.WriteByte(byte('0' + (month % 10))) 1033 1034 // date conversion 1035 buf.WriteByte(byte('0' + (day / 10))) 1036 buf.WriteByte(byte('0' + (day % 10))) 1037 return nil 1038 } 1039 1040 // handle '%Y' -> 2021 1041 func date_format_combine_pattern3(ctx context.Context, t types.Datetime, format string, buf *bytes.Buffer) error { 1042 year := t.Year() 1043 // Year conversion 1044 buf.WriteByte(byte('0' + (year / 1000 % 10))) 1045 buf.WriteByte(byte('0' + (year / 100 % 10))) 1046 buf.WriteByte(byte('0' + (year / 10 % 10))) 1047 buf.WriteByte(byte('0' + (year % 10))) 1048 return nil 1049 } 1050 1051 // %Y-%m-%d 2021-04-22 1052 func date_format_combine_pattern4(ctx context.Context, t types.Datetime, format string, buf *bytes.Buffer) error { 1053 year := t.Year() 1054 month := int(t.Month()) 1055 day := int(t.Day()) 1056 1057 // Convert numbers to strings using bitwise operations and append them to a buffer 1058 buf.Grow(10) // Pre allocate sufficient buffer size 1059 1060 // Year conversion 1061 buf.WriteByte(byte('0' + (year / 1000 % 10))) 1062 buf.WriteByte(byte('0' + (year / 100 % 10))) 1063 buf.WriteByte(byte('0' + (year / 10 % 10))) 1064 buf.WriteByte(byte('0' + (year % 10))) 1065 1066 // Month conversion 1067 buf.WriteByte('-') 1068 buf.WriteByte(byte('0' + (month / 10))) 1069 buf.WriteByte(byte('0' + (month % 10))) 1070 1071 // date conversion 1072 buf.WriteByte('-') 1073 buf.WriteByte(byte('0' + (day / 10))) 1074 buf.WriteByte(byte('0' + (day % 10))) 1075 return nil 1076 } 1077 1078 // handle '%Y-%m-%d %H:%i:%s' -> 2004-04-03 13:11:10 1079 // handle ' %Y-%m-%d %T' -> 2004-04-03 13:11:10 1080 func date_format_combine_pattern5(ctx context.Context, t types.Datetime, format string, buf *bytes.Buffer) error { 1081 year := int(t.Year()) 1082 month := int(t.Month()) 1083 day := int(t.Day()) 1084 hour := int(t.Hour()) 1085 minute := int(t.Minute()) 1086 sec := int(t.Sec()) 1087 1088 // Convert numbers to strings using bitwise operations and append them to a buffer 1089 buf.Grow(19) // Pre allocate sufficient buffer size 1090 1091 // Year conversion 1092 buf.WriteByte(byte('0' + (year / 1000 % 10))) 1093 buf.WriteByte(byte('0' + (year / 100 % 10))) 1094 buf.WriteByte(byte('0' + (year / 10 % 10))) 1095 buf.WriteByte(byte('0' + (year % 10))) 1096 1097 buf.WriteByte('-') 1098 1099 // Month conversion 1100 buf.WriteByte(byte('0' + (month / 10))) 1101 buf.WriteByte(byte('0' + (month % 10))) 1102 1103 buf.WriteByte('-') 1104 1105 // date conversion 1106 buf.WriteByte(byte('0' + (day / 10))) 1107 buf.WriteByte(byte('0' + (day % 10))) 1108 1109 buf.WriteByte(' ') 1110 1111 // Hour conversion 1112 buf.WriteByte(byte('0' + (hour / 10))) 1113 buf.WriteByte(byte('0' + (hour % 10))) 1114 1115 buf.WriteByte(':') 1116 1117 // Minute conversion 1118 buf.WriteByte(byte('0' + (minute / 10))) 1119 buf.WriteByte(byte('0' + (minute % 10))) 1120 1121 buf.WriteByte(':') 1122 1123 // Second conversion 1124 buf.WriteByte(byte('0' + (sec / 10))) 1125 buf.WriteByte(byte('0' + (sec % 10))) 1126 return nil 1127 } 1128 1129 // handle '%Y/%m/%d' -> 2010/01/07 1130 func date_format_combine_pattern6(ctx context.Context, t types.Datetime, format string, buf *bytes.Buffer) error { 1131 year := t.Year() 1132 month := int(t.Month()) 1133 day := int(t.Day()) 1134 1135 // Convert numbers to strings using bitwise operations and append them to a buffer 1136 buf.Grow(10) // Pre allocate sufficient buffer size 1137 1138 // Year conversion 1139 buf.WriteByte(byte('0' + (year / 1000 % 10))) 1140 buf.WriteByte(byte('0' + (year / 100 % 10))) 1141 buf.WriteByte(byte('0' + (year / 10 % 10))) 1142 buf.WriteByte(byte('0' + (year % 10))) 1143 1144 // Month conversion 1145 buf.WriteByte('/') 1146 buf.WriteByte(byte('0' + (month / 10))) 1147 buf.WriteByte(byte('0' + (month % 10))) 1148 1149 // date conversion 1150 buf.WriteByte('/') 1151 buf.WriteByte(byte('0' + (day / 10))) 1152 buf.WriteByte(byte('0' + (day % 10))) 1153 return nil 1154 } 1155 1156 // handle '%Y/%m/%d %H:%i:%s' -> 2010/01/07 23:12:34 1157 // handle '%Y/%m/%d %T' -> 2010/01/07 23:12:34 1158 func date_format_combine_pattern7(ctx context.Context, t types.Datetime, format string, buf *bytes.Buffer) error { 1159 year := int(t.Year()) 1160 month := int(t.Month()) 1161 day := int(t.Day()) 1162 hour := int(t.Hour()) 1163 minute := int(t.Minute()) 1164 sec := int(t.Sec()) 1165 1166 // Convert numbers to strings using bitwise operations and append them to a buffer 1167 buf.Grow(19) // Pre allocate sufficient buffer size 1168 1169 // Year conversion 1170 buf.WriteByte(byte('0' + (year / 1000 % 10))) 1171 buf.WriteByte(byte('0' + (year / 100 % 10))) 1172 buf.WriteByte(byte('0' + (year / 10 % 10))) 1173 buf.WriteByte(byte('0' + (year % 10))) 1174 1175 buf.WriteByte('/') 1176 1177 // Month conversion 1178 buf.WriteByte(byte('0' + (month / 10))) 1179 buf.WriteByte(byte('0' + (month % 10))) 1180 1181 buf.WriteByte('/') 1182 1183 // date conversion 1184 buf.WriteByte(byte('0' + (day / 10))) 1185 buf.WriteByte(byte('0' + (day % 10))) 1186 1187 buf.WriteByte(' ') 1188 1189 // Hour conversion 1190 buf.WriteByte(byte('0' + (hour / 10))) 1191 buf.WriteByte(byte('0' + (hour % 10))) 1192 1193 buf.WriteByte(':') 1194 1195 // Minute conversion 1196 buf.WriteByte(byte('0' + (minute / 10))) 1197 buf.WriteByte(byte('0' + (minute % 10))) 1198 1199 buf.WriteByte(':') 1200 1201 // Second conversion 1202 buf.WriteByte(byte('0' + (sec / 10))) 1203 buf.WriteByte(byte('0' + (sec % 10))) 1204 return nil 1205 } 1206 1207 // datetimeFormat: format the datetime value according to the format string. 1208 func datetimeFormat(ctx context.Context, datetime types.Datetime, format string, buf *bytes.Buffer) error { 1209 inPatternMatch := false 1210 for _, b := range format { 1211 if inPatternMatch { 1212 if err := makeDateFormat(ctx, datetime, b, buf); err != nil { 1213 return err 1214 } 1215 inPatternMatch = false 1216 continue 1217 } 1218 1219 // It's not in pattern match now. 1220 if b == '%' { 1221 inPatternMatch = true 1222 } else { 1223 buf.WriteRune(b) 1224 } 1225 } 1226 return nil 1227 } 1228 1229 var ( 1230 // WeekdayNames lists names of weekdays, which are used in builtin function `date_format`. 1231 WeekdayNames = []string{ 1232 "Monday", 1233 "Tuesday", 1234 "Wednesday", 1235 "Thursday", 1236 "Friday", 1237 "Saturday", 1238 "Sunday", 1239 } 1240 1241 // MonthNames lists names of months, which are used in builtin function `date_format`. 1242 MonthNames = []string{ 1243 "January", 1244 "February", 1245 "March", 1246 "April", 1247 "May", 1248 "June", 1249 "July", 1250 "August", 1251 "September", 1252 "October", 1253 "November", 1254 "December", 1255 } 1256 1257 // AbbrevWeekdayName lists Abbreviation of week names, which are used int builtin function 'date_format' 1258 AbbrevWeekdayName = []string{ 1259 "Sun", 1260 "Mon", 1261 "Tue", 1262 "Wed", 1263 "Thu", 1264 "Fri", 1265 "Sat", 1266 } 1267 ) 1268 1269 // makeDateFormat: Get the format string corresponding to the date according to a single format character 1270 func makeDateFormat(ctx context.Context, t types.Datetime, b rune, buf *bytes.Buffer) error { 1271 switch b { 1272 case 'b': 1273 m := t.Month() 1274 if m == 0 || m > 12 { 1275 return moerr.NewInvalidInput(ctx, "invalud date format for month '%d'", m) 1276 } 1277 buf.WriteString(MonthNames[m-1][:3]) 1278 case 'M': 1279 m := t.Month() 1280 if m == 0 || m > 12 { 1281 return moerr.NewInvalidInput(ctx, "invalud date format for month '%d'", m) 1282 } 1283 buf.WriteString(MonthNames[m-1]) 1284 case 'm': 1285 FormatInt2BufByWidth(int(t.Month()), 2, buf) 1286 //buf.WriteString(FormatIntByWidth(int(t.Month()), 2)) 1287 case 'c': 1288 buf.WriteString(strconv.FormatInt(int64(t.Month()), 10)) 1289 case 'D': 1290 buf.WriteString(strconv.FormatInt(int64(t.Day()), 10)) 1291 buf.WriteString(AbbrDayOfMonth(int(t.Day()))) 1292 case 'd': 1293 FormatInt2BufByWidth(int(t.Day()), 2, buf) 1294 //buf.WriteString(FormatIntByWidth(int(t.Day()), 2)) 1295 case 'e': 1296 buf.WriteString(strconv.FormatInt(int64(t.Day()), 10)) 1297 case 'f': 1298 fmt.Fprintf(buf, "%06d", t.MicroSec()) 1299 case 'j': 1300 fmt.Fprintf(buf, "%03d", t.DayOfYear()) 1301 case 'H': 1302 FormatInt2BufByWidth(int(t.Hour()), 2, buf) 1303 //buf.WriteString(FormatIntByWidth(int(t.Hour()), 2)) 1304 case 'k': 1305 buf.WriteString(strconv.FormatInt(int64(t.Hour()), 10)) 1306 case 'h', 'I': 1307 tt := t.Hour() 1308 if tt%12 == 0 { 1309 buf.WriteString("12") 1310 } else { 1311 FormatInt2BufByWidth(int(tt%12), 2, buf) 1312 //buf.WriteString(FormatIntByWidth(int(tt%12), 2)) 1313 } 1314 case 'i': 1315 FormatInt2BufByWidth(int(t.Minute()), 2, buf) 1316 //buf.WriteString(FormatIntByWidth(int(t.Minute()), 2)) 1317 case 'l': 1318 tt := t.Hour() 1319 if tt%12 == 0 { 1320 buf.WriteString("12") 1321 } else { 1322 buf.WriteString(strconv.FormatInt(int64(tt%12), 10)) 1323 } 1324 case 'p': 1325 hour := t.Hour() 1326 if hour/12%2 == 0 { 1327 buf.WriteString("AM") 1328 } else { 1329 buf.WriteString("PM") 1330 } 1331 case 'r': 1332 h := t.Hour() 1333 h %= 24 1334 switch { 1335 case h == 0: 1336 fmt.Fprintf(buf, "%02d:%02d:%02d AM", 12, t.Minute(), t.Sec()) 1337 case h == 12: 1338 fmt.Fprintf(buf, "%02d:%02d:%02d PM", 12, t.Minute(), t.Sec()) 1339 case h < 12: 1340 fmt.Fprintf(buf, "%02d:%02d:%02d AM", h, t.Minute(), t.Sec()) 1341 default: 1342 fmt.Fprintf(buf, "%02d:%02d:%02d PM", h-12, t.Minute(), t.Sec()) 1343 } 1344 case 'S', 's': 1345 FormatInt2BufByWidth(int(t.Sec()), 2, buf) 1346 //buf.WriteString(FormatIntByWidth(int(t.Sec()), 2)) 1347 case 'T': 1348 fmt.Fprintf(buf, "%02d:%02d:%02d", t.Hour(), t.Minute(), t.Sec()) 1349 case 'U': 1350 w := t.Week(0) 1351 FormatInt2BufByWidth(w, 2, buf) 1352 //buf.WriteString(FormatIntByWidth(w, 2)) 1353 case 'u': 1354 w := t.Week(1) 1355 FormatInt2BufByWidth(w, 2, buf) 1356 //buf.WriteString(FormatIntByWidth(w, 2)) 1357 case 'V': 1358 w := t.Week(2) 1359 FormatInt2BufByWidth(w, 2, buf) 1360 //buf.WriteString(FormatIntByWidth(w, 2)) 1361 case 'v': 1362 _, w := t.YearWeek(3) 1363 FormatInt2BufByWidth(w, 2, buf) 1364 //buf.WriteString(FormatIntByWidth(w, 2)) 1365 case 'a': 1366 weekday := t.DayOfWeek() 1367 buf.WriteString(AbbrevWeekdayName[weekday]) 1368 case 'W': 1369 buf.WriteString(t.DayOfWeek().String()) 1370 case 'w': 1371 buf.WriteString(strconv.FormatInt(int64(t.DayOfWeek()), 10)) 1372 case 'X': 1373 year, _ := t.YearWeek(2) 1374 if year < 0 { 1375 buf.WriteString(strconv.FormatUint(uint64(math.MaxUint32), 10)) 1376 } else { 1377 FormatInt2BufByWidth(year, 4, buf) 1378 //buf.WriteString(FormatIntByWidth(year, 4)) 1379 } 1380 case 'x': 1381 year, _ := t.YearWeek(3) 1382 if year < 0 { 1383 buf.WriteString(strconv.FormatUint(uint64(math.MaxUint32), 10)) 1384 } else { 1385 FormatInt2BufByWidth(year, 4, buf) 1386 //buf.WriteString(FormatIntByWidth(year, 4)) 1387 } 1388 case 'Y': 1389 FormatInt2BufByWidth(int(t.Year()), 4, buf) 1390 //buf.WriteString(FormatIntByWidth(int(t.Year()), 4)) 1391 case 'y': 1392 str := FormatIntByWidth(int(t.Year()), 4) 1393 buf.WriteString(str[2:]) 1394 default: 1395 buf.WriteRune(b) 1396 } 1397 return nil 1398 } 1399 1400 // FormatIntByWidth: Formatintwidthn is used to format ints with width parameter n. Insufficient numbers are filled with 0. 1401 func FormatIntByWidth(num, n int) string { 1402 numStr := strconv.Itoa(num) 1403 if len(numStr) >= n { 1404 return numStr 1405 } 1406 1407 pad := strings.Repeat("0", n-len(numStr)) 1408 var builder strings.Builder 1409 builder.Grow(n) 1410 builder.WriteString(pad) 1411 builder.WriteString(numStr) 1412 return builder.String() 1413 } 1414 1415 func FormatInt2BufByWidth(num, n int, buf *bytes.Buffer) { 1416 numStr := strconv.Itoa(num) 1417 if len(numStr) >= n { 1418 buf.WriteString(numStr) 1419 return 1420 } 1421 1422 pad := strings.Repeat("0", n-len(numStr)) 1423 buf.WriteString(pad) 1424 buf.WriteString(numStr) 1425 } 1426 1427 // AbbrDayOfMonth: Get the abbreviation of month of day 1428 func AbbrDayOfMonth(day int) string { 1429 var str string 1430 switch day { 1431 case 1, 21, 31: 1432 str = "st" 1433 case 2, 22: 1434 str = "nd" 1435 case 3, 23: 1436 str = "rd" 1437 default: 1438 str = "th" 1439 } 1440 return str 1441 } 1442 1443 func doDateSub(start types.Date, diff int64, iTyp types.IntervalType) (types.Date, error) { 1444 err := types.JudgeIntervalNumOverflow(diff, iTyp) 1445 if err != nil { 1446 return 0, err 1447 } 1448 dt, success := start.ToDatetime().AddInterval(-diff, iTyp, types.DateType) 1449 if success { 1450 return dt.ToDate(), nil 1451 } else { 1452 return 0, moerr.NewOutOfRangeNoCtx("date", "") 1453 } 1454 } 1455 1456 //func doTimeSub(start types.Time, diff int64, unit int64) (types.Time, error) { 1457 // err := types.JudgeIntervalNumOverflow(diff, types.IntervalType(unit)) 1458 // if err != nil { 1459 // return 0, err 1460 // } 1461 // t, success := start.AddInterval(-diff, types.IntervalType(unit)) 1462 // if success { 1463 // return t, nil 1464 // } else { 1465 // return 0, moerr.NewOutOfRangeNoCtx("time", "") 1466 // } 1467 //} 1468 1469 func doDatetimeSub(start types.Datetime, diff int64, iTyp types.IntervalType) (types.Datetime, error) { 1470 err := types.JudgeIntervalNumOverflow(diff, iTyp) 1471 if err != nil { 1472 return 0, err 1473 } 1474 dt, success := start.AddInterval(-diff, iTyp, types.DateTimeType) 1475 if success { 1476 return dt, nil 1477 } else { 1478 return 0, moerr.NewOutOfRangeNoCtx("datetime", "") 1479 } 1480 } 1481 1482 func doDateStringSub(startStr string, diff int64, iTyp types.IntervalType) (types.Datetime, error) { 1483 err := types.JudgeIntervalNumOverflow(diff, iTyp) 1484 if err != nil { 1485 return 0, err 1486 } 1487 start, err := types.ParseDatetime(startStr, 6) 1488 if err != nil { 1489 return 0, err 1490 } 1491 dt, success := start.AddInterval(-diff, iTyp, types.DateType) 1492 if success { 1493 return dt, nil 1494 } else { 1495 return 0, moerr.NewOutOfRangeNoCtx("datetime", "") 1496 } 1497 } 1498 1499 func doTimestampSub(loc *time.Location, start types.Timestamp, diff int64, iTyp types.IntervalType) (types.Timestamp, error) { 1500 err := types.JudgeIntervalNumOverflow(diff, iTyp) 1501 if err != nil { 1502 return 0, err 1503 } 1504 dt, success := start.ToDatetime(loc).AddInterval(-diff, iTyp, types.DateTimeType) 1505 if success { 1506 return dt.ToTimestamp(loc), nil 1507 } else { 1508 return 0, moerr.NewOutOfRangeNoCtx("timestamp", "") 1509 } 1510 } 1511 1512 func DateSub(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 1513 unit, _ := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[2]).GetValue(0) 1514 iTyp := types.IntervalType(unit) 1515 1516 return opBinaryFixedFixedToFixedWithErrorCheck[types.Date, int64, types.Date](ivecs, result, proc, length, func(v1 types.Date, v2 int64) (types.Date, error) { 1517 return doDateSub(v1, v2, iTyp) 1518 }) 1519 } 1520 1521 func DatetimeSub(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 1522 unit, _ := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[2]).GetValue(0) 1523 scale := ivecs[0].GetType().Scale 1524 iTyp := types.IntervalType(unit) 1525 if iTyp == types.MicroSecond { 1526 scale = 6 1527 } 1528 rs := vector.MustFunctionResult[types.Datetime](result) 1529 rs.TempSetType(types.New(types.T_datetime, 0, scale)) 1530 1531 return opBinaryFixedFixedToFixedWithErrorCheck[types.Datetime, int64, types.Datetime](ivecs, result, proc, length, func(v1 types.Datetime, v2 int64) (types.Datetime, error) { 1532 return doDatetimeSub(v1, v2, iTyp) 1533 }) 1534 } 1535 1536 func DateStringSub(ivecs []*vector.Vector, result vector.FunctionResultWrapper, _ *process.Process, length int) (err error) { 1537 rs := vector.MustFunctionResult[types.Datetime](result) 1538 unit, _ := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[2]).GetValue(0) 1539 1540 var d types.Datetime 1541 starts := vector.GenerateFunctionStrParameter(ivecs[0]) 1542 diffs := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[1]) 1543 rs.TempSetType(types.New(types.T_datetime, 0, 6)) 1544 iTyp := types.IntervalType(unit) 1545 for i := uint64(0); i < uint64(length); i++ { 1546 v1, null1 := starts.GetStrValue(i) 1547 v2, null2 := diffs.GetValue(i) 1548 1549 if null1 || null2 { 1550 if err = rs.Append(d, true); err != nil { 1551 return err 1552 } 1553 } else { 1554 val, err := doDateStringSub(functionUtil.QuickBytesToStr(v1), v2, iTyp) 1555 if err != nil { 1556 return err 1557 } 1558 if err = rs.Append(val, false); err != nil { 1559 return err 1560 } 1561 } 1562 } 1563 return nil 1564 } 1565 1566 func TimestampSub(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 1567 unit, _ := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[2]).GetValue(0) 1568 iTyp := types.IntervalType(unit) 1569 1570 scale := ivecs[0].GetType().Scale 1571 rs := vector.MustFunctionResult[types.Timestamp](result) 1572 rs.TempSetType(types.New(types.T_timestamp, 0, scale)) 1573 1574 return opBinaryFixedFixedToFixedWithErrorCheck[types.Timestamp, int64, types.Timestamp](ivecs, result, proc, length, func(v1 types.Timestamp, v2 int64) (types.Timestamp, error) { 1575 return doTimestampSub(proc.SessionInfo.TimeZone, v1, v2, iTyp) 1576 }) 1577 } 1578 1579 type number interface { 1580 constraints.Unsigned | constraints.Signed | constraints.Float 1581 } 1582 1583 func fieldCheck(overloads []overload, inputs []types.Type) checkResult { 1584 tc := func(inputs []types.Type, t types.T) bool { 1585 for _, input := range inputs { 1586 if (input.Oid == types.T_char && t == types.T_varchar) || (input.Oid == types.T_varchar && t == types.T_char) { 1587 continue 1588 } 1589 if input.Oid != t && input.Oid != types.T_any { 1590 return false 1591 } 1592 } 1593 return true 1594 } 1595 if len(inputs) < 2 { 1596 return newCheckResultWithFailure(failedFunctionParametersWrong) 1597 } 1598 returnType := [...]types.T{ 1599 types.T_varchar, types.T_char, 1600 types.T_int8, types.T_int16, types.T_int32, types.T_int64, 1601 types.T_uint8, types.T_uint16, types.T_uint32, types.T_uint64, 1602 types.T_float32, types.T_float64, 1603 types.T_bit, 1604 } 1605 for i, r := range returnType { 1606 if tc(inputs, r) { 1607 if i < 2 { 1608 return newCheckResultWithSuccess(0) 1609 } else { 1610 return newCheckResultWithSuccess(i - 1) 1611 } 1612 } 1613 } 1614 castTypes := make([]types.T, len(inputs)) 1615 targetTypes := make([]types.Type, len(inputs)) 1616 for j := 0; j < len(inputs); j++ { 1617 castTypes[j] = types.T_float64 1618 targetTypes[j] = types.T_float64.ToType() 1619 } 1620 c, _ := tryToMatch(inputs, castTypes) 1621 if c == matchFailed { 1622 return newCheckResultWithFailure(failedFunctionParametersWrong) 1623 } 1624 if c == matchByCast { 1625 return newCheckResultWithCast(10, targetTypes) 1626 } 1627 return newCheckResultWithSuccess(10) 1628 } 1629 1630 func FieldNumber[T number](ivecs []*vector.Vector, result vector.FunctionResultWrapper, _ *process.Process, length int) (err error) { 1631 rs := vector.MustFunctionResult[uint64](result) 1632 1633 fs := make([]vector.FunctionParameterWrapper[T], len(ivecs)) 1634 for i := range ivecs { 1635 fs[i] = vector.GenerateFunctionFixedTypeParameter[T](ivecs[i]) 1636 } 1637 1638 nums := make([]uint64, length) 1639 1640 for j := 1; j < len(ivecs); j++ { 1641 1642 for i := uint64(0); i < uint64(length); i++ { 1643 1644 v1, null1 := fs[0].GetValue(i) 1645 v2, null2 := fs[j].GetValue(i) 1646 1647 if (nums[i] != 0) || (null1 || null2) { 1648 continue 1649 } 1650 1651 if v1 == v2 { 1652 nums[i] = uint64(j) 1653 } 1654 1655 } 1656 } 1657 1658 for i := uint64(0); i < uint64(length); i++ { 1659 if err := rs.Append(nums[i], false); err != nil { 1660 return err 1661 } 1662 } 1663 1664 return nil 1665 } 1666 1667 func FieldString(ivecs []*vector.Vector, result vector.FunctionResultWrapper, _ *process.Process, length int) (err error) { 1668 rs := vector.MustFunctionResult[uint64](result) 1669 1670 fs := make([]vector.FunctionParameterWrapper[types.Varlena], len(ivecs)) 1671 for i := range ivecs { 1672 fs[i] = vector.GenerateFunctionStrParameter(ivecs[i]) 1673 } 1674 1675 nums := make([]uint64, length) 1676 1677 for j := 1; j < len(ivecs); j++ { 1678 1679 for i := uint64(0); i < uint64(length); i++ { 1680 1681 v1, null1 := fs[0].GetStrValue(i) 1682 v2, null2 := fs[j].GetStrValue(i) 1683 1684 if (nums[i] != 0) || (null1 || null2) { 1685 continue 1686 } 1687 1688 if strings.EqualFold(functionUtil.QuickBytesToStr(v1), functionUtil.QuickBytesToStr(v2)) { 1689 nums[i] = uint64(j) 1690 } 1691 1692 } 1693 } 1694 1695 for i := uint64(0); i < uint64(length); i++ { 1696 if err := rs.Append(nums[i], false); err != nil { 1697 return err 1698 } 1699 } 1700 1701 return nil 1702 } 1703 1704 func formatCheck(overloads []overload, inputs []types.Type) checkResult { 1705 if len(inputs) > 1 { 1706 // if the first param's type is time type. return failed. 1707 if inputs[0].Oid.IsDateRelate() { 1708 return newCheckResultWithFailure(failedFunctionParametersWrong) 1709 } 1710 return fixedTypeMatch(overloads, inputs) 1711 } 1712 return newCheckResultWithFailure(failedFunctionParametersWrong) 1713 } 1714 1715 func FormatWith2Args(ivecs []*vector.Vector, result vector.FunctionResultWrapper, _ *process.Process, length int) (err error) { 1716 rs := vector.MustFunctionResult[types.Varlena](result) 1717 1718 vs1 := vector.GenerateFunctionStrParameter(ivecs[0]) 1719 vs2 := vector.GenerateFunctionStrParameter(ivecs[1]) 1720 1721 for i := uint64(0); i < uint64(length); i++ { 1722 v1, null1 := vs1.GetStrValue(i) 1723 v2, null2 := vs2.GetStrValue(i) 1724 1725 if null1 || null2 { 1726 if err = rs.AppendBytes(nil, true); err != nil { 1727 return err 1728 } 1729 } else { 1730 val, err := format.GetNumberFormat(string(v1), string(v2), "en_US") 1731 if err != nil { 1732 return err 1733 } 1734 if err = rs.AppendBytes([]byte(val), false); err != nil { 1735 return err 1736 } 1737 } 1738 } 1739 return nil 1740 } 1741 1742 func FormatWith3Args(ivecs []*vector.Vector, result vector.FunctionResultWrapper, _ *process.Process, length int) (err error) { 1743 rs := vector.MustFunctionResult[types.Varlena](result) 1744 1745 vs1 := vector.GenerateFunctionStrParameter(ivecs[0]) 1746 vs2 := vector.GenerateFunctionStrParameter(ivecs[1]) 1747 vs3 := vector.GenerateFunctionStrParameter(ivecs[2]) 1748 1749 val := "" 1750 for i := uint64(0); i < uint64(length); i++ { 1751 v1, null1 := vs1.GetStrValue(i) 1752 v2, null2 := vs2.GetStrValue(i) 1753 v3, null3 := vs3.GetStrValue(i) 1754 1755 if null1 || null2 { 1756 if err = rs.AppendBytes(nil, true); err != nil { 1757 return err 1758 } 1759 } else { 1760 if null3 { 1761 val, err = format.GetNumberFormat(string(v1), string(v2), "en_US") 1762 } else { 1763 val, err = format.GetNumberFormat(string(v1), string(v2), string(v3)) 1764 } 1765 if err != nil { 1766 return err 1767 } 1768 if err = rs.AppendBytes([]byte(val), false); err != nil { 1769 return err 1770 } 1771 } 1772 } 1773 return nil 1774 } 1775 1776 const ( 1777 maxUnixTimestampInt = 32536771199 1778 ) 1779 1780 func FromUnixTimeInt64(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 1781 rs := vector.MustFunctionResult[types.Datetime](result) 1782 vs := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[0]) 1783 1784 var d types.Datetime 1785 for i := uint64(0); i < uint64(length); i++ { 1786 v, null := vs.GetValue(i) 1787 1788 if null || (v < 0 || v > maxUnixTimestampInt) { 1789 if err = rs.Append(d, true); err != nil { 1790 return err 1791 } 1792 } else { 1793 if err = rs.Append(types.DatetimeFromUnix(proc.SessionInfo.TimeZone, v), false); err != nil { 1794 return err 1795 } 1796 } 1797 } 1798 return nil 1799 } 1800 1801 func FromUnixTimeUint64(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 1802 rs := vector.MustFunctionResult[types.Datetime](result) 1803 vs := vector.GenerateFunctionFixedTypeParameter[uint64](ivecs[0]) 1804 1805 var d types.Datetime 1806 for i := uint64(0); i < uint64(length); i++ { 1807 v, null := vs.GetValue(i) 1808 1809 if null || v > maxUnixTimestampInt { 1810 if err = rs.Append(d, true); err != nil { 1811 return err 1812 } 1813 } else { 1814 if err = rs.Append(types.DatetimeFromUnix(proc.SessionInfo.TimeZone, int64(v)), false); err != nil { 1815 return err 1816 } 1817 } 1818 } 1819 return nil 1820 } 1821 1822 func splitDecimalToIntAndFrac(f float64) (int64, int64) { 1823 intPart := int64(f) 1824 nano := (f - float64(intPart)) * math.Pow10(9) 1825 fracPart := int64(nano) 1826 return intPart, fracPart 1827 } 1828 1829 func FromUnixTimeFloat64(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 1830 rs := vector.MustFunctionResult[types.Datetime](result) 1831 vs := vector.GenerateFunctionFixedTypeParameter[float64](ivecs[0]) 1832 rs.TempSetType(types.New(types.T_datetime, 0, 6)) 1833 var d types.Datetime 1834 for i := uint64(0); i < uint64(length); i++ { 1835 v, null := vs.GetValue(i) 1836 1837 if null || (v < 0 || v > maxUnixTimestampInt) { 1838 if err = rs.Append(d, true); err != nil { 1839 return err 1840 } 1841 } else { 1842 x, y := splitDecimalToIntAndFrac(v) 1843 if err = rs.Append(types.DatetimeFromUnixWithNsec(proc.SessionInfo.TimeZone, x, y), false); err != nil { 1844 return err 1845 } 1846 } 1847 } 1848 return nil 1849 } 1850 1851 func FromUnixTimeInt64Format(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 1852 if !ivecs[1].IsConst() { 1853 return moerr.NewInvalidArg(proc.Ctx, "from_unixtime format", "not constant") 1854 } 1855 1856 rs := vector.MustFunctionResult[types.Varlena](result) 1857 vs := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[0]) 1858 formatMask, null1 := vector.GenerateFunctionStrParameter(ivecs[1]).GetStrValue(0) 1859 f := string(formatMask) 1860 1861 var buf bytes.Buffer 1862 for i := uint64(0); i < uint64(length); i++ { 1863 v, null := vs.GetValue(i) 1864 1865 if null || (v < 0 || v > maxUnixTimestampInt) || null1 { 1866 if err = rs.AppendBytes(nil, true); err != nil { 1867 return err 1868 } 1869 } else { 1870 buf.Reset() 1871 r := types.DatetimeFromUnix(proc.SessionInfo.TimeZone, v) 1872 if err = datetimeFormat(proc.Ctx, r, f, &buf); err != nil { 1873 return err 1874 } 1875 if err = rs.AppendBytes(buf.Bytes(), false); err != nil { 1876 return err 1877 } 1878 } 1879 } 1880 return nil 1881 } 1882 1883 func FromUnixTimeUint64Format(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 1884 if !ivecs[1].IsConst() { 1885 return moerr.NewInvalidArg(proc.Ctx, "from_unixtime format", "not constant") 1886 } 1887 1888 rs := vector.MustFunctionResult[types.Varlena](result) 1889 vs := vector.GenerateFunctionFixedTypeParameter[uint64](ivecs[0]) 1890 formatMask, null1 := vector.GenerateFunctionStrParameter(ivecs[1]).GetStrValue(0) 1891 f := string(formatMask) 1892 1893 var buf bytes.Buffer 1894 for i := uint64(0); i < uint64(length); i++ { 1895 v, null := vs.GetValue(i) 1896 1897 if null1 || null || v > maxUnixTimestampInt { 1898 if err = rs.AppendBytes(nil, true); err != nil { 1899 return err 1900 } 1901 } else { 1902 buf.Reset() 1903 r := types.DatetimeFromUnix(proc.SessionInfo.TimeZone, int64(v)) 1904 if err = datetimeFormat(proc.Ctx, r, f, &buf); err != nil { 1905 return err 1906 } 1907 if err = rs.AppendBytes(buf.Bytes(), false); err != nil { 1908 return err 1909 } 1910 } 1911 } 1912 return nil 1913 } 1914 1915 func FromUnixTimeFloat64Format(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 1916 if !ivecs[1].IsConst() { 1917 return moerr.NewInvalidArg(proc.Ctx, "from_unixtime format", "not constant") 1918 } 1919 1920 rs := vector.MustFunctionResult[types.Varlena](result) 1921 vs := vector.GenerateFunctionFixedTypeParameter[float64](ivecs[0]) 1922 formatMask, null1 := vector.GenerateFunctionStrParameter(ivecs[1]).GetStrValue(0) 1923 f := string(formatMask) 1924 1925 var buf bytes.Buffer 1926 for i := uint64(0); i < uint64(length); i++ { 1927 v, null := vs.GetValue(i) 1928 1929 if null || (v < 0 || v > maxUnixTimestampInt) || null1 { 1930 if err = rs.AppendBytes(nil, true); err != nil { 1931 return err 1932 } 1933 } else { 1934 buf.Reset() 1935 x, y := splitDecimalToIntAndFrac(v) 1936 r := types.DatetimeFromUnixWithNsec(proc.SessionInfo.TimeZone, x, y) 1937 if err = datetimeFormat(proc.Ctx, r, f, &buf); err != nil { 1938 return err 1939 } 1940 if err = rs.AppendBytes(buf.Bytes(), false); err != nil { 1941 return err 1942 } 1943 } 1944 } 1945 return nil 1946 } 1947 1948 // Slice from left to right, starting from 0 1949 func getSliceFromLeft(s string, offset int64) string { 1950 sourceRune := []rune(s) 1951 elemsize := int64(len(sourceRune)) 1952 if offset > elemsize { 1953 return "" 1954 } 1955 substrRune := sourceRune[offset:] 1956 return string(substrRune) 1957 } 1958 1959 // Cut slices from right to left, starting from 1 1960 func getSliceFromRight(s string, offset int64) string { 1961 sourceRune := []rune(s) 1962 elemsize := int64(len(sourceRune)) 1963 if offset > elemsize { 1964 return "" 1965 } 1966 substrRune := sourceRune[elemsize-offset:] 1967 return string(substrRune) 1968 } 1969 1970 func SubStringWith2Args(ivecs []*vector.Vector, result vector.FunctionResultWrapper, _ *process.Process, length int) (err error) { 1971 rs := vector.MustFunctionResult[types.Varlena](result) 1972 vs := vector.GenerateFunctionStrParameter(ivecs[0]) 1973 starts := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[1]) 1974 1975 for i := uint64(0); i < uint64(length); i++ { 1976 v, null1 := vs.GetStrValue(i) 1977 s, null2 := starts.GetValue(i) 1978 1979 if null1 || null2 { 1980 if err = rs.AppendBytes(nil, true); err != nil { 1981 return err 1982 } 1983 } else { 1984 var r string 1985 if s > 0 { 1986 r = getSliceFromLeft(functionUtil.QuickBytesToStr(v), s-1) 1987 } else if s < 0 { 1988 r = getSliceFromRight(functionUtil.QuickBytesToStr(v), -s) 1989 } else { 1990 r = "" 1991 } 1992 if err = rs.AppendBytes(functionUtil.QuickStrToBytes(r), false); err != nil { 1993 return err 1994 } 1995 } 1996 } 1997 return nil 1998 } 1999 2000 // Cut the slice with length from left to right, starting from 0 2001 func getSliceFromLeftWithLength(s string, offset int64, length int64) string { 2002 if offset < 0 { 2003 return "" 2004 } 2005 return getSliceOffsetLen(s, offset, length) 2006 } 2007 2008 func getSliceOffsetLen(s string, offset int64, length int64) string { 2009 sourceRune := []rune(s) 2010 elemsize := int64(len(sourceRune)) 2011 if offset < 0 { 2012 offset += elemsize 2013 if offset < 0 { 2014 return "" 2015 } 2016 } 2017 if offset >= elemsize { 2018 return "" 2019 } 2020 2021 if length <= 0 { 2022 return "" 2023 } else { 2024 end := offset + length 2025 if end > elemsize { 2026 end = elemsize 2027 } 2028 substrRune := sourceRune[offset:end] 2029 return string(substrRune) 2030 } 2031 } 2032 2033 // From right to left, cut the slice with length from 1 2034 func getSliceFromRightWithLength(s string, offset int64, length int64) string { 2035 return getSliceOffsetLen(s, -offset, length) 2036 } 2037 2038 func SubStringWith3Args(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 2039 rs := vector.MustFunctionResult[types.Varlena](result) 2040 vs := vector.GenerateFunctionStrParameter(ivecs[0]) 2041 starts := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[1]) 2042 lens := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[2]) 2043 2044 for i := uint64(0); i < uint64(length); i++ { 2045 v, null1 := vs.GetStrValue(i) 2046 s, null2 := starts.GetValue(i) 2047 l, null3 := lens.GetValue(i) 2048 2049 if null1 || null2 || null3 { 2050 if err = rs.AppendBytes(nil, true); err != nil { 2051 return err 2052 } 2053 } else { 2054 var r string 2055 if s > 0 { 2056 r = getSliceFromLeftWithLength(functionUtil.QuickBytesToStr(v), s-1, l) 2057 } else if s < 0 { 2058 r = getSliceFromRightWithLength(functionUtil.QuickBytesToStr(v), -s, l) 2059 } else { 2060 r = "" 2061 } 2062 if err = rs.AppendBytes(functionUtil.QuickStrToBytes(r), false); err != nil { 2063 return err 2064 } 2065 } 2066 } 2067 return nil 2068 } 2069 2070 func subStrIndex(str, delim string, count int64) (string, error) { 2071 // if the length of delim is 0, return empty string 2072 if len(delim) == 0 { 2073 return "", nil 2074 } 2075 // if the count is 0, return empty string 2076 if count == 0 { 2077 return "", nil 2078 } 2079 2080 partions := strings.Split(str, delim) 2081 start, end := int64(0), int64(len(partions)) 2082 2083 if count > 0 { 2084 //is count is positive, reset the end position 2085 if count < end { 2086 end = count 2087 } 2088 } else { 2089 count = -count 2090 2091 // -count overflows max int64, return the whole string. 2092 if count < 0 { 2093 return str, nil 2094 } 2095 2096 //if count is negative, reset the start postion 2097 if count < end { 2098 start = end - count 2099 } 2100 } 2101 subPartions := partions[start:end] 2102 return strings.Join(subPartions, delim), nil 2103 } 2104 2105 func getCount[T number](typ types.Type, val T) int64 { 2106 var r int64 2107 switch typ.Oid { 2108 case types.T_float64: 2109 v := float64(val) 2110 if v > float64(math.MaxInt64) { 2111 r = math.MaxInt64 2112 } else if v < float64(math.MinInt64) { 2113 r = math.MinInt64 2114 } else { 2115 r = int64(v) 2116 } 2117 case types.T_uint64, types.T_bit: 2118 v := uint64(val) 2119 if v > uint64(math.MaxInt64) { 2120 r = math.MaxInt64 2121 } else { 2122 r = int64(v) 2123 } 2124 default: 2125 r = int64(val) 2126 } 2127 return r 2128 } 2129 2130 func SubStrIndex[T number](ivecs []*vector.Vector, result vector.FunctionResultWrapper, _ *process.Process, length int) (err error) { 2131 rs := vector.MustFunctionResult[types.Varlena](result) 2132 vs := vector.GenerateFunctionStrParameter(ivecs[0]) 2133 delims := vector.GenerateFunctionStrParameter(ivecs[1]) 2134 counts := vector.GenerateFunctionFixedTypeParameter[T](ivecs[2]) 2135 typ := counts.GetType() 2136 2137 for i := uint64(0); i < uint64(length); i++ { 2138 v, null1 := vs.GetStrValue(i) 2139 d, null2 := delims.GetStrValue(i) 2140 c, null3 := counts.GetValue(i) 2141 2142 if null1 || null2 || null3 { 2143 if err = rs.AppendBytes(nil, true); err != nil { 2144 return err 2145 } 2146 } else { 2147 r, err := subStrIndex(string(v), string(d), getCount(typ, c)) 2148 if err != nil { 2149 return err 2150 } 2151 2152 if err = rs.AppendBytes([]byte(r), false); err != nil { 2153 return err 2154 } 2155 } 2156 } 2157 return nil 2158 } 2159 2160 func StartsWith(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 2161 return opBinaryBytesBytesToFixed[bool](ivecs, result, proc, length, bytes.HasPrefix) 2162 } 2163 2164 func EndsWith(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 2165 return opBinaryBytesBytesToFixed[bool](ivecs, result, proc, length, bytes.HasSuffix) 2166 } 2167 2168 // https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html#function_sha2 2169 func SHA2Func(args []*vector.Vector, result vector.FunctionResultWrapper, _ *process.Process, length int) (err error) { 2170 res := vector.MustFunctionResult[types.Varlena](result) 2171 strs := vector.GenerateFunctionStrParameter(args[0]) 2172 shaTypes := vector.GenerateFunctionFixedTypeParameter[int64](args[1]) 2173 2174 for i := uint64(0); i < uint64(length); i++ { 2175 str, isnull1 := strs.GetStrValue(i) 2176 shaType, isnull2 := shaTypes.GetValue(i) 2177 2178 if isnull1 || isnull2 || !isSha2Family(shaType) { 2179 if err = res.AppendBytes(nil, true); err != nil { 2180 return err 2181 } 2182 } else { 2183 var checksum []byte 2184 2185 switch shaType { 2186 case 0, 256: 2187 sum256 := sha256.Sum256(str) 2188 checksum = sum256[:] 2189 case 224: 2190 sum224 := sha256.Sum224(str) 2191 checksum = sum224[:] 2192 case 384: 2193 sum384 := sha512.Sum384(str) 2194 checksum = sum384[:] 2195 case 512: 2196 sum512 := sha512.Sum512(str) 2197 checksum = sum512[:] 2198 default: 2199 panic("unexpected err happened in sha2 function") 2200 } 2201 checksum = []byte(hex.EncodeToString(checksum)) 2202 if err = res.AppendBytes(checksum, false); err != nil { 2203 return err 2204 } 2205 } 2206 2207 } 2208 2209 return nil 2210 } 2211 2212 // any one of 224 256 384 512 0 is valid 2213 func isSha2Family(len int64) bool { 2214 return len == 0 || len == 224 || len == 256 || len == 384 || len == 512 2215 } 2216 2217 func ExtractFromDate(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 2218 extractFromDate := func(unit string, d types.Date) (uint32, error) { 2219 var r uint32 2220 switch unit { 2221 case "day": 2222 r = uint32(d.Day()) 2223 case "week": 2224 r = uint32(d.WeekOfYear2()) 2225 case "month": 2226 r = uint32(d.Month()) 2227 case "quarter": 2228 r = d.Quarter() 2229 case "year_month": 2230 r = d.YearMonth() 2231 case "year": 2232 r = uint32(d.Year()) 2233 default: 2234 return 0, moerr.NewInternalErrorNoCtx("invalid unit") 2235 } 2236 return r, nil 2237 } 2238 2239 if !ivecs[0].IsConst() { 2240 return moerr.NewInternalError(proc.Ctx, "invalid input for extract") 2241 } 2242 2243 return opBinaryStrFixedToFixedWithErrorCheck[types.Date, uint32](ivecs, result, proc, length, extractFromDate) 2244 } 2245 2246 func ExtractFromDatetime(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 2247 if !ivecs[0].IsConst() { 2248 return moerr.NewInternalError(proc.Ctx, "invalid input") 2249 } 2250 2251 p1 := vector.GenerateFunctionStrParameter(ivecs[0]) 2252 p2 := vector.GenerateFunctionFixedTypeParameter[types.Datetime](ivecs[1]) 2253 rs := vector.MustFunctionResult[types.Varlena](result) 2254 2255 v1, null1 := p1.GetStrValue(0) 2256 if null1 { 2257 for i := uint64(0); i < uint64(length); i++ { 2258 if err = rs.AppendBytes(nil, true); err != nil { 2259 return err 2260 } 2261 } 2262 return nil 2263 } 2264 unit := functionUtil.QuickBytesToStr(v1) 2265 for i := uint64(0); i < uint64(length); i++ { 2266 v2, null2 := p2.GetValue(i) 2267 if null2 { 2268 if err = rs.AppendBytes(nil, true); err != nil { 2269 return err 2270 } 2271 } else { 2272 res, _ := extractFromDatetime(unit, v2) 2273 if err = rs.AppendBytes(functionUtil.QuickStrToBytes(res), false); err != nil { 2274 return err 2275 } 2276 } 2277 } 2278 2279 return nil 2280 } 2281 2282 var validDatetimeUnit = map[string]struct{}{ 2283 "microsecond": {}, 2284 "second": {}, 2285 "minute": {}, 2286 "hour": {}, 2287 "day": {}, 2288 "week": {}, 2289 "month": {}, 2290 "quarter": {}, 2291 "year": {}, 2292 "second_microsecond": {}, 2293 "minute_microsecond": {}, 2294 "minute_second": {}, 2295 "hour_microsecond": {}, 2296 "hour_second": {}, 2297 "hour_minute": {}, 2298 "day_microsecond": {}, 2299 "day_second": {}, 2300 "day_minute": {}, 2301 "day_hour": {}, 2302 "year_month": {}, 2303 } 2304 2305 func extractFromDatetime(unit string, d types.Datetime) (string, error) { 2306 if _, ok := validDatetimeUnit[unit]; !ok { 2307 return "", moerr.NewInternalErrorNoCtx("invalid unit") 2308 } 2309 var value string 2310 switch unit { 2311 case "microsecond": 2312 value = fmt.Sprintf("%d", int(d.MicroSec())) 2313 case "second": 2314 value = fmt.Sprintf("%02d", int(d.Sec())) 2315 case "minute": 2316 value = fmt.Sprintf("%02d", int(d.Minute())) 2317 case "hour": 2318 value = fmt.Sprintf("%02d", int(d.Hour())) 2319 case "day": 2320 value = fmt.Sprintf("%02d", int(d.ToDate().Day())) 2321 case "week": 2322 value = fmt.Sprintf("%02d", int(d.ToDate().WeekOfYear2())) 2323 case "month": 2324 value = fmt.Sprintf("%02d", int(d.ToDate().Month())) 2325 case "quarter": 2326 value = fmt.Sprintf("%d", int(d.ToDate().Quarter())) 2327 case "year": 2328 value = fmt.Sprintf("%04d", int(d.ToDate().Year())) 2329 case "second_microsecond": 2330 value = d.SecondMicrosecondStr() 2331 case "minute_microsecond": 2332 value = d.MinuteMicrosecondStr() 2333 case "minute_second": 2334 value = d.MinuteSecondStr() 2335 case "hour_microsecond": 2336 value = d.HourMicrosecondStr() 2337 case "hour_second": 2338 value = d.HourSecondStr() 2339 case "hour_minute": 2340 value = d.HourMinuteStr() 2341 case "day_microsecond": 2342 value = d.DayMicrosecondStr() 2343 case "day_second": 2344 value = d.DaySecondStr() 2345 case "day_minute": 2346 value = d.DayMinuteStr() 2347 case "day_hour": 2348 value = d.DayHourStr() 2349 case "year_month": 2350 value = d.ToDate().YearMonthStr() 2351 } 2352 return value, nil 2353 } 2354 2355 func ExtractFromTime(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 2356 if !ivecs[0].IsConst() { 2357 return moerr.NewInternalError(proc.Ctx, "invalid input for extract") 2358 } 2359 2360 p1 := vector.GenerateFunctionStrParameter(ivecs[0]) 2361 p2 := vector.GenerateFunctionFixedTypeParameter[types.Time](ivecs[1]) 2362 rs := vector.MustFunctionResult[types.Varlena](result) 2363 2364 v1, null1 := p1.GetStrValue(0) 2365 if null1 { 2366 for i := uint64(0); i < uint64(length); i++ { 2367 if err = rs.AppendBytes(nil, true); err != nil { 2368 return err 2369 } 2370 } 2371 return nil 2372 } 2373 unit := functionUtil.QuickBytesToStr(v1) 2374 for i := uint64(0); i < uint64(length); i++ { 2375 v2, null2 := p2.GetValue(i) 2376 if null2 { 2377 if err = rs.AppendBytes(nil, true); err != nil { 2378 return err 2379 } 2380 } else { 2381 res, _ := extractFromTime(unit, v2) 2382 if err = rs.AppendBytes(functionUtil.QuickStrToBytes(res), false); err != nil { 2383 return err 2384 } 2385 } 2386 } 2387 2388 return nil 2389 } 2390 2391 var validTimeUnit = map[string]struct{}{ 2392 "microsecond": {}, 2393 "second": {}, 2394 "minute": {}, 2395 "hour": {}, 2396 "second_microsecond": {}, 2397 "minute_microsecond": {}, 2398 "minute_second": {}, 2399 "hour_microsecond": {}, 2400 "hour_second": {}, 2401 "hour_minute": {}, 2402 "day_microsecond": {}, 2403 "day_second": {}, 2404 "day_minute": {}, 2405 "day_hour": {}, 2406 } 2407 2408 func extractFromTime(unit string, t types.Time) (string, error) { 2409 if _, ok := validTimeUnit[unit]; !ok { 2410 return "", moerr.NewInternalErrorNoCtx("invalid unit") 2411 } 2412 var value string 2413 switch unit { 2414 case "microsecond": 2415 value = fmt.Sprintf("%d", int(t)) 2416 case "second": 2417 value = fmt.Sprintf("%02d", int(t.Sec())) 2418 case "minute": 2419 value = fmt.Sprintf("%02d", int(t.Minute())) 2420 case "hour", "day_hour": 2421 value = fmt.Sprintf("%02d", int(t.Hour())) 2422 case "second_microsecond": 2423 microSec := fmt.Sprintf("%0*d", 6, int(t.MicroSec())) 2424 value = fmt.Sprintf("%2d%s", int(t.Sec()), microSec) 2425 case "minute_microsecond": 2426 microSec := fmt.Sprintf("%0*d", 6, int(t.MicroSec())) 2427 value = fmt.Sprintf("%2d%2d%s", int(t.Minute()), int(t.Sec()), microSec) 2428 case "minute_second": 2429 value = fmt.Sprintf("%2d%2d", int(t.Minute()), int(t.Sec())) 2430 case "hour_microsecond", "day_microsecond": 2431 microSec := fmt.Sprintf("%0*d", 6, int(t.MicroSec())) 2432 value = fmt.Sprintf("%2d%2d%2d%s", int(t.Hour()), int(t.Minute()), int(t.Sec()), microSec) 2433 case "hour_second", "day_second": 2434 value = fmt.Sprintf("%2d%2d%2d", int(t.Hour()), int(t.Minute()), int(t.Sec())) 2435 case "hour_minute", "day_minute": 2436 value = fmt.Sprintf("%2d%2d", int(t.Hour()), int(t.Minute())) 2437 } 2438 return value, nil 2439 } 2440 2441 func ExtractFromVarchar(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 2442 if !ivecs[0].IsConst() { 2443 return moerr.NewInternalError(proc.Ctx, "invalid input for extract") 2444 } 2445 2446 p1 := vector.GenerateFunctionStrParameter(ivecs[0]) 2447 p2 := vector.GenerateFunctionStrParameter(ivecs[1]) 2448 rs := vector.MustFunctionResult[types.Varlena](result) 2449 2450 v1, null1 := p1.GetStrValue(0) 2451 if null1 { 2452 for i := uint64(0); i < uint64(length); i++ { 2453 if err = rs.AppendBytes(nil, true); err != nil { 2454 return err 2455 } 2456 } 2457 return nil 2458 } 2459 unit := functionUtil.QuickBytesToStr(v1) 2460 scale := p2.GetType().Scale 2461 for i := uint64(0); i < uint64(length); i++ { 2462 v2, null2 := p2.GetStrValue(i) 2463 if null2 { 2464 if err = rs.AppendBytes(nil, true); err != nil { 2465 return err 2466 } 2467 } else { 2468 res, err := extractFromVarchar(unit, functionUtil.QuickBytesToStr(v2), scale) 2469 if err != nil { 2470 return err 2471 } 2472 if err = rs.AppendBytes(functionUtil.QuickStrToBytes(res), false); err != nil { 2473 return err 2474 } 2475 } 2476 } 2477 2478 return nil 2479 } 2480 2481 func extractFromVarchar(unit string, t string, scale int32) (string, error) { 2482 var result string 2483 if len(t) == 0 { 2484 result = t 2485 } else if value, err := types.ParseDatetime(t, scale); err == nil { 2486 result, err = extractFromDatetime(unit, value) 2487 if err != nil { 2488 return "", err 2489 } 2490 } else if value, err := types.ParseTime(t, scale); err == nil { 2491 result, err = extractFromTime(unit, value) 2492 if err != nil { 2493 return "", err 2494 } 2495 } else { 2496 return "", moerr.NewInternalErrorNoCtx("invalid input") 2497 } 2498 2499 return result, nil 2500 } 2501 2502 func FindInSet(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 2503 findInStrList := func(str, strlist string) uint64 { 2504 for j, s := range strings.Split(strlist, ",") { 2505 if s == str { 2506 return uint64(j + 1) 2507 } 2508 } 2509 return 0 2510 } 2511 2512 return opBinaryStrStrToFixed[uint64](ivecs, result, proc, length, findInStrList) 2513 } 2514 2515 func Instr(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 2516 return opBinaryStrStrToFixed[int64](ivecs, result, proc, length, instr.Single) 2517 } 2518 2519 func Left(ivecs []*vector.Vector, result vector.FunctionResultWrapper, _ *process.Process, length int) (err error) { 2520 p1 := vector.GenerateFunctionStrParameter(ivecs[0]) 2521 p2 := vector.GenerateFunctionFixedTypeParameter[int64](ivecs[1]) 2522 rs := vector.MustFunctionResult[types.Varlena](result) 2523 2524 for i := uint64(0); i < uint64(length); i++ { 2525 v1, null1 := p1.GetStrValue(i) 2526 v2, null2 := p2.GetValue(i) 2527 if null1 || null2 { 2528 if err = rs.AppendBytes(nil, true); err != nil { 2529 return err 2530 } 2531 } else { 2532 //TODO: Ignoring 4 switch cases: https://github.com/m-schen/matrixone/blob/0c480ca11b6302de26789f916a3e2faca7f79d47/pkg/sql/plan/function/builtin/binary/left.go#L38 2533 res := evalLeft(functionUtil.QuickBytesToStr(v1), v2) 2534 if err = rs.AppendBytes(functionUtil.QuickStrToBytes(res), false); err != nil { 2535 return err 2536 } 2537 } 2538 } 2539 return nil 2540 } 2541 2542 func evalLeft(str string, length int64) string { 2543 runeStr := []rune(str) 2544 leftLength := int(length) 2545 if strLength := len(runeStr); leftLength > strLength { 2546 leftLength = strLength 2547 } else if leftLength < 0 { 2548 leftLength = 0 2549 } 2550 return string(runeStr[:leftLength]) 2551 } 2552 2553 func Power(ivecs []*vector.Vector, result vector.FunctionResultWrapper, _ *process.Process, length int) (err error) { 2554 p1 := vector.GenerateFunctionFixedTypeParameter[float64](ivecs[0]) 2555 p2 := vector.GenerateFunctionFixedTypeParameter[float64](ivecs[1]) 2556 rs := vector.MustFunctionResult[float64](result) 2557 2558 for i := uint64(0); i < uint64(length); i++ { 2559 v1, null1 := p1.GetValue(i) 2560 v2, null2 := p2.GetValue(i) 2561 if null1 || null2 { 2562 if err = rs.Append(0, true); err != nil { 2563 return err 2564 } 2565 } else { 2566 //TODO: Ignoring 4 switch cases:https://github.com/m-schen/matrixone/blob/0c480ca11b6302de26789f916a3e2faca7f79d47/pkg/sql/plan/function/builtin/binary/power.go#L36 2567 res := math.Pow(v1, v2) 2568 if err = rs.Append(res, false); err != nil { 2569 return err 2570 } 2571 } 2572 } 2573 return nil 2574 } 2575 2576 func TimeDiff[T types.Time | types.Datetime](ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 2577 return opBinaryFixedFixedToFixedWithErrorCheck[T, T, types.Time](ivecs, result, proc, length, timeDiff[T]) 2578 } 2579 2580 func timeDiff[T types.Time | types.Datetime](v1, v2 T) (types.Time, error) { 2581 tmpTime := int64(v1 - v2) 2582 // different sign need to check overflow 2583 if (int64(v1)>>63)^(int64(v2)>>63) != 0 { 2584 if (tmpTime>>63)^(int64(v1)>>63) != 0 { 2585 // overflow 2586 isNeg := int64(v1) < 0 2587 return types.TimeFromClock(isNeg, types.MaxHourInTime, 59, 59, 0), nil 2588 } 2589 } 2590 2591 // same sign don't need to check overflow 2592 tt := types.Time(tmpTime) 2593 hour, _, _, _, isNeg := tt.ClockFormat() 2594 if !types.ValidTime(uint64(hour), 0, 0) { 2595 return types.TimeFromClock(isNeg, types.MaxHourInTime, 59, 59, 0), nil 2596 } 2597 return tt, nil 2598 } 2599 2600 func TimestampDiff(ivecs []*vector.Vector, result vector.FunctionResultWrapper, _ *process.Process, length int) (err error) { 2601 p1 := vector.GenerateFunctionStrParameter(ivecs[0]) 2602 p2 := vector.GenerateFunctionFixedTypeParameter[types.Datetime](ivecs[1]) 2603 p3 := vector.GenerateFunctionFixedTypeParameter[types.Datetime](ivecs[2]) 2604 rs := vector.MustFunctionResult[int64](result) 2605 2606 for i := uint64(0); i < uint64(length); i++ { 2607 v1, null1 := p1.GetStrValue(i) 2608 v2, null2 := p2.GetValue(i) 2609 v3, null3 := p3.GetValue(i) 2610 if null1 || null2 || null3 { 2611 if err = rs.Append(0, true); err != nil { 2612 return err 2613 } 2614 } else { 2615 res, _ := v3.DateTimeDiffWithUnit(functionUtil.QuickBytesToStr(v1), v2) 2616 if err = rs.Append(res, false); err != nil { 2617 return err 2618 } 2619 } 2620 } 2621 return nil 2622 } 2623 2624 func Replace(ivecs []*vector.Vector, result vector.FunctionResultWrapper, _ *process.Process, length int) (err error) { 2625 p1 := vector.GenerateFunctionStrParameter(ivecs[0]) 2626 p2 := vector.GenerateFunctionStrParameter(ivecs[1]) 2627 p3 := vector.GenerateFunctionStrParameter(ivecs[2]) 2628 rs := vector.MustFunctionResult[types.Varlena](result) 2629 2630 for i := uint64(0); i < uint64(length); i++ { 2631 v1, null1 := p1.GetStrValue(i) 2632 v2, null2 := p2.GetStrValue(i) 2633 v3, null3 := p3.GetStrValue(i) 2634 2635 if null1 || null2 || null3 { 2636 if err = rs.AppendBytes(nil, true); err != nil { 2637 return err 2638 } 2639 } else { 2640 v1Str := functionUtil.QuickBytesToStr(v1) 2641 v2Str := functionUtil.QuickBytesToStr(v2) 2642 var res string 2643 if v2Str == "" { 2644 res = v1Str 2645 } else { 2646 res = strings.ReplaceAll(v1Str, v2Str, functionUtil.QuickBytesToStr(v3)) 2647 } 2648 2649 if err = rs.AppendBytes(functionUtil.QuickStrToBytes(res), false); err != nil { 2650 return err 2651 } 2652 } 2653 } 2654 return nil 2655 } 2656 2657 func Trim(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 2658 p1 := vector.GenerateFunctionStrParameter(ivecs[0]) 2659 p2 := vector.GenerateFunctionStrParameter(ivecs[1]) 2660 p3 := vector.GenerateFunctionStrParameter(ivecs[2]) 2661 rs := vector.MustFunctionResult[types.Varlena](result) 2662 2663 for i := uint64(0); i < uint64(length); i++ { 2664 2665 v1, null1 := p1.GetStrValue(i) 2666 src, null2 := p2.GetStrValue(i) 2667 cut, null3 := p3.GetStrValue(i) 2668 2669 if null1 || null2 || null3 { 2670 if err = rs.AppendBytes(nil, true); err != nil { 2671 return err 2672 } 2673 } else { 2674 2675 v1Str := strings.ToLower(string(v1)) 2676 var res string 2677 switch v1Str { 2678 case "both": 2679 res = trimBoth(string(cut), string(src)) 2680 case "leading": 2681 res = trimLeading(string(cut), string(src)) 2682 case "trailing": 2683 res = trimTrailing(string(cut), string(src)) 2684 default: 2685 return moerr.NewNotSupported(proc.Ctx, "trim type %s", v1Str) 2686 } 2687 2688 if err = rs.AppendBytes([]byte(res), false); err != nil { 2689 return err 2690 } 2691 } 2692 2693 } 2694 return nil 2695 } 2696 2697 func trimBoth(src, cuts string) string { 2698 if len(cuts) == 0 { 2699 return src 2700 } 2701 return trimLeading(trimTrailing(src, cuts), cuts) 2702 } 2703 2704 func trimLeading(src, cuts string) string { 2705 if len(cuts) == 0 { 2706 return src 2707 } 2708 for strings.HasPrefix(src, cuts) { 2709 src = src[len(cuts):] 2710 } 2711 return src 2712 } 2713 2714 func trimTrailing(src, cuts string) string { 2715 if len(cuts) == 0 { 2716 return src 2717 } 2718 for strings.HasSuffix(src, cuts) { 2719 src = src[:len(src)-len(cuts)] 2720 } 2721 return src 2722 } 2723 2724 // JSON_EXTRACT 2725 func jsonExtractCheckFn(overloads []overload, inputs []types.Type) checkResult { 2726 if len(inputs) > 1 { 2727 ts := make([]types.Type, 0, len(inputs)) 2728 allMatch := true 2729 for _, input := range inputs { 2730 if input.Oid == types.T_json || input.Oid.IsMySQLString() { 2731 ts = append(ts, input) 2732 } else { 2733 if canCast, _ := fixedImplicitTypeCast(input, types.T_varchar); canCast { 2734 ts = append(ts, types.T_varchar.ToType()) 2735 allMatch = false 2736 } else { 2737 return newCheckResultWithFailure(failedFunctionParametersWrong) 2738 } 2739 } 2740 } 2741 if allMatch { 2742 return newCheckResultWithSuccess(0) 2743 } 2744 return newCheckResultWithCast(0, ts) 2745 } 2746 return newCheckResultWithFailure(failedFunctionParametersWrong) 2747 } 2748 2749 type computeFn func([]byte, []*bytejson.Path) (*bytejson.ByteJson, error) 2750 2751 func computeJson(json []byte, paths []*bytejson.Path) (*bytejson.ByteJson, error) { 2752 bj := types.DecodeJson(json) 2753 return bj.Query(paths), nil 2754 } 2755 2756 func computeString(json []byte, paths []*bytejson.Path) (*bytejson.ByteJson, error) { 2757 bj, err := types.ParseSliceToByteJson(json) 2758 if err != nil { 2759 return nil, err 2760 } 2761 return bj.Query(paths), nil 2762 } 2763 2764 func JsonExtract(parameters []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) error { 2765 jsonVec := parameters[0] 2766 var fn computeFn 2767 switch jsonVec.GetType().Oid { 2768 case types.T_json: 2769 fn = computeJson 2770 default: 2771 fn = computeString 2772 } 2773 jsonWrapper := vector.GenerateFunctionStrParameter(jsonVec) 2774 pathWrapers := make([]vector.FunctionParameterWrapper[types.Varlena], len(parameters)-1) 2775 rs := vector.MustFunctionResult[types.Varlena](result) 2776 paths := make([]*bytejson.Path, len(parameters)-1) 2777 for i := 0; i < len(parameters)-1; i++ { 2778 pathWrapers[i] = vector.GenerateFunctionStrParameter(parameters[i+1]) 2779 } 2780 for i := uint64(0); i < uint64(length); i++ { 2781 jsonBytes, jIsNull := jsonWrapper.GetStrValue(i) 2782 if jIsNull { 2783 err := rs.AppendBytes(nil, true) 2784 if err != nil { 2785 return err 2786 } 2787 continue 2788 } 2789 skip := false 2790 for j := 0; j < len(parameters)-1; j++ { 2791 pathBytes, pIsNull := pathWrapers[j].GetStrValue(i) 2792 if pIsNull { 2793 skip = true 2794 break 2795 } 2796 p, err := types.ParseStringToPath(string(pathBytes)) 2797 if err != nil { 2798 return err 2799 } 2800 paths[j] = &p 2801 } 2802 if skip { 2803 err := rs.AppendBytes(nil, true) 2804 if err != nil { 2805 return err 2806 } 2807 continue 2808 } 2809 out, err := fn(jsonBytes, paths) 2810 if err != nil { 2811 return err 2812 } 2813 if out.IsNull() { 2814 err := rs.AppendBytes(nil, true) 2815 if err != nil { 2816 return err 2817 } 2818 continue 2819 } 2820 dt, _ := out.Marshal() 2821 err = rs.AppendBytes(dt, false) 2822 if err != nil { 2823 return err 2824 } 2825 } 2826 return nil 2827 } 2828 2829 // SPLIT PART 2830 2831 func SplitPart(ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) (err error) { 2832 p1 := vector.GenerateFunctionStrParameter(ivecs[0]) 2833 p2 := vector.GenerateFunctionStrParameter(ivecs[1]) 2834 p3 := vector.GenerateFunctionFixedTypeParameter[uint32](ivecs[2]) 2835 rs := vector.MustFunctionResult[types.Varlena](result) 2836 2837 for i := uint64(0); i < uint64(length); i++ { 2838 v1, null1 := p1.GetStrValue(i) 2839 v2, null2 := p2.GetStrValue(i) 2840 v3, null3 := p3.GetValue(i) 2841 if null1 || null2 || null3 { 2842 if err = rs.AppendBytes(nil, true); err != nil { 2843 return err 2844 } 2845 } else { 2846 2847 if v3 == 0 { 2848 err = moerr.NewInvalidInput(proc.Ctx, "split_part: field contains non-positive integer") 2849 return 2850 } 2851 2852 res, isNull := SplitSingle(string(v1), string(v2), v3) 2853 if isNull { 2854 if err = rs.AppendBytes(nil, true); err != nil { 2855 return err 2856 } 2857 } else { 2858 if err = rs.AppendBytes([]byte(res), false); err != nil { 2859 return err 2860 } 2861 } 2862 } 2863 } 2864 return nil 2865 } 2866 2867 func SplitSingle(str, sep string, cnt uint32) (string, bool) { 2868 expectedLen := int(cnt + 1) 2869 strSlice := strings.SplitN(str, sep, expectedLen) 2870 if len(strSlice) < int(cnt) { 2871 return "", true 2872 } 2873 return strSlice[cnt-1], false 2874 } 2875 2876 func InnerProductArray[T types.RealNumbers](ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) error { 2877 return opBinaryBytesBytesToFixedWithErrorCheck[float64](ivecs, result, proc, length, func(v1, v2 []byte) (out float64, err error) { 2878 _v1 := types.BytesToArray[T](v1) 2879 _v2 := types.BytesToArray[T](v2) 2880 2881 return moarray.InnerProduct[T](_v1, _v2) 2882 }) 2883 } 2884 2885 func CosineSimilarityArray[T types.RealNumbers](ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) error { 2886 return opBinaryBytesBytesToFixedWithErrorCheck[float64](ivecs, result, proc, length, func(v1, v2 []byte) (out float64, err error) { 2887 _v1 := types.BytesToArray[T](v1) 2888 _v2 := types.BytesToArray[T](v2) 2889 return moarray.CosineSimilarity[T](_v1, _v2) 2890 }) 2891 } 2892 2893 func L2DistanceArray[T types.RealNumbers](ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) error { 2894 return opBinaryBytesBytesToFixedWithErrorCheck[float64](ivecs, result, proc, length, func(v1, v2 []byte) (out float64, err error) { 2895 _v1 := types.BytesToArray[T](v1) 2896 _v2 := types.BytesToArray[T](v2) 2897 return moarray.L2Distance[T](_v1, _v2) 2898 }) 2899 } 2900 2901 func CosineDistanceArray[T types.RealNumbers](ivecs []*vector.Vector, result vector.FunctionResultWrapper, proc *process.Process, length int) error { 2902 return opBinaryBytesBytesToFixedWithErrorCheck[float64](ivecs, result, proc, length, func(v1, v2 []byte) (out float64, err error) { 2903 _v1 := types.BytesToArray[T](v1) 2904 _v2 := types.BytesToArray[T](v2) 2905 return moarray.CosineDistance[T](_v1, _v2) 2906 }) 2907 }