github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_miscellaneous_vec.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package memex 15 16 import ( 17 "bytes" 18 "encoding/binary" 19 "fmt" 20 "math" 21 "net" 22 "strings" 23 "sync/atomic" 24 "time" 25 26 "github.com/google/uuid" 27 "github.com/whtcorpsinc/milevadb/stochastikctx/variable" 28 "github.com/whtcorpsinc/milevadb/types" 29 "github.com/whtcorpsinc/milevadb/soliton/chunk" 30 ) 31 32 func (b *builtinInetNtoaSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 33 n := input.NumEvents() 34 buf, err := b.bufSlabPredictor.get(types.ETInt, n) 35 if err != nil { 36 return err 37 } 38 defer b.bufSlabPredictor.put(buf) 39 if err := b.args[0].VecEvalInt(b.ctx, input, buf); err != nil { 40 return err 41 } 42 43 result.ReserveString(n) 44 i64s := buf.Int64s() 45 ip := make(net.IP, net.IPv4len) 46 for i := 0; i < n; i++ { 47 val := i64s[i] 48 if buf.IsNull(i) || val < 0 || uint64(val) > math.MaxUint32 { 49 result.AppendNull() 50 continue 51 } 52 binary.BigEndian.PutUint32(ip, uint32(val)) 53 ipv4 := ip.To4() 54 if ipv4 == nil { 55 //Not a vaild ipv4 address. 56 result.AppendNull() 57 continue 58 } 59 result.AppendString(ipv4.String()) 60 } 61 return nil 62 } 63 64 func (b *builtinInetNtoaSig) vectorized() bool { 65 return true 66 } 67 68 func (b *builtinIsIPv4Sig) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error { 69 n := input.NumEvents() 70 buf, err := b.bufSlabPredictor.get(types.ETString, n) 71 if err != nil { 72 return err 73 } 74 defer b.bufSlabPredictor.put(buf) 75 if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil { 76 return err 77 } 78 result.ResizeInt64(n, false) 79 i64s := result.Int64s() 80 for i := 0; i < n; i++ { 81 // Note that even when the i-th input string is null, the output is 82 // 0 instead of null, therefore we do not set the null bit mask in 83 // result's corresponding event. 84 // See https://dev.allegrosql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_is-ipv4 85 if isIPv4(buf.GetString(i)) { 86 i64s[i] = 1 87 } else { 88 i64s[i] = 0 89 } 90 } 91 return nil 92 } 93 94 func (b *builtinIsIPv4Sig) vectorized() bool { 95 return true 96 } 97 func (b *builtinJSONAnyValueSig) vectorized() bool { 98 return true 99 } 100 101 func (b *builtinJSONAnyValueSig) vecEvalJSON(input *chunk.Chunk, result *chunk.DeferredCauset) error { 102 return b.args[0].VecEvalJSON(b.ctx, input, result) 103 } 104 105 func (b *builtinRealAnyValueSig) vectorized() bool { 106 return true 107 } 108 109 func (b *builtinRealAnyValueSig) vecEvalReal(input *chunk.Chunk, result *chunk.DeferredCauset) error { 110 return b.args[0].VecEvalReal(b.ctx, input, result) 111 } 112 113 func (b *builtinStringAnyValueSig) vectorized() bool { 114 return true 115 } 116 117 func (b *builtinStringAnyValueSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 118 return b.args[0].VecEvalString(b.ctx, input, result) 119 } 120 121 func (b *builtinIsIPv6Sig) vectorized() bool { 122 return true 123 } 124 125 func (b *builtinIsIPv6Sig) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error { 126 n := input.NumEvents() 127 buf, err := b.bufSlabPredictor.get(types.ETString, n) 128 if err != nil { 129 return err 130 } 131 defer b.bufSlabPredictor.put(buf) 132 if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil { 133 return err 134 } 135 result.ResizeInt64(n, false) 136 i64s := result.Int64s() 137 for i := 0; i < n; i++ { 138 // Note that even when the i-th input string is null, the output is 139 // 0 instead of null, therefore we do not set the null bit mask in 140 // result's corresponding event. 141 // See https://dev.allegrosql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_is-ipv6 142 if buf.IsNull(i) { 143 i64s[i] = 0 144 } else { 145 ipStr := buf.GetString(i) 146 if ip := net.ParseIP(ipStr); ip != nil && !isIPv4(ipStr) { 147 i64s[i] = 1 148 } else { 149 i64s[i] = 0 150 } 151 } 152 } 153 return nil 154 } 155 156 func (b *builtinNameConstStringSig) vectorized() bool { 157 return true 158 } 159 160 func (b *builtinNameConstStringSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 161 return b.args[1].VecEvalString(b.ctx, input, result) 162 } 163 164 func (b *builtinDecimalAnyValueSig) vectorized() bool { 165 return true 166 } 167 168 func (b *builtinDecimalAnyValueSig) vecEvalDecimal(input *chunk.Chunk, result *chunk.DeferredCauset) error { 169 return b.args[0].VecEvalDecimal(b.ctx, input, result) 170 } 171 172 func (b *builtinUUIDSig) vectorized() bool { 173 return true 174 } 175 176 func (b *builtinUUIDSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 177 n := input.NumEvents() 178 result.ReserveString(n) 179 var id uuid.UUID 180 var err error 181 for i := 0; i < n; i++ { 182 id, err = uuid.NewUUID() 183 if err != nil { 184 return err 185 } 186 result.AppendString(id.String()) 187 } 188 return nil 189 } 190 191 func (b *builtinNameConstDurationSig) vectorized() bool { 192 return true 193 } 194 195 func (b *builtinNameConstDurationSig) vecEvalDuration(input *chunk.Chunk, result *chunk.DeferredCauset) error { 196 return b.args[1].VecEvalDuration(b.ctx, input, result) 197 } 198 199 func (b *builtinLockSig) vectorized() bool { 200 return true 201 } 202 203 // See https://dev.allegrosql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_get-dagger 204 // The dagger function will do nothing. 205 // Warning: get_lock() function is parsed but ignored. 206 func (b *builtinLockSig) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error { 207 n := input.NumEvents() 208 result.ResizeInt64(n, false) 209 i64s := result.Int64s() 210 for i := range i64s { 211 i64s[i] = 1 212 } 213 return nil 214 } 215 216 func (b *builtinDurationAnyValueSig) vectorized() bool { 217 return true 218 } 219 220 func (b *builtinDurationAnyValueSig) vecEvalDuration(input *chunk.Chunk, result *chunk.DeferredCauset) error { 221 return b.args[0].VecEvalDuration(b.ctx, input, result) 222 } 223 224 func (b *builtinIntAnyValueSig) vectorized() bool { 225 return true 226 } 227 228 func (b *builtinIntAnyValueSig) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error { 229 return b.args[0].VecEvalInt(b.ctx, input, result) 230 } 231 232 func (b *builtinIsIPv4CompatSig) vectorized() bool { 233 return true 234 } 235 236 func (b *builtinIsIPv4CompatSig) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error { 237 n := input.NumEvents() 238 buf, err := b.bufSlabPredictor.get(types.ETString, n) 239 if err != nil { 240 return err 241 } 242 defer b.bufSlabPredictor.put(buf) 243 if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil { 244 return err 245 } 246 result.ResizeInt64(n, false) 247 i64s := result.Int64s() 248 prefixCompat := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 249 for i := 0; i < n; i++ { 250 if buf.IsNull(i) { 251 i64s[i] = 0 252 } else { 253 // Note that the input should be IP address in byte format. 254 // For IPv4, it should be byte slice with 4 bytes. 255 // For IPv6, it should be byte slice with 16 bytes. 256 // See example https://dev.allegrosql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_is-ipv4-compat 257 ipAddress := buf.GetBytes(i) 258 if len(ipAddress) != net.IPv6len || !bytes.HasPrefix(ipAddress, prefixCompat) { 259 //Not an IPv6 address, return false 260 i64s[i] = 0 261 } else { 262 i64s[i] = 1 263 } 264 } 265 } 266 return nil 267 } 268 269 func (b *builtinNameConstIntSig) vectorized() bool { 270 return true 271 } 272 273 func (b *builtinNameConstIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error { 274 return b.args[1].VecEvalInt(b.ctx, input, result) 275 } 276 277 func (b *builtinNameConstTimeSig) vectorized() bool { 278 return true 279 } 280 281 func (b *builtinNameConstTimeSig) vecEvalTime(input *chunk.Chunk, result *chunk.DeferredCauset) error { 282 return b.args[1].VecEvalTime(b.ctx, input, result) 283 } 284 285 func (b *builtinSleepSig) vectorized() bool { 286 return true 287 } 288 289 // vecEvalInt evals a builtinSleepSig in a vectorized manner. 290 // See https://dev.allegrosql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_sleep 291 func (b *builtinSleepSig) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error { 292 n := input.NumEvents() 293 buf, err := b.bufSlabPredictor.get(types.ETReal, n) 294 if err != nil { 295 return err 296 } 297 defer b.bufSlabPredictor.put(buf) 298 299 err = b.args[0].VecEvalReal(b.ctx, input, buf) 300 if err != nil { 301 return err 302 } 303 304 result.ResizeInt64(n, false) 305 i64s := result.Int64s() 306 307 for i := 0; i < n; i++ { 308 isNull := buf.IsNull(i) 309 val := buf.GetFloat64(i) 310 311 sessVars := b.ctx.GetStochastikVars() 312 if isNull || val < 0 { 313 if sessVars.StrictALLEGROSQLMode { 314 return errIncorrectArgs.GenWithStackByArgs("sleep") 315 } 316 err := errIncorrectArgs.GenWithStackByArgs("sleep") 317 sessVars.StmtCtx.AppendWarning(err) 318 continue 319 } 320 321 if val > math.MaxFloat64/float64(time.Second.Nanoseconds()) { 322 return errIncorrectArgs.GenWithStackByArgs("sleep") 323 } 324 325 if isKilled := doSleep(val, sessVars); isKilled { 326 for j := i; j < n; j++ { 327 i64s[j] = 1 328 } 329 return nil 330 } 331 } 332 333 return nil 334 } 335 336 func doSleep(secs float64, sessVars *variable.StochastikVars) (isKilled bool) { 337 if secs <= 0.0 { 338 return false 339 } 340 dur := time.Duration(secs * float64(time.Second.Nanoseconds())) 341 ticker := time.NewTicker(10 * time.Millisecond) 342 defer ticker.Stop() 343 timer := time.NewTimer(dur) 344 for { 345 select { 346 case <-ticker.C: 347 if atomic.CompareAndSwapUint32(&sessVars.Killed, 1, 0) { 348 timer.Stop() 349 return true 350 } 351 case <-timer.C: 352 return false 353 } 354 } 355 } 356 357 func (b *builtinIsIPv4MappedSig) vectorized() bool { 358 return true 359 } 360 361 func (b *builtinIsIPv4MappedSig) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error { 362 n := input.NumEvents() 363 buf, err := b.bufSlabPredictor.get(types.ETString, n) 364 if err != nil { 365 return err 366 } 367 defer b.bufSlabPredictor.put(buf) 368 if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil { 369 return err 370 } 371 result.ResizeInt64(n, false) 372 i64s := result.Int64s() 373 prefixMapped := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff} 374 for i := 0; i < n; i++ { 375 if buf.IsNull(i) { 376 i64s[i] = 0 377 } else { 378 // Note that the input should be IP address in byte format. 379 // For IPv4, it should be byte slice with 4 bytes. 380 // For IPv6, it should be byte slice with 16 bytes. 381 // See example https://dev.allegrosql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_is-ipv4-mapped 382 ipAddress := buf.GetBytes(i) 383 if len(ipAddress) != net.IPv6len || !bytes.HasPrefix(ipAddress, prefixMapped) { 384 //Not an IPv6 address, return false 385 i64s[i] = 0 386 } else { 387 i64s[i] = 1 388 } 389 } 390 } 391 return nil 392 } 393 394 func (b *builtinNameConstDecimalSig) vectorized() bool { 395 return true 396 } 397 398 func (b *builtinNameConstDecimalSig) vecEvalDecimal(input *chunk.Chunk, result *chunk.DeferredCauset) error { 399 return b.args[1].VecEvalDecimal(b.ctx, input, result) 400 } 401 402 func (b *builtinNameConstJSONSig) vectorized() bool { 403 return true 404 } 405 406 func (b *builtinNameConstJSONSig) vecEvalJSON(input *chunk.Chunk, result *chunk.DeferredCauset) error { 407 return b.args[1].VecEvalJSON(b.ctx, input, result) 408 } 409 410 func (b *builtinInet6AtonSig) vectorized() bool { 411 return true 412 } 413 414 // vecEvalString evals a builtinInet6AtonSig. 415 // See https://dev.allegrosql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_inet6-aton 416 func (b *builtinInet6AtonSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 417 n := input.NumEvents() 418 buf, err := b.bufSlabPredictor.get(types.ETString, n) 419 if err != nil { 420 return err 421 } 422 defer b.bufSlabPredictor.put(buf) 423 if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil { 424 return err 425 } 426 427 var ( 428 resv4 []byte 429 resv6 []byte 430 res []byte 431 ) 432 result.ReserveString(n) 433 for i := 0; i < n; i++ { 434 if buf.IsNull(i) { 435 result.AppendNull() 436 continue 437 } 438 val := buf.GetString(i) 439 if len(val) == 0 { 440 result.AppendNull() 441 continue 442 } 443 ip := net.ParseIP(val) 444 if ip == nil { 445 result.AppendNull() 446 continue 447 } 448 var isMappedIpv6 bool 449 ipTo4 := ip.To4() 450 if ipTo4 != nil && strings.Contains(val, ":") { 451 //mapped ipv6 address. 452 isMappedIpv6 = true 453 } 454 455 if isMappedIpv6 || ipTo4 == nil { 456 if resv6 == nil { 457 resv6 = make([]byte, net.IPv6len) 458 } 459 res = resv6 460 } else { 461 if resv4 == nil { 462 resv4 = make([]byte, net.IPv4len) 463 } 464 res = resv4 465 } 466 467 if isMappedIpv6 { 468 copy(res[12:], ipTo4) 469 res[11] = 0xff 470 res[10] = 0xff 471 } else if ipTo4 == nil { 472 copy(res, ip.To16()) 473 } else { 474 copy(res, ipTo4) 475 } 476 result.AppendBytes(res) 477 } 478 return nil 479 } 480 481 func (b *builtinTimeAnyValueSig) vectorized() bool { 482 return true 483 } 484 485 func (b *builtinTimeAnyValueSig) vecEvalTime(input *chunk.Chunk, result *chunk.DeferredCauset) error { 486 return b.args[0].VecEvalTime(b.ctx, input, result) 487 } 488 489 func (b *builtinInetAtonSig) vectorized() bool { 490 return true 491 } 492 493 func (b *builtinInetAtonSig) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error { 494 n := input.NumEvents() 495 buf, err := b.bufSlabPredictor.get(types.ETString, n) 496 if err != nil { 497 return err 498 } 499 defer b.bufSlabPredictor.put(buf) 500 if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil { 501 return err 502 } 503 var ( 504 byteResult, res uint64 505 dotCount int 506 ) 507 result.ResizeInt64(n, false) 508 i64s := result.Int64s() 509 result.MergeNulls(buf) 510 for i := 0; i < n; i++ { 511 if result.IsNull(i) { 512 continue 513 } 514 ipAddr := buf.GetString(i) 515 if len(ipAddr) == 0 || ipAddr[len(ipAddr)-1] == '.' { 516 // ip address should not end with '.'. 517 result.SetNull(i, true) 518 continue 519 } 520 //reset 521 byteResult = 0 522 res = 0 523 dotCount = 0 524 for _, c := range ipAddr { 525 if c >= '0' && c <= '9' { 526 digit := uint64(c - '0') 527 byteResult = byteResult*10 + digit 528 if byteResult > 255 { 529 result.SetNull(i, true) 530 break 531 } 532 } else if c == '.' { 533 dotCount++ 534 if dotCount > 3 { 535 result.SetNull(i, true) 536 break 537 } 538 res = (res << 8) + byteResult 539 byteResult = 0 540 } else { 541 result.SetNull(i, true) 542 break // illegal char (not number or .) 543 } 544 } 545 // 127 -> 0.0.0.127 546 // 127.255 -> 127.0.0.255 547 // 127.256 -> NULL 548 // 127.2.1 -> 127.2.0.1 549 if !result.IsNull(i) { 550 if dotCount == 1 { 551 res <<= 16 552 } 553 if dotCount == 2 { 554 res <<= 8 555 } 556 i64s[i] = int64((res << 8) + byteResult) 557 } 558 } 559 return nil 560 } 561 562 func (b *builtinInet6NtoaSig) vectorized() bool { 563 return true 564 } 565 566 func (b *builtinInet6NtoaSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 567 n := input.NumEvents() 568 val, err := b.bufSlabPredictor.get(types.ETString, n) 569 if err != nil { 570 return err 571 } 572 defer b.bufSlabPredictor.put(val) 573 if err := b.args[0].VecEvalString(b.ctx, input, val); err != nil { 574 return err 575 } 576 result.ReserveString(n) 577 for i := 0; i < n; i++ { 578 if val.IsNull(i) { 579 result.AppendNull() 580 continue 581 } 582 valI := val.GetString(i) 583 ip := net.IP(valI).String() 584 if len(valI) == net.IPv6len && !strings.Contains(ip, ":") { 585 ip = fmt.Sprintf("::ffff:%s", ip) 586 } 587 if net.ParseIP(ip) == nil { 588 result.AppendNull() 589 continue 590 } 591 result.AppendString(ip) 592 } 593 return nil 594 } 595 596 func (b *builtinNameConstRealSig) vectorized() bool { 597 return true 598 } 599 600 func (b *builtinNameConstRealSig) vecEvalReal(input *chunk.Chunk, result *chunk.DeferredCauset) error { 601 return b.args[1].VecEvalReal(b.ctx, input, result) 602 } 603 604 func (b *builtinReleaseLockSig) vectorized() bool { 605 return true 606 } 607 608 // See https://dev.allegrosql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_release-dagger 609 // The release dagger function will do nothing. 610 // Warning: release_lock() function is parsed but ignored. 611 func (b *builtinReleaseLockSig) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error { 612 n := input.NumEvents() 613 result.ResizeInt64(n, false) 614 i64s := result.Int64s() 615 for i := range i64s { 616 i64s[i] = 1 617 } 618 return nil 619 }